Merge github.com:grpc/grpc into epex4

pull/10712/head
Craig Tiller 8 years ago
commit f54b89c4f8
  1. 28
      Makefile
  2. 4
      bazel/cc_grpc_library.bzl
  3. 11
      bazel/generate_cc.bzl
  4. 3
      bazel/grpc_build_system.bzl
  5. 7
      build.yaml
  6. 163
      include/grpc++/test/mock_stream.h
  7. 176
      src/compiler/cpp_generator.cc
  8. 34
      src/compiler/cpp_generator.h
  9. 21
      src/compiler/cpp_plugin.cc
  10. 19
      src/core/lib/iomgr/udp_server.c
  11. 2
      src/proto/grpc/testing/BUILD
  12. 8
      src/proto/grpc/testing/compiler_test.proto
  13. 14
      templates/Makefile.template
  14. 2
      templates/tools/run_tests/generated/sources_and_headers.json.template
  15. 4
      test/core/util/port_server_client.c
  16. 10
      test/core/util/test_config.c
  17. 2
      test/cpp/codegen/BUILD
  18. 144
      test/cpp/codegen/compiler_test_golden
  19. 34
      test/cpp/codegen/compiler_test_mock_golden
  20. 31
      test/cpp/codegen/golden_file_test.cc
  21. 278
      test/cpp/end2end/mock_test.cc
  22. 24
      test/cpp/microbenchmarks/fullstack_fixtures.h
  23. 5
      third_party/gtest.BUILD
  24. 1
      tools/jenkins/run_performance.sh
  25. 5
      tools/profiling/microbenchmarks/bm_diff.py
  26. 83
      tools/run_tests/generated/sources_and_headers.json
  27. 2
      tools/run_tests/generated/tests.json
  28. 27
      tools/run_tests/python_utils/port_server.py
  29. 3
      vsprojects/vcxproj/test/mock_test/mock_test.vcxproj
  30. 14
      vsprojects/vcxproj/test/mock_test/mock_test.vcxproj.filters

@ -174,7 +174,7 @@ LD_ubsan = clang
LDXX_ubsan = clang++ LDXX_ubsan = clang++
CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow
DEFINES_ubsan = NDEBUG DEFINES_ubsan = NDEBUG GRPC_UBSAN
VALID_CONFIG_tsan = 1 VALID_CONFIG_tsan = 1
REQUIRE_CUSTOM_LIBRARIES_tsan = 1 REQUIRE_CUSTOM_LIBRARIES_tsan = 1
@ -418,7 +418,7 @@ AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little
USE_BUILT_PROTOC = false USE_BUILT_PROTOC = false
endif endif
GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc -Ithird_party/googletest/googlemock/include -Ithird_party/googletest/googlemock third_party/googletest/googlemock/src/gmock-all.cc
GTEST_LIB += -lgflags GTEST_LIB += -lgflags
ifeq ($(V),1) ifeq ($(V),1)
E = @: E = @:
@ -793,7 +793,7 @@ PROTOBUF_PKG_CONFIG = false
PC_REQUIRES_GRPCXX = PC_REQUIRES_GRPCXX =
PC_LIBS_GRPCXX = PC_LIBS_GRPCXX =
CPPFLAGS := -Ithird_party/googletest/googletest/include $(CPPFLAGS) CPPFLAGS := -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include $(CPPFLAGS)
PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_php_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_php_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG) PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG)
@ -2238,6 +2238,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: src/proto/grpc/health/v1/health.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: src/proto/grpc/health/v1/health.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2253,6 +2254,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2268,6 +2270,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2283,6 +2286,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/status/status.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/status/status.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/status/status.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/status/status.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2298,6 +2302,8 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2306,13 +2312,14 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com
$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif endif
ifeq ($(NO_PROTOC),true) ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/control.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/control.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2328,6 +2335,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2343,6 +2351,8 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2351,13 +2361,14 @@ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $
$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif endif
ifeq ($(NO_PROTOC),true) ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2373,6 +2384,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2388,6 +2400,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2403,6 +2416,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2418,6 +2432,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2433,6 +2448,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/services.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/services.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2448,6 +2464,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -2463,6 +2480,7 @@ ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/test.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/test.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: protoc_dep_error
else else
$(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`

@ -2,7 +2,7 @@
load("//:bazel/generate_cc.bzl", "generate_cc") load("//:bazel/generate_cc.bzl", "generate_cc")
def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_external = False, **kwargs): def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mock, use_external = False, **kwargs):
"""Generates C++ grpc classes from a .proto file. """Generates C++ grpc classes from a .proto file.
Assumes the generated classes will be used in cc_api_version = 2. Assumes the generated classes will be used in cc_api_version = 2.
@ -17,6 +17,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_externa
"@com_google_protobuf//:well_known_protos" "@com_google_protobuf//:well_known_protos"
use_external: When True the grpc deps are prefixed with //external. This use_external: When True the grpc deps are prefixed with //external. This
allows grpc to be used as a dependency in other bazel projects. allows grpc to be used as a dependency in other bazel projects.
generate_mock: When true GMOCk code for client stub is generated.
**kwargs: rest of arguments, e.g., compatible_with and visibility. **kwargs: rest of arguments, e.g., compatible_with and visibility.
""" """
if len(srcs) > 1: if len(srcs) > 1:
@ -54,6 +55,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_externa
srcs = [proto_target], srcs = [proto_target],
plugin = plugin, plugin = plugin,
well_known_protos = well_known_protos, well_known_protos = well_known_protos,
generate_mock = generate_mock,
**kwargs **kwargs
) )

@ -12,6 +12,8 @@ def generate_cc_impl(ctx):
if ctx.executable.plugin: if ctx.executable.plugin:
outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos] outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos]
outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos] outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
if ctx.attr.generate_mock:
outs += [proto.basename[:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos]
else: else:
outs += [proto.basename[:-len(".proto")] + ".pb.h" for proto in protos] outs += [proto.basename[:-len(".proto")] + ".pb.h" for proto in protos]
outs += [proto.basename[:-len(".proto")] + ".pb.cc" for proto in protos] outs += [proto.basename[:-len(".proto")] + ".pb.cc" for proto in protos]
@ -23,7 +25,10 @@ def generate_cc_impl(ctx):
arguments = [] arguments = []
if ctx.executable.plugin: if ctx.executable.plugin:
arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] flags = list(ctx.attr.flags)
if ctx.attr.generate_mock:
flags.append("generate_mock_code=true")
arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out]
additional_input = [ctx.executable.plugin] additional_input = [ctx.executable.plugin]
else: else:
arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
@ -71,6 +76,10 @@ generate_cc = rule(
"well_known_protos" : attr.label( "well_known_protos" : attr.label(
mandatory = False, mandatory = False,
), ),
"generate_mock" : attr.bool(
default = False,
mandatory = False,
),
"_protoc": attr.label( "_protoc": attr.label(
default = Label("//external:protocol_compiler"), default = Label("//external:protocol_compiler"),
executable = True, executable = True,

@ -75,7 +75,7 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None, def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
has_services = True, use_external = False): has_services = True, use_external = False, generate_mock = False):
cc_grpc_library( cc_grpc_library(
name = name, name = name,
srcs = srcs, srcs = srcs,
@ -83,5 +83,6 @@ def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
well_known_protos = well_known_protos, well_known_protos = well_known_protos,
proto_only = not has_services, proto_only = not has_services,
use_external = use_external, use_external = use_external,
generate_mock = generate_mock,
) )

@ -971,6 +971,7 @@ filegroups:
- name: grpc++_test - name: grpc++_test
language: c++ language: c++
public_headers: public_headers:
- include/grpc++/test/mock_stream.h
- include/grpc++/test/server_context_test_spouse.h - include/grpc++/test/server_context_test_spouse.h
deps: deps:
- grpc++ - grpc++
@ -3693,7 +3694,7 @@ targets:
- grpc - grpc
- gpr - gpr
args: args:
- --generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h - --generated_file_path=gens/src/proto/grpc/testing/
- name: grpc_cli - name: grpc_cli
build: test build: test
run: false run: false
@ -3954,6 +3955,8 @@ targets:
gtest: true gtest: true
build: test build: test
language: c++ language: c++
headers:
- include/grpc++/test/mock_stream.h
src: src:
- test/cpp/end2end/mock_test.cc - test/cpp/end2end/mock_test.cc
deps: deps:
@ -4466,7 +4469,7 @@ configs:
CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined -fno-omit-frame-pointer
-Wno-unused-command-line-argument -Wvarargs -Wno-unused-command-line-argument -Wvarargs
CXX: clang++ CXX: clang++
DEFINES: NDEBUG DEFINES: NDEBUG GRPC_UBSAN
LD: clang LD: clang
LDFLAGS: -fsanitize=undefined,unsigned-integer-overflow LDFLAGS: -fsanitize=undefined,unsigned-integer-overflow
LDXX: clang++ LDXX: clang++

@ -0,0 +1,163 @@
/*
*
* Copyright 2017, 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.
*
*/
#ifndef GRPCXX_TEST_MOCK_STREAM_H
#define GRPCXX_TEST_MOCK_STREAM_H
#include <stdint.h>
#include <gmock/gmock.h>
#include <grpc++/impl/codegen/call.h>
#include <grpc++/support/async_stream.h>
#include <grpc++/support/async_unary_call.h>
#include <grpc++/support/sync_stream.h>
namespace grpc {
namespace testing {
template <class R>
class MockClientReader : public ClientReaderInterface<R> {
public:
MockClientReader() = default;
// ClientStreamingInterface
MOCK_METHOD0_T(Finish, Status());
// ReaderInterface
MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
MOCK_METHOD1_T(Read, bool(R*));
// ClientReaderInterface
MOCK_METHOD0_T(WaitForInitialMetadata, void());
};
template <class W>
class MockClientWriter : public ClientWriterInterface<W> {
public:
MockClientWriter() = default;
// ClientStreamingInterface
MOCK_METHOD0_T(Finish, Status());
// WriterInterface
MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
// ClientWriterInterface
MOCK_METHOD0_T(WritesDone, bool());
};
template <class W, class R>
class MockClientReaderWriter : public ClientReaderWriterInterface<W, R> {
public:
MockClientReaderWriter() = default;
// ClientStreamingInterface
MOCK_METHOD0_T(Finish, Status());
// ReaderInterface
MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
MOCK_METHOD1_T(Read, bool(R*));
// WriterInterface
MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
// ClientReaderWriterInterface
MOCK_METHOD0_T(WaitForInitialMetadata, void());
MOCK_METHOD0_T(WritesDone, bool());
};
// TODO: We do not support mocking an async RPC for now.
template <class R>
class MockClientAsyncResponseReader
: public ClientAsyncResponseReaderInterface<R> {
public:
MockClientAsyncResponseReader() = default;
MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
MOCK_METHOD3_T(Finish, void(R*, Status*, void*));
};
template <class R>
class MockClientAsyncReader : public ClientAsyncReaderInterface<R> {
public:
MockClientAsyncReader() = default;
// ClientAsyncStreamingInterface
MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
MOCK_METHOD2_T(Finish, void(Status*, void*));
// AsyncReaderInterface
MOCK_METHOD2_T(Read, void(R*, void*));
};
template <class W>
class MockClientAsyncWriter : public ClientAsyncWriterInterface<W> {
public:
MockClientAsyncWriter() = default;
// ClientAsyncStreamingInterface
MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
MOCK_METHOD2_T(Finish, void(Status*, void*));
// AsyncWriterInterface
MOCK_METHOD2_T(Write, void(const W&, void*));
// ClientAsyncWriterInterface
MOCK_METHOD1_T(WritesDone, void(void*));
};
template <class W, class R>
class MockClientAsyncReaderWriter
: public ClientAsyncReaderWriterInterface<W, R> {
public:
MockClientAsyncReaderWriter() = default;
// ClientAsyncStreamingInterface
MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
MOCK_METHOD2_T(Finish, void(Status*, void*));
// AsyncWriterInterface
MOCK_METHOD2_T(Write, void(const W&, void*));
// AsyncReaderInterface
MOCK_METHOD2_T(Read, void(R*, void*));
// ClientAsyncReaderWriterInterface
MOCK_METHOD1_T(WritesDone, void(void*));
};
} // namespace testing
} // namespace grpc
#endif // GRPCXX_TEST_MOCK_STREAM_H

@ -1408,4 +1408,180 @@ grpc::string GetSourceEpilogue(grpc_generator::File *file,
return temp; return temp;
} }
// TODO(mmukhi): Make sure we need parameters or not.
grpc::string GetMockPrologue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = message_header_ext();
vars["service_header_ext"] = service_header_ext();
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n\n");
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
printer->Print(vars, file->additional_headers().c_str());
printer->Print(vars, "\n");
}
return output;
}
// TODO(mmukhi): Add client-stream and completion-queue headers.
grpc::string GetMockIncludes(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = {
"grpc++/impl/codegen/async_stream.h",
"grpc++/impl/codegen/sync_stream.h", "gmock/gmock.h",
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params);
if (!file->package().empty()) {
std::vector<grpc::string> parts = file->package_parts();
for (auto part = parts.begin(); part != parts.end(); part++) {
vars["part"] = *part;
printer->Print(vars, "namespace $part$ {\n");
}
}
printer->Print(vars, "\n");
}
return output;
}
void PrintMockClientMethods(grpc_generator::Printer *printer,
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
if (method->NoStreaming()) {
printer->Print(
*vars,
"MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response));\n");
printer->Print(*vars,
"MOCK_METHOD3(Async$Method$Raw, "
"::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
"(::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq));\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"MOCK_METHOD2($Method$Raw, "
"::grpc::ClientWriterInterface< $Request$>*"
"(::grpc::ClientContext* context, $Response$* response));\n");
printer->Print(*vars,
"MOCK_METHOD4(Async$Method$Raw, "
"::grpc::ClientAsyncWriterInterface< $Request$>*"
"(::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq, void* tag));\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"MOCK_METHOD2($Method$Raw, "
"::grpc::ClientReaderInterface< $Response$>*"
"(::grpc::ClientContext* context, const $Request$& request));\n");
printer->Print(*vars,
"MOCK_METHOD4(Async$Method$Raw, "
"::grpc::ClientAsyncReaderInterface< $Response$>*"
"(::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag));\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
"MOCK_METHOD1($Method$Raw, "
"::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
"(::grpc::ClientContext* context));\n");
printer->Print(
*vars,
"MOCK_METHOD3(Async$Method$Raw, "
"::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
"(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, "
"void* tag));\n");
}
}
void PrintMockService(grpc_generator::Printer *printer,
const grpc_generator::Service *service,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars,
"class Mock$Service$Stub : public $Service$::StubInterface {\n"
" public:\n");
printer->Indent();
for (int i = 0; i < service->method_count(); ++i) {
PrintMockClientMethods(printer, service->method(i).get(), vars);
}
printer->Outdent();
printer->Print("};\n");
}
grpc::string GetMockServices(grpc_generator::File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
// Package string is empty or ends with a dot. It is used to fully qualify
// method names.
vars["Package"] = file->package();
if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace;
printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
}
for (int i = 0; i < file->service_count(); i++) {
PrintMockService(printer.get(), file->service(i).get(), &vars);
printer->Print("\n");
}
if (!params.services_namespace.empty()) {
printer->Print(vars, "} // namespace $services_namespace$\n\n");
}
}
return output;
}
grpc::string GetMockEpilogue(grpc_generator::File *file,
const Parameters & /*params*/) {
grpc::string temp;
if (!file->package().empty()) {
std::vector<grpc::string> parts = file->package_parts();
for (auto part = parts.begin(); part != parts.end(); part++) {
temp.append("} // namespace ");
temp.append(*part);
temp.append("\n");
}
temp.append("\n");
}
return temp;
}
} // namespace grpc_cpp_generator } // namespace grpc_cpp_generator

@ -65,6 +65,8 @@ struct Parameters {
bool use_system_headers; bool use_system_headers;
// Prefix to any grpc include // Prefix to any grpc include
grpc::string grpc_search_path; grpc::string grpc_search_path;
// Generate GMOCK code to facilitate unit testing.
bool generate_mock_code;
}; };
// Return the prologue of the generated header file. // Return the prologue of the generated header file.
@ -99,6 +101,38 @@ grpc::string GetSourceServices(grpc_generator::File *file,
grpc::string GetSourceEpilogue(grpc_generator::File *file, grpc::string GetSourceEpilogue(grpc_generator::File *file,
const Parameters &params); const Parameters &params);
// Return the prologue of the generated mock file.
grpc::string GetMockPrologue(grpc_generator::File *file,
const Parameters &params);
// Return the includes needed for generated mock file.
grpc::string GetMockIncludes(grpc_generator::File *file,
const Parameters &params);
// Return the services for generated mock file.
grpc::string GetMockServices(grpc_generator::File *file,
const Parameters &params);
// Return the epilogue of generated mock file.
grpc::string GetMockEpilogue(grpc_generator::File *file,
const Parameters &params);
// Return the prologue of the generated mock file.
grpc::string GetMockPrologue(grpc_generator::File *file,
const Parameters &params);
// Return the includes needed for generated mock file.
grpc::string GetMockIncludes(grpc_generator::File *file,
const Parameters &params);
// Return the services for generated mock file.
grpc::string GetMockServices(grpc_generator::File *file,
const Parameters &params);
// Return the epilogue of generated mock file.
grpc::string GetMockEpilogue(grpc_generator::File *file,
const Parameters &params);
} // namespace grpc_cpp_generator } // namespace grpc_cpp_generator
#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H #endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H

@ -62,6 +62,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_cpp_generator::Parameters generator_parameters; grpc_cpp_generator::Parameters generator_parameters;
generator_parameters.use_system_headers = true; generator_parameters.use_system_headers = true;
generator_parameters.generate_mock_code = false;
ProtoBufFile pbfile(file); ProtoBufFile pbfile(file);
@ -85,6 +86,13 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
} }
} else if (param[0] == "grpc_search_path") { } else if (param[0] == "grpc_search_path") {
generator_parameters.grpc_search_path = param[1]; generator_parameters.grpc_search_path = param[1];
} else if (param[0] == "generate_mock_code") {
if (param[1] == "true") {
generator_parameters.generate_mock_code = true;
} else if (param[1] != "false") {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else { } else {
*error = grpc::string("Unknown parameter: ") + *parameter_string; *error = grpc::string("Unknown parameter: ") + *parameter_string;
return false; return false;
@ -114,6 +122,19 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get()); grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get());
source_coded_out.WriteRaw(source_code.data(), source_code.size()); source_coded_out.WriteRaw(source_code.data(), source_code.size());
if (!generator_parameters.generate_mock_code) {
return true;
}
grpc::string mock_code =
grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> mock_output(
context->Open(file_name + "_mock.grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get());
mock_coded_out.WriteRaw(mock_code.data(), mock_code.size());
return true; return true;
} }

@ -92,6 +92,11 @@ struct grpc_udp_listener {
struct grpc_udp_listener *next; struct grpc_udp_listener *next;
}; };
struct shutdown_fd_args {
grpc_fd *fd;
gpr_mu *server_mu;
};
/* the overall server */ /* the overall server */
struct grpc_udp_server { struct grpc_udp_server {
gpr_mu mu; gpr_mu mu;
@ -151,8 +156,13 @@ grpc_udp_server *grpc_udp_server_create(const grpc_channel_args *args) {
return s; return s;
} }
static void shutdown_fd(grpc_exec_ctx *exec_ctx, void *fd, grpc_error *error) { static void shutdown_fd(grpc_exec_ctx *exec_ctx, void *args,
grpc_fd_shutdown(exec_ctx, (grpc_fd *)fd, GRPC_ERROR_REF(error)); grpc_error *error) {
struct shutdown_fd_args *shutdown_args = (struct shutdown_fd_args *)args;
gpr_mu_lock(shutdown_args->server_mu);
grpc_fd_shutdown(exec_ctx, shutdown_args->fd, GRPC_ERROR_REF(error));
gpr_mu_unlock(shutdown_args->server_mu);
gpr_free(shutdown_args);
} }
static void dummy_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { static void dummy_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
@ -242,7 +252,10 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
if (s->active_ports) { if (s->active_ports) {
for (sp = s->head; sp; sp = sp->next) { for (sp = s->head; sp; sp = sp->next) {
GPR_ASSERT(sp->orphan_cb); GPR_ASSERT(sp->orphan_cb);
grpc_closure_init(&sp->orphan_fd_closure, shutdown_fd, sp->emfd, struct shutdown_fd_args *args = gpr_malloc(sizeof(*args));
args->fd = sp->emfd;
args->server_mu = &s->mu;
grpc_closure_init(&sp->orphan_fd_closure, shutdown_fd, args,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure, sp->orphan_cb(exec_ctx, sp->emfd, &sp->orphan_fd_closure,
sp->server->user_data); sp->server->user_data);

@ -36,6 +36,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
grpc_proto_library( grpc_proto_library(
name = "compiler_test_proto", name = "compiler_test_proto",
srcs = ["compiler_test.proto"], srcs = ["compiler_test.proto"],
generate_mock = True,
) )
grpc_proto_library( grpc_proto_library(
@ -55,6 +56,7 @@ grpc_proto_library(
name = "echo_proto", name = "echo_proto",
srcs = ["echo.proto"], srcs = ["echo.proto"],
deps = ["echo_messages_proto"], deps = ["echo_messages_proto"],
generate_mock = True,
) )
grpc_proto_library( grpc_proto_library(

@ -59,6 +59,14 @@ service ServiceA {
// Method A2 leading comment 2 // Method A2 leading comment 2
rpc MethodA2(stream Request) returns (Response); rpc MethodA2(stream Request) returns (Response);
// MethodA2 trailing comment 1 // MethodA2 trailing comment 1
// Method A3 leading comment 1
rpc MethodA3(Request) returns (stream Response);
// Method A3 trailing comment 1
// Method A4 leading comment 1
rpc MethodA4(stream Request) returns (stream Response);
// Method A4 trailing comment 1
} }
// Ignored ServiceA trailing comment 1 // Ignored ServiceA trailing comment 1

@ -311,7 +311,7 @@
USE_BUILT_PROTOC = false USE_BUILT_PROTOC = false
endif endif
GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc GTEST_LIB = -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googletest third_party/googletest/googletest/src/gtest-all.cc -Ithird_party/googletest/googlemock/include -Ithird_party/googletest/googlemock third_party/googletest/googlemock/src/gmock-all.cc
GTEST_LIB += -lgflags GTEST_LIB += -lgflags
ifeq ($(V),1) ifeq ($(V),1)
E = @: E = @:
@ -716,7 +716,7 @@
PC_REQUIRES_GRPCXX = PC_REQUIRES_GRPCXX =
PC_LIBS_GRPCXX = PC_LIBS_GRPCXX =
CPPFLAGS := -Ithird_party/googletest/googletest/include $(CPPFLAGS) CPPFLAGS := -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include $(CPPFLAGS)
PROTOC_PLUGINS_ALL =\ PROTOC_PLUGINS_ALL =\
% for tgt in targets: % for tgt in targets:
@ -1240,6 +1240,14 @@
$(GENDIR)/${p}.pb.cc: protoc_dep_error $(GENDIR)/${p}.pb.cc: protoc_dep_error
$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error $(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
else else
<%
pluginflags=""
%>
% if p in ["src/proto/grpc/testing/compiler_test", "src/proto/grpc/testing/echo"]:
<%
pluginflags="generate_mock_code=true:"
%>
% endif
$(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc' % q for q in proto_deps.get(p, []))} $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc' % q for q in proto_deps.get(p, []))}
$(E) "[PROTOC] Generating protobuf CC file from $<" $(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
@ -1248,7 +1256,7 @@
$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))} $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))}
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=${pluginflags}$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
endif endif
% endfor % endfor

@ -9,7 +9,7 @@
for f in src: for f in src:
name, ext = os.path.splitext(f) name, ext = os.path.splitext(f)
if ext == '.proto': if ext == '.proto':
out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h']) out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h', '%s_mock.grpc.pb.h'])
return out return out
def all_targets(targets, libs, filegroups): def all_targets(targets, libs, filegroups):

@ -102,7 +102,7 @@ void grpc_free_port_using_server(int port) {
grpc_resource_quota *resource_quota = grpc_resource_quota *resource_quota =
grpc_resource_quota_create("port_server_client/free"); grpc_resource_quota_create("port_server_client/free");
grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req, grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
grpc_timeout_seconds_to_deadline(10), grpc_timeout_seconds_to_deadline(30),
grpc_closure_create(freed_port_from_server, &pr, grpc_closure_create(freed_port_from_server, &pr,
grpc_schedule_on_exec_ctx), grpc_schedule_on_exec_ctx),
&rsp); &rsp);
@ -235,7 +235,7 @@ int grpc_pick_port_using_server(void) {
grpc_resource_quota_create("port_server_client/pick"); grpc_resource_quota_create("port_server_client/pick");
grpc_httpcli_get( grpc_httpcli_get(
&exec_ctx, &context, &pr.pops, resource_quota, &req, &exec_ctx, &context, &pr.pops, resource_quota, &req,
grpc_timeout_seconds_to_deadline(10), grpc_timeout_seconds_to_deadline(30),
grpc_closure_create(got_port_from_server, &pr, grpc_schedule_on_exec_ctx), grpc_closure_create(got_port_from_server, &pr, grpc_schedule_on_exec_ctx),
&pr.response); &pr.response);
grpc_resource_quota_unref_internal(&exec_ctx, resource_quota); grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);

@ -348,6 +348,14 @@ bool BuiltUnderMsan() {
#endif #endif
} }
bool BuiltUnderUbsan() {
#ifdef GRPC_UBSAN
return true;
#else
return false;
#endif
}
int64_t grpc_test_sanitizer_slowdown_factor() { int64_t grpc_test_sanitizer_slowdown_factor() {
int64_t sanitizer_multiplier = 1; int64_t sanitizer_multiplier = 1;
if (BuiltUnderValgrind()) { if (BuiltUnderValgrind()) {
@ -358,6 +366,8 @@ int64_t grpc_test_sanitizer_slowdown_factor() {
sanitizer_multiplier = 3; sanitizer_multiplier = 3;
} else if (BuiltUnderMsan()) { } else if (BuiltUnderMsan()) {
sanitizer_multiplier = 4; sanitizer_multiplier = 4;
} else if (BuiltUnderUbsan()) {
sanitizer_multiplier = 5;
} }
return sanitizer_multiplier; return sanitizer_multiplier;
} }

@ -62,7 +62,7 @@ cc_test(
cc_test( cc_test(
name = "golden_file_test", name = "golden_file_test",
srcs = ["golden_file_test.cc"], srcs = ["golden_file_test.cc"],
args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h"], args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/"],
data = [ data = [
":compiler_test_golden", ":compiler_test_golden",
"//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen", "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen",

@ -89,10 +89,30 @@ class ServiceA final {
return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag));
} }
// MethodA2 trailing comment 1 // MethodA2 trailing comment 1
// Method A3 leading comment 1
std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) {
return std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>>(MethodA3Raw(context, request));
}
std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) {
return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag));
}
// Method A3 trailing comment 1
// Method A4 leading comment 1
std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) {
return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context));
}
std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag));
}
// Method A4 trailing comment 1
private: private:
virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
virtual ::grpc::ClientWriterInterface< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) = 0; virtual ::grpc::ClientWriterInterface< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) = 0;
virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) = 0; virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) = 0;
virtual ::grpc::ClientReaderInterface< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) = 0;
virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
virtual ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) = 0;
virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0;
}; };
class Stub final : public StubInterface { class Stub final : public StubInterface {
public: public:
@ -107,14 +127,32 @@ class ServiceA final {
std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) { std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) {
return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag));
} }
std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) {
return std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>>(MethodA3Raw(context, request));
}
std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) {
return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag));
}
std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) {
return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context));
}
std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag));
}
private: private:
std::shared_ptr< ::grpc::ChannelInterface> channel_; std::shared_ptr< ::grpc::ChannelInterface> channel_;
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override; ::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override;
::grpc::ClientAsyncWriter< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) override; ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) override;
::grpc::ClientReader< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) override;
::grpc::ClientAsyncReader< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) override;
::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) override;
::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override;
const ::grpc::RpcMethod rpcmethod_MethodA1_; const ::grpc::RpcMethod rpcmethod_MethodA1_;
const ::grpc::RpcMethod rpcmethod_MethodA2_; const ::grpc::RpcMethod rpcmethod_MethodA2_;
const ::grpc::RpcMethod rpcmethod_MethodA3_;
const ::grpc::RpcMethod rpcmethod_MethodA4_;
}; };
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
@ -131,6 +169,12 @@ class ServiceA final {
// Method A2 leading comment 2 // Method A2 leading comment 2
virtual ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response); virtual ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response);
// MethodA2 trailing comment 1 // MethodA2 trailing comment 1
// Method A3 leading comment 1
virtual ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer);
// Method A3 trailing comment 1
// Method A4 leading comment 1
virtual ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream);
// Method A4 trailing comment 1
}; };
template <class BaseClass> template <class BaseClass>
class WithAsyncMethod_MethodA1 : public BaseClass { class WithAsyncMethod_MethodA1 : public BaseClass {
@ -172,7 +216,47 @@ class ServiceA final {
::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag); ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag);
} }
}; };
typedef WithAsyncMethod_MethodA1<WithAsyncMethod_MethodA2<Service > > AsyncService; template <class BaseClass>
class WithAsyncMethod_MethodA3 : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
WithAsyncMethod_MethodA3() {
::grpc::Service::MarkMethodAsync(2);
}
~WithAsyncMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
void RequestMethodA3(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncWriter< ::grpc::testing::Response>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
}
};
template <class BaseClass>
class WithAsyncMethod_MethodA4 : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
WithAsyncMethod_MethodA4() {
::grpc::Service::MarkMethodAsync(3);
}
~WithAsyncMethod_MethodA4() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag);
}
};
typedef WithAsyncMethod_MethodA1<WithAsyncMethod_MethodA2<WithAsyncMethod_MethodA3<WithAsyncMethod_MethodA4<Service > > > > AsyncService;
template <class BaseClass> template <class BaseClass>
class WithGenericMethod_MethodA1 : public BaseClass { class WithGenericMethod_MethodA1 : public BaseClass {
private: private:
@ -208,6 +292,40 @@ class ServiceA final {
} }
}; };
template <class BaseClass> template <class BaseClass>
class WithGenericMethod_MethodA3 : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
WithGenericMethod_MethodA3() {
::grpc::Service::MarkMethodGeneric(2);
}
~WithGenericMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
};
template <class BaseClass>
class WithGenericMethod_MethodA4 : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
WithGenericMethod_MethodA4() {
::grpc::Service::MarkMethodGeneric(3);
}
~WithGenericMethod_MethodA4() override {
BaseClassMustBeDerivedFromService(this);
}
// disable synchronous version of this method
::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) final override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
};
template <class BaseClass>
class WithStreamedUnaryMethod_MethodA1 : public BaseClass { class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
private: private:
void BaseClassMustBeDerivedFromService(const Service *service) {} void BaseClassMustBeDerivedFromService(const Service *service) {}
@ -228,8 +346,28 @@ class ServiceA final {
virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0;
}; };
typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedUnaryService; typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedUnaryService;
typedef Service SplitStreamedService; template <class BaseClass>
typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedService; class WithSplitStreamingMethod_MethodA3 : public BaseClass {
private:
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
WithSplitStreamingMethod_MethodA3() {
::grpc::Service::MarkMethodStreamed(2,
new ::grpc::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3<BaseClass>::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2)));
}
~WithSplitStreamingMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
}
// disable regular version of this method
::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) final override {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
// replace default version of method with split streamed
virtual ::grpc::Status StreamedMethodA3(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_split_streamer) = 0;
};
typedef WithSplitStreamingMethod_MethodA3<Service > SplitStreamedService;
typedef WithStreamedUnaryMethod_MethodA1<WithSplitStreamingMethod_MethodA3<Service > > StreamedService;
}; };
// ServiceB leading comment 1 // ServiceB leading comment 1

@ -0,0 +1,34 @@
// Generated by the gRPC C++ plugin.
// If you make any local change, they will be lost.
// source: src/proto/grpc/testing/compiler_test.proto
#include "src/proto/grpc/testing/compiler_test.pb.h"
#include "src/proto/grpc/testing/compiler_test.grpc.pb.h"
#include <grpc++/impl/codegen/async_stream.h>
#include <grpc++/impl/codegen/sync_stream.h>
#include <gmock/gmock.h>
namespace grpc {
namespace testing {
class MockServiceAStub : public ServiceA::StubInterface {
public:
MOCK_METHOD3(MethodA1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
MOCK_METHOD3(AsyncMethodA1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
MOCK_METHOD2(MethodA2Raw, ::grpc::ClientWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response));
MOCK_METHOD4(AsyncMethodA2Raw, ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag));
MOCK_METHOD2(MethodA3Raw, ::grpc::ClientReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request));
MOCK_METHOD4(AsyncMethodA3Raw, ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag));
MOCK_METHOD1(MethodA4Raw, ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>*(::grpc::ClientContext* context));
MOCK_METHOD3(AsyncMethodA4Raw, ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, ::grpc::testing::Response>*(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag));
};
class MockServiceBStub : public ServiceB::StubInterface {
public:
MOCK_METHOD3(MethodB1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
MOCK_METHOD3(AsyncMethodB1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
};
} // namespace grpc
} // namespace testing

@ -37,16 +37,18 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
DEFINE_string(generated_file_path, "", DEFINE_string(
"path to the generated compiler_test.grpc.pb.h file"); generated_file_path, "",
"path to the directory containing generated files compiler_test.grpc.pb.h"
"and compiler_test_mock.grpc.pb.h");
const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden"; const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden";
const char kMockGoldenFilePath[] = "test/cpp/codegen/compiler_test_mock_golden";
TEST(GoldenFileTest, TestGeneratedFile) { void run_test(std::basic_string<char> generated_file,
ASSERT_FALSE(FLAGS_generated_file_path.empty()); std::basic_string<char> golden_file) {
std::ifstream generated(generated_file);
std::ifstream generated(FLAGS_generated_file_path); std::ifstream golden(golden_file);
std::ifstream golden(kGoldenFilePath);
ASSERT_TRUE(generated.good()); ASSERT_TRUE(generated.good());
ASSERT_TRUE(golden.good()); ASSERT_TRUE(golden.good());
@ -61,8 +63,23 @@ TEST(GoldenFileTest, TestGeneratedFile) {
golden.close(); golden.close();
} }
TEST(GoldenFileTest, TestGeneratedFile) {
run_test(FLAGS_generated_file_path + "compiler_test.grpc.pb.h",
kGoldenFilePath);
}
TEST(GoldenMockFileTest, TestGeneratedMockFile) {
run_test(FLAGS_generated_file_path + "compiler_test_mock.grpc.pb.h",
kMockGoldenFilePath);
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
::google::ParseCommandLineFlags(&argc, &argv, true); ::google::ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_generated_file_path.empty()) {
FLAGS_generated_file_path = "gens/src/proto/grpc/testing/";
}
if (FLAGS_generated_file_path.back() != '/')
FLAGS_generated_file_path.append("/");
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

@ -34,6 +34,7 @@
#include <climits> #include <climits>
#include <thread> #include <thread>
#include <gmock/gmock.h>
#include <grpc++/channel.h> #include <grpc++/channel.h>
#include <grpc++/client_context.h> #include <grpc++/client_context.h>
#include <grpc++/create_channel.h> #include <grpc++/create_channel.h>
@ -46,120 +47,35 @@
#include <grpc/support/time.h> #include <grpc/support/time.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <grpc++/test/mock_stream.h>
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
#include "test/core/util/port.h" #include "test/core/util/port.h"
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
#include <iostream>
using namespace std;
using grpc::testing::EchoRequest; using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse; using grpc::testing::EchoResponse;
using grpc::testing::EchoTestService; using grpc::testing::EchoTestService;
using grpc::testing::MockClientReaderWriter;
using std::chrono::system_clock; using std::chrono::system_clock;
using ::testing::AtLeast;
using ::testing::SetArgPointee;
using ::testing::SaveArg;
using ::testing::_;
using ::testing::Return;
using ::testing::Invoke;
using ::testing::WithArg;
using ::testing::DoAll;
namespace grpc { namespace grpc {
namespace testing { namespace testing {
namespace { namespace {
template <class W, class R>
class MockClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
public:
void WaitForInitialMetadata() override {}
bool NextMessageSize(uint32_t* sz) override {
*sz = UINT_MAX;
return true;
}
bool Read(R* msg) override { return true; }
bool Write(const W& msg) override { return true; }
bool WritesDone() override { return true; }
Status Finish() override { return Status::OK; }
};
template <>
class MockClientReaderWriter<EchoRequest, EchoResponse> final
: public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
public:
MockClientReaderWriter() : writes_done_(false) {}
void WaitForInitialMetadata() override {}
bool NextMessageSize(uint32_t* sz) override {
*sz = UINT_MAX;
return true;
}
bool Read(EchoResponse* msg) override {
if (writes_done_) return false;
msg->set_message(last_message_);
return true;
}
bool Write(const EchoRequest& msg, WriteOptions options) override {
gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
last_message_ = msg.message();
return true;
}
bool WritesDone() override {
writes_done_ = true;
return true;
}
Status Finish() override { return Status::OK; }
private:
bool writes_done_;
grpc::string last_message_;
};
// Mocked stub.
class MockStub : public EchoTestService::StubInterface {
public:
MockStub() {}
~MockStub() {}
Status Echo(ClientContext* context, const EchoRequest& request,
EchoResponse* response) override {
response->set_message(request.message());
return Status::OK;
}
Status Unimplemented(ClientContext* context, const EchoRequest& request,
EchoResponse* response) override {
return Status::OK;
}
private:
ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
ClientContext* context, const EchoRequest& request,
CompletionQueue* cq) override {
return nullptr;
}
ClientWriterInterface<EchoRequest>* RequestStreamRaw(
ClientContext* context, EchoResponse* response) override {
return nullptr;
}
ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
ClientContext* context, EchoResponse* response, CompletionQueue* cq,
void* tag) override {
return nullptr;
}
ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
ClientContext* context, const EchoRequest& request) override {
return nullptr;
}
ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
void* tag) override {
return nullptr;
}
ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
ClientContext* context) override {
return new MockClientReaderWriter<EchoRequest, EchoResponse>();
}
ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
void* tag) override {
return nullptr;
}
ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
ClientContext* context, const EchoRequest& request,
CompletionQueue* cq) override {
return nullptr;
}
};
class FakeClient { class FakeClient {
public: public:
explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {} explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {}
@ -174,6 +90,55 @@ class FakeClient {
EXPECT_TRUE(s.ok()); EXPECT_TRUE(s.ok());
} }
void DoRequestStream() {
EchoRequest request;
EchoResponse response;
ClientContext context;
grpc::string msg("hello");
grpc::string exp(msg);
std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream =
stub_->RequestStream(&context, &response);
request.set_message(msg);
EXPECT_TRUE(cstream->Write(request));
msg = ", world";
request.set_message(msg);
exp.append(msg);
EXPECT_TRUE(cstream->Write(request));
cstream->WritesDone();
Status s = cstream->Finish();
EXPECT_EQ(exp, response.message());
EXPECT_TRUE(s.ok());
}
void DoResponseStream() {
EchoRequest request;
EchoResponse response;
request.set_message("hello world");
ClientContext context;
std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream =
stub_->ResponseStream(&context, request);
grpc::string exp = "";
EXPECT_TRUE(cstream->Read(&response));
exp.append(response.message() + " ");
EXPECT_TRUE(cstream->Read(&response));
exp.append(response.message());
EXPECT_FALSE(cstream->Read(&response));
EXPECT_EQ(request.message(), exp);
Status s = cstream->Finish();
EXPECT_TRUE(s.ok());
}
void DoBidiStream() { void DoBidiStream() {
EchoRequest request; EchoRequest request;
EchoResponse response; EchoResponse response;
@ -219,6 +184,30 @@ class TestServiceImpl : public EchoTestService::Service {
return Status::OK; return Status::OK;
} }
Status RequestStream(ServerContext* context,
ServerReader<EchoRequest>* reader,
EchoResponse* response) override {
EchoRequest request;
grpc::string resp("");
while (reader->Read(&request)) {
gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
resp.append(request.message());
}
response->set_message(resp);
return Status::OK;
}
Status ResponseStream(ServerContext* context, const EchoRequest* request,
ServerWriter<EchoResponse>* writer) override {
EchoResponse response;
vector<grpc::string> tokens = split(request->message());
for (grpc::string token : tokens) {
response.set_message(token);
writer->Write(response);
}
return Status::OK;
}
Status BidiStream( Status BidiStream(
ServerContext* context, ServerContext* context,
ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
@ -231,6 +220,25 @@ class TestServiceImpl : public EchoTestService::Service {
} }
return Status::OK; return Status::OK;
} }
private:
const vector<grpc::string> split(const grpc::string& input) {
grpc::string buff("");
vector<grpc::string> result;
for (auto n : input) {
if (n != ' ') {
buff += n;
continue;
}
if (buff == "") continue;
result.push_back(buff);
buff = "";
}
if (buff != "") result.push_back(buff);
return result;
}
}; };
class MockTest : public ::testing::Test { class MockTest : public ::testing::Test {
@ -267,16 +275,82 @@ TEST_F(MockTest, SimpleRpc) {
ResetStub(); ResetStub();
FakeClient client(stub_.get()); FakeClient client(stub_.get());
client.DoEcho(); client.DoEcho();
MockStub stub; MockEchoTestServiceStub stub;
EchoResponse resp;
resp.set_message("hello world");
EXPECT_CALL(stub, Echo(_, _, _))
.Times(AtLeast(1))
.WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK)));
client.ResetStub(&stub); client.ResetStub(&stub);
client.DoEcho(); client.DoEcho();
} }
TEST_F(MockTest, ClientStream) {
ResetStub();
FakeClient client(stub_.get());
client.DoRequestStream();
MockEchoTestServiceStub stub;
auto w = new MockClientWriter<EchoRequest>();
EchoResponse resp;
resp.set_message("hello, world");
EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true));
EXPECT_CALL(*w, WritesDone());
EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK));
EXPECT_CALL(stub, RequestStreamRaw(_, _))
.WillOnce(DoAll(SetArgPointee<1>(resp), Return(w)));
client.ResetStub(&stub);
client.DoRequestStream();
}
TEST_F(MockTest, ServerStream) {
ResetStub();
FakeClient client(stub_.get());
client.DoResponseStream();
MockEchoTestServiceStub stub;
auto r = new MockClientReader<EchoResponse>();
EchoResponse resp1;
resp1.set_message("hello");
EchoResponse resp2;
resp2.set_message("world");
EXPECT_CALL(*r, Read(_))
.WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true)))
.WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true)))
.WillOnce(Return(false));
EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK));
EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r));
client.ResetStub(&stub);
client.DoResponseStream();
}
ACTION_P(copy, msg) { arg0->set_message(msg->message()); }
TEST_F(MockTest, BidiStream) { TEST_F(MockTest, BidiStream) {
ResetStub(); ResetStub();
FakeClient client(stub_.get()); FakeClient client(stub_.get());
client.DoBidiStream(); client.DoBidiStream();
MockStub stub; MockEchoTestServiceStub stub;
auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>();
EchoRequest msg;
EXPECT_CALL(*rw, Write(_, _))
.Times(3)
.WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true)));
EXPECT_CALL(*rw, Read(_))
.WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
.WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
.WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
.WillOnce(Return(false));
EXPECT_CALL(*rw, WritesDone());
EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK));
EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw));
client.ResetStub(&stub); client.ResetStub(&stub);
client.DoBidiStream(); client.DoBidiStream();
} }

@ -113,13 +113,17 @@ class TCP : public FullstackFixture {
public: public:
TCP(Service* service, const FixtureConfiguration& fixture_configuration = TCP(Service* service, const FixtureConfiguration& fixture_configuration =
FixtureConfiguration()) FixtureConfiguration())
: FullstackFixture(service, fixture_configuration, MakeAddress()) {} : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
~TCP() { grpc_recycle_unused_port(port_); }
private: private:
static grpc::string MakeAddress() { int port_;
int port = grpc_pick_unused_port_or_die();
static grpc::string MakeAddress(int* port) {
*port = grpc_pick_unused_port_or_die();
std::stringstream addr; std::stringstream addr;
addr << "localhost:" << port; addr << "localhost:" << *port;
return addr.str(); return addr.str();
} }
}; };
@ -128,14 +132,18 @@ class UDS : public FullstackFixture {
public: public:
UDS(Service* service, const FixtureConfiguration& fixture_configuration = UDS(Service* service, const FixtureConfiguration& fixture_configuration =
FixtureConfiguration()) FixtureConfiguration())
: FullstackFixture(service, fixture_configuration, MakeAddress()) {} : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
~UDS() { grpc_recycle_unused_port(port_); }
private: private:
static grpc::string MakeAddress() { int port_;
int port = grpc_pick_unused_port_or_die(); // just for a unique id - not a
static grpc::string MakeAddress(int* port) {
*port = grpc_pick_unused_port_or_die(); // just for a unique id - not a
// real port // real port
std::stringstream addr; std::stringstream addr;
addr << "unix:/tmp/bm_fullstack." << port; addr << "unix:/tmp/bm_fullstack." << *port;
return addr.str(); return addr.str();
} }
}; };

@ -2,11 +2,14 @@ cc_library(
name = "gtest", name = "gtest",
srcs = [ srcs = [
"googletest/src/gtest-all.cc", "googletest/src/gtest-all.cc",
"googlemock/src/gmock-all.cc"
], ],
hdrs = glob(["googletest/include/**/*.h", "googletest/src/*.cc", "googletest/src/*.h"]), hdrs = glob(["googletest/include/**/*.h", "googletest/src/*.cc", "googletest/src/*.h", "googlemock/include/**/*.h", "googlemock/src/*.cc", "googlemock/src/*.h"]),
includes = [ includes = [
"googletest", "googletest",
"googletest/include", "googletest/include",
"googlemock",
"googlemock/include",
], ],
linkstatic = 1, linkstatic = 1,
visibility = [ visibility = [

@ -37,4 +37,5 @@ BENCHMARKS_TO_RUN="bm_fullstack_unary_ping_pong bm_fullstack_streaming_ping_pong
# Enter the gRPC repo root # Enter the gRPC repo root
cd $(dirname $0)/../.. cd $(dirname $0)/../..
tools/run_tests/start_port_server.py
tools/profiling/microbenchmarks/bm_diff.py -d origin/$ghprbTargetBranch -b $BENCHMARKS_TO_RUN tools/profiling/microbenchmarks/bm_diff.py -d origin/$ghprbTargetBranch -b $BENCHMARKS_TO_RUN

@ -204,7 +204,10 @@ def eintr_be_gone(fn):
def read_json(filename): def read_json(filename):
try:
with open(filename) as f: return json.loads(f.read()) with open(filename) as f: return json.loads(f.read())
except ValueError, e:
return None
def finalize(): def finalize():
@ -217,11 +220,13 @@ def finalize():
js_old_ctr = read_json('%s.counters.old.%d.json' % (bm, loop)) js_old_ctr = read_json('%s.counters.old.%d.json' % (bm, loop))
js_old_opt = read_json('%s.opt.old.%d.json' % (bm, loop)) js_old_opt = read_json('%s.opt.old.%d.json' % (bm, loop))
if js_new_ctr:
for row in bm_json.expand_json(js_new_ctr, js_new_opt): for row in bm_json.expand_json(js_new_ctr, js_new_opt):
print row print row
name = row['cpp_name'] name = row['cpp_name']
if name.endswith('_mean') or name.endswith('_stddev'): continue if name.endswith('_mean') or name.endswith('_stddev'): continue
benchmarks[name].add_sample(row, True) benchmarks[name].add_sample(row, True)
if js_old_ctr:
for row in bm_json.expand_json(js_old_ctr, js_old_opt): for row in bm_json.expand_json(js_old_ctr, js_old_opt):
print row print row
name = row['cpp_name'] name = row['cpp_name']

@ -2871,14 +2871,19 @@
"headers": [ "headers": [
"src/proto/grpc/testing/control.grpc.pb.h", "src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h", "src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/payloads.grpc.pb.h", "src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h", "src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
"src/proto/grpc/testing/services.grpc.pb.h", "src/proto/grpc/testing/services.grpc.pb.h",
"src/proto/grpc/testing/services.pb.h", "src/proto/grpc/testing/services.pb.h",
"src/proto/grpc/testing/services_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h", "src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h" "src/proto/grpc/testing/stats.pb.h",
"src/proto/grpc/testing/stats_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -2899,14 +2904,19 @@
"headers": [ "headers": [
"src/proto/grpc/testing/control.grpc.pb.h", "src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h", "src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/payloads.grpc.pb.h", "src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h", "src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
"src/proto/grpc/testing/services.grpc.pb.h", "src/proto/grpc/testing/services.grpc.pb.h",
"src/proto/grpc/testing/services.pb.h", "src/proto/grpc/testing/services.pb.h",
"src/proto/grpc/testing/services_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h", "src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h" "src/proto/grpc/testing/stats.pb.h",
"src/proto/grpc/testing/stats_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3027,7 +3037,8 @@
], ],
"headers": [ "headers": [
"src/proto/grpc/testing/echo_messages.grpc.pb.h", "src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h" "src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3084,7 +3095,8 @@
], ],
"headers": [ "headers": [
"src/proto/grpc/testing/compiler_test.grpc.pb.h", "src/proto/grpc/testing/compiler_test.grpc.pb.h",
"src/proto/grpc/testing/compiler_test.pb.h" "src/proto/grpc/testing/compiler_test.pb.h",
"src/proto/grpc/testing/compiler_test_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3229,7 +3241,9 @@
"src/proto/grpc/testing/echo.grpc.pb.h", "src/proto/grpc/testing/echo.grpc.pb.h",
"src/proto/grpc/testing/echo.pb.h", "src/proto/grpc/testing/echo.pb.h",
"src/proto/grpc/testing/echo_messages.grpc.pb.h", "src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h" "src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3249,7 +3263,8 @@
], ],
"headers": [ "headers": [
"src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h",
"src/proto/grpc/lb/v1/load_balancer.pb.h" "src/proto/grpc/lb/v1/load_balancer.pb.h",
"src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3271,7 +3286,8 @@
], ],
"headers": [ "headers": [
"src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h",
"src/proto/grpc/lb/v1/load_balancer.pb.h" "src/proto/grpc/lb/v1/load_balancer.pb.h",
"src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3426,6 +3442,7 @@
"headers": [ "headers": [
"src/proto/grpc/testing/metrics.grpc.pb.h", "src/proto/grpc/testing/metrics.grpc.pb.h",
"src/proto/grpc/testing/metrics.pb.h", "src/proto/grpc/testing/metrics.pb.h",
"src/proto/grpc/testing/metrics_mock.grpc.pb.h",
"test/cpp/util/metrics_server.h" "test/cpp/util/metrics_server.h"
], ],
"is_filegroup": false, "is_filegroup": false,
@ -3447,11 +3464,14 @@
"grpc++_test_util", "grpc++_test_util",
"grpc_test_util" "grpc_test_util"
], ],
"headers": [], "headers": [
"include/grpc++/test/mock_stream.h"
],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
"name": "mock_test", "name": "mock_test",
"src": [ "src": [
"include/grpc++/test/mock_stream.h",
"test/cpp/end2end/mock_test.cc" "test/cpp/end2end/mock_test.cc"
], ],
"third_party": false, "third_party": false,
@ -3610,10 +3630,13 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h" "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3639,10 +3662,13 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h" "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3743,7 +3769,9 @@
"src/proto/grpc/testing/echo.grpc.pb.h", "src/proto/grpc/testing/echo.grpc.pb.h",
"src/proto/grpc/testing/echo.pb.h", "src/proto/grpc/testing/echo.pb.h",
"src/proto/grpc/testing/echo_messages.grpc.pb.h", "src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h" "src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -3880,12 +3908,16 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/metrics.grpc.pb.h", "src/proto/grpc/testing/metrics.grpc.pb.h",
"src/proto/grpc/testing/metrics.pb.h", "src/proto/grpc/testing/metrics.pb.h",
"src/proto/grpc/testing/metrics_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h", "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h",
"test/cpp/interop/client_helper.h", "test/cpp/interop/client_helper.h",
"test/cpp/interop/interop_client.h", "test/cpp/interop/interop_client.h",
"test/cpp/interop/stress_interop_client.h", "test/cpp/interop/stress_interop_client.h",
@ -5900,7 +5932,8 @@
"headers": [ "headers": [
"include/grpc++/support/error_details.h", "include/grpc++/support/error_details.h",
"src/proto/grpc/status/status.grpc.pb.h", "src/proto/grpc/status/status.grpc.pb.h",
"src/proto/grpc/status/status.pb.h" "src/proto/grpc/status/status.pb.h",
"src/proto/grpc/status/status_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -5980,12 +6013,16 @@
"headers": [ "headers": [
"src/proto/grpc/health/v1/health.grpc.pb.h", "src/proto/grpc/health/v1/health.grpc.pb.h",
"src/proto/grpc/health/v1/health.pb.h", "src/proto/grpc/health/v1/health.pb.h",
"src/proto/grpc/health/v1/health_mock.grpc.pb.h",
"src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h", "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h",
"src/proto/grpc/testing/duplicate/echo_duplicate.pb.h", "src/proto/grpc/testing/duplicate/echo_duplicate.pb.h",
"src/proto/grpc/testing/duplicate/echo_duplicate_mock.grpc.pb.h",
"src/proto/grpc/testing/echo.grpc.pb.h", "src/proto/grpc/testing/echo.grpc.pb.h",
"src/proto/grpc/testing/echo.pb.h", "src/proto/grpc/testing/echo.pb.h",
"src/proto/grpc/testing/echo_messages.grpc.pb.h", "src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h", "src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h",
"test/cpp/end2end/test_service_impl.h", "test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/create_test_channel.h", "test/cpp/util/create_test_channel.h",
@ -6165,10 +6202,13 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h", "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h",
"test/cpp/interop/http2_client.h" "test/cpp/interop/http2_client.h"
], ],
"is_filegroup": false, "is_filegroup": false,
@ -6192,6 +6232,7 @@
"headers": [ "headers": [
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"test/cpp/interop/client_helper.h" "test/cpp/interop/client_helper.h"
], ],
"is_filegroup": false, "is_filegroup": false,
@ -6218,10 +6259,13 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h", "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h",
"test/cpp/interop/interop_client.h" "test/cpp/interop/interop_client.h"
], ],
"is_filegroup": false, "is_filegroup": false,
@ -6270,10 +6314,13 @@
"headers": [ "headers": [
"src/proto/grpc/testing/empty.grpc.pb.h", "src/proto/grpc/testing/empty.grpc.pb.h",
"src/proto/grpc/testing/empty.pb.h", "src/proto/grpc/testing/empty.pb.h",
"src/proto/grpc/testing/empty_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/test.grpc.pb.h", "src/proto/grpc/testing/test.grpc.pb.h",
"src/proto/grpc/testing/test.pb.h" "src/proto/grpc/testing/test.pb.h",
"src/proto/grpc/testing/test_mock.grpc.pb.h"
], ],
"is_filegroup": false, "is_filegroup": false,
"language": "c++", "language": "c++",
@ -6307,14 +6354,19 @@
"headers": [ "headers": [
"src/proto/grpc/testing/control.grpc.pb.h", "src/proto/grpc/testing/control.grpc.pb.h",
"src/proto/grpc/testing/control.pb.h", "src/proto/grpc/testing/control.pb.h",
"src/proto/grpc/testing/control_mock.grpc.pb.h",
"src/proto/grpc/testing/messages.grpc.pb.h", "src/proto/grpc/testing/messages.grpc.pb.h",
"src/proto/grpc/testing/messages.pb.h", "src/proto/grpc/testing/messages.pb.h",
"src/proto/grpc/testing/messages_mock.grpc.pb.h",
"src/proto/grpc/testing/payloads.grpc.pb.h", "src/proto/grpc/testing/payloads.grpc.pb.h",
"src/proto/grpc/testing/payloads.pb.h", "src/proto/grpc/testing/payloads.pb.h",
"src/proto/grpc/testing/payloads_mock.grpc.pb.h",
"src/proto/grpc/testing/services.grpc.pb.h", "src/proto/grpc/testing/services.grpc.pb.h",
"src/proto/grpc/testing/services.pb.h", "src/proto/grpc/testing/services.pb.h",
"src/proto/grpc/testing/services_mock.grpc.pb.h",
"src/proto/grpc/testing/stats.grpc.pb.h", "src/proto/grpc/testing/stats.grpc.pb.h",
"src/proto/grpc/testing/stats.pb.h", "src/proto/grpc/testing/stats.pb.h",
"src/proto/grpc/testing/stats_mock.grpc.pb.h",
"test/cpp/qps/benchmark_config.h", "test/cpp/qps/benchmark_config.h",
"test/cpp/qps/client.h", "test/cpp/qps/client.h",
"test/cpp/qps/driver.h", "test/cpp/qps/driver.h",
@ -9023,7 +9075,8 @@
"deps": [], "deps": [],
"headers": [ "headers": [
"src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h", "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h",
"src/proto/grpc/reflection/v1alpha/reflection.pb.h" "src/proto/grpc/reflection/v1alpha/reflection.pb.h",
"src/proto/grpc/reflection/v1alpha/reflection_mock.grpc.pb.h"
], ],
"is_filegroup": true, "is_filegroup": true,
"language": "c++", "language": "c++",
@ -9037,12 +9090,14 @@
"grpc++" "grpc++"
], ],
"headers": [ "headers": [
"include/grpc++/test/mock_stream.h",
"include/grpc++/test/server_context_test_spouse.h" "include/grpc++/test/server_context_test_spouse.h"
], ],
"is_filegroup": true, "is_filegroup": true,
"language": "c++", "language": "c++",
"name": "grpc++_test", "name": "grpc++_test",
"src": [ "src": [
"include/grpc++/test/mock_stream.h",
"include/grpc++/test/server_context_test_spouse.h" "include/grpc++/test/server_context_test_spouse.h"
], ],
"third_party": false, "third_party": false,

@ -3329,7 +3329,7 @@
}, },
{ {
"args": [ "args": [
"--generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h" "--generated_file_path=gens/src/proto/grpc/testing/"
], ],
"ci_platforms": [ "ci_platforms": [
"linux", "linux",

@ -33,18 +33,20 @@
from __future__ import print_function from __future__ import print_function
import argparse import argparse
from six.moves import BaseHTTPServer from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import hashlib import hashlib
import os import os
import socket import socket
import sys import sys
import time import time
from SocketServer import ThreadingMixIn
import threading
# increment this number whenever making a change to ensure that # increment this number whenever making a change to ensure that
# the changes are picked up by running CI servers # the changes are picked up by running CI servers
# note that all changes must be backwards compatible # note that all changes must be backwards compatible
_MY_VERSION = 9 _MY_VERSION = 14
if len(sys.argv) == 2 and sys.argv[1] == 'dump_version': if len(sys.argv) == 2 and sys.argv[1] == 'dump_version':
@ -68,6 +70,7 @@ print('port server running on port %d' % args.port)
pool = [] pool = []
in_use = {} in_use = {}
mu = threading.Lock()
def refill_pool(max_timeout, req): def refill_pool(max_timeout, req):
@ -95,28 +98,33 @@ def refill_pool(max_timeout, req):
def allocate_port(req): def allocate_port(req):
global pool global pool
global in_use global in_use
global mu
mu.acquire()
max_timeout = 600 max_timeout = 600
while not pool: while not pool:
refill_pool(max_timeout, req) refill_pool(max_timeout, req)
if not pool: if not pool:
req.log_message("failed to find ports: retrying soon") req.log_message("failed to find ports: retrying soon")
mu.release()
time.sleep(1) time.sleep(1)
mu.acquire()
max_timeout /= 2 max_timeout /= 2
port = pool[0] port = pool[0]
pool = pool[1:] pool = pool[1:]
in_use[port] = time.time() in_use[port] = time.time()
mu.release()
return port return port
keep_running = True keep_running = True
class Handler(BaseHTTPServer.BaseHTTPRequestHandler): class Handler(BaseHTTPRequestHandler):
def setup(self): def setup(self):
# If the client is unreachable for 5 seconds, close the connection # If the client is unreachable for 5 seconds, close the connection
self.timeout = 5 self.timeout = 5
BaseHTTPServer.BaseHTTPRequestHandler.setup(self) BaseHTTPRequestHandler.setup(self)
def do_GET(self): def do_GET(self):
global keep_running global keep_running
@ -158,12 +166,11 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
elif self.path == '/quitquitquit': elif self.path == '/quitquitquit':
self.send_response(200) self.send_response(200)
self.end_headers() self.end_headers()
keep_running = False self.server.shutdown()
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread"""
httpd = BaseHTTPServer.HTTPServer(('', args.port), Handler)
while keep_running:
httpd.handle_request()
sys.stderr.flush()
print('done') ThreadedHTTPServer(('', args.port), Handler).serve_forever()

@ -159,6 +159,9 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\test\mock_stream.h" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\mock_test.cc"> <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\mock_test.cc">
</ClCompile> </ClCompile>

@ -5,8 +5,22 @@
<Filter>test\cpp\end2end</Filter> <Filter>test\cpp\end2end</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\test\mock_stream.h">
<Filter>include\grpc++\test</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="include">
<UniqueIdentifier>{b827d6d2-cfa5-2dd4-6ebc-afcccd5e8e0c}</UniqueIdentifier>
</Filter>
<Filter Include="include\grpc++">
<UniqueIdentifier>{28289e8f-b68e-b9f5-7680-c15d77b574a5}</UniqueIdentifier>
</Filter>
<Filter Include="include\grpc++\test">
<UniqueIdentifier>{4a7b43be-c730-6221-d190-e394521f9ae7}</UniqueIdentifier>
</Filter>
<Filter Include="test"> <Filter Include="test">
<UniqueIdentifier>{69c257a2-3e4c-a86e-ce0d-1a97b237d294}</UniqueIdentifier> <UniqueIdentifier>{69c257a2-3e4c-a86e-ce0d-1a97b237d294}</UniqueIdentifier>
</Filter> </Filter>

Loading…
Cancel
Save