Merge pull request #15097 from matt-kwong/xcode-9.2

Update xcode version for macOS Obj-C tests to 9.2
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index fb6f98c..12f46d1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,6 +4,6 @@
 /**/OWNERS @markdroth @nicolasnoble @a11r
 /bazel/** @nicolasnoble @dgquintas @a11r @vjpai
 /cmake/** @jtattermusch @nicolasnoble @matt-kwong
-/src/core/ext/filters/client_channel/** @markdroth @dgquintas @a11r
+/src/core/ext/filters/client_channel/** @markdroth @dgquintas @AspirinSJL
 /tools/dockerfile/** @jtattermusch @matt-kwong @nicolasnoble
 /tools/run_tests/performance/** @ncteisen @matt-kwong @jtattermusch
diff --git a/.pylintrc-tests b/.pylintrc-tests
new file mode 100644
index 0000000..b358b2c
--- /dev/null
+++ b/.pylintrc-tests
@@ -0,0 +1,108 @@
+[VARIABLES]
+
+# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection
+# not include "unused_" and "ignored_" by default?
+dummy-variables-rgx=^ignored_|^unused_
+
+[DESIGN]
+
+# NOTE(nathaniel): Not particularly attached to this value; it just seems to
+# be what works for us at the moment (excepting the dead-code-walking Beta
+# API).
+max-args=6
+
+[MISCELLANEOUS]
+
+# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
+# "NOTE(<username or issue link>): ". We do not allow "TODO:",
+# "TODO(<username>):", "FIXME:", or anything else.
+notes=FIXME,XXX
+
+[MESSAGES CONTROL]
+
+disable=
+	# These suppressions are specific to tests:
+	#
+	# TODO(https://github.com/grpc/grpc/issues/261): investigate
+	# each of the following one by one and consider eliminating
+	# the suppression category.
+	# Eventually, the hope is to eliminate the .pylintrc-tests
+	# altogether and rely on .pylintrc for everything.
+	pointless-statement,
+	no-member,
+	no-self-use,
+	attribute-defined-outside-init,
+	unused-argument,
+	unused-variable,
+	unused-import,
+	redefined-builtin,
+	too-many-public-methods,
+	too-many-locals,
+	redefined-variable-type,
+	redefined-outer-name,
+	ungrouped-imports,
+	too-many-branches,
+	too-many-arguments,
+	too-many-format-args,
+	too-many-return-statements,
+	too-many-statements,
+	line-too-long,
+	wrong-import-position,
+	wrong-import-order,
+	# -- END OF TEST-SPECIFIC SUPPRESSIONS --
+
+
+	# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
+	# Enable cyclic-import after a 1.7-or-later pylint release that
+	# recognizes our disable=cyclic-import suppressions.
+	cyclic-import,
+	# TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the
+	# Beta API is removed.
+	duplicate-code,
+	# TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to
+	# understand enum and concurrent.futures; look into this later with the
+	# latest pylint version.
+	import-error,
+	# TODO(https://github.com/grpc/grpc/issues/261): Enable this one.
+	# Should take a little configuration but not much.
+	invalid-name,
+	# TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to
+	# work for now? Try with a later pylint?
+	locally-disabled,
+	# NOTE(nathaniel): What even is this? *Enabling* an inspection results
+	# in a warning? How does that encourage more analysis and coverage?
+	locally-enabled,
+	# NOTE(nathaniel): We don't write doc strings for most private code
+	# elements.
+	missing-docstring,
+	# NOTE(nathaniel): In numeric comparisons it is better to have the
+	# lesser (or lesser-or-equal-to) quantity on the left when the
+	# expression is true than it is to worry about which is an identifier
+	# and which a literal value.
+	misplaced-comparison-constant,
+	# NOTE(nathaniel): Our completely abstract interface classes don't have
+	# constructors.
+	no-init,
+	# TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play
+	# nicely with some of our code being implemented in Cython. Maybe in a
+	# later version?
+	no-name-in-module,
+	# TODO(https://github.com/grpc/grpc/issues/261): Suppress these where
+	# the odd shape of the authentication portion of the API forces them on
+	# us and enable everywhere else.
+	protected-access,
+	# NOTE(nathaniel): Pylint and I will probably never agree on this.
+	too-few-public-methods,
+	# NOTE(nathaniel): Pylint and I wil probably never agree on this for
+	# private classes. For public classes maybe?
+	too-many-instance-attributes,
+	# NOTE(nathaniel): Some of our modules have a lot of lines... of
+	# specification and documentation. Maybe if this were
+	# lines-of-code-based we would use it.
+	too-many-lines,
+	# TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have
+	# this one if we extracted just a few more helper functions...
+	too-many-nested-blocks,
+	# NOTE(nathaniel): I have disputed the premise of this inspection from
+	# the beginning and will continue to do so until it goes away for good.
+	useless-else-on-loop,
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 18400ea..88df3fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4993,10 +4993,18 @@
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
   test/cpp/qps/benchmark_config.cc
   test/cpp/qps/client_async.cc
   test/cpp/qps/client_sync.cc
@@ -5033,7 +5041,13 @@
   src/proto/grpc/testing/control.proto
 )
 protobuf_generate_grpc_cpp(
-  src/proto/grpc/testing/services.proto
+  src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/worker_service.proto
 )
 
 target_include_directories(qps
@@ -10733,10 +10747,18 @@
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
@@ -10756,7 +10778,13 @@
   src/proto/grpc/testing/payloads.proto
 )
 protobuf_generate_grpc_cpp(
-  src/proto/grpc/testing/services.proto
+  src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/worker_service.proto
 )
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/stats.proto
@@ -10805,10 +10833,18 @@
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
-  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
@@ -10829,7 +10865,13 @@
   src/proto/grpc/testing/payloads.proto
 )
 protobuf_generate_grpc_cpp(
-  src/proto/grpc/testing/services.proto
+  src/proto/grpc/testing/benchmark_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/report_qps_scenario_service.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/worker_service.proto
 )
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/stats.proto
diff --git a/Makefile b/Makefile
index da5f2ef..dce07b2 100644
--- a/Makefile
+++ b/Makefile
@@ -2570,6 +2570,22 @@
 endif
 
 ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(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) $<
+endif
+
+ifeq ($(NO_PROTOC),true)
 $(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
 else
@@ -2716,16 +2732,16 @@
 endif
 
 ifeq ($(NO_PROTOC),true)
-$(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/report_qps_scenario_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: protoc_dep_error
 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/report_qps_scenario_service.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
+$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(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) $<
@@ -2763,6 +2779,22 @@
 	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
+ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: src/proto/grpc/testing/worker_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: src/proto/grpc/testing/worker_service.proto $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(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) $<
+endif
+
 
 ifeq ($(CONFIG),stapprof)
 src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
@@ -7180,7 +7212,9 @@
     $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
     test/cpp/qps/benchmark_config.cc \
     test/cpp/qps/client_async.cc \
     test/cpp/qps/client_sync.cc \
@@ -7236,16 +7270,16 @@
 -include $(LIBQPS_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc
 
 
 LIBGRPC_CSHARP_EXT_SRC = \
@@ -16496,7 +16530,9 @@
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     test/cpp/codegen/codegen_test_full.cc \
 
@@ -16535,7 +16571,11 @@
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/benchmark_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/report_qps_scenario_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/worker_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
@@ -16548,14 +16588,16 @@
 -include $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 
 
 CODEGEN_TEST_MINIMAL_SRC = \
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     test/cpp/codegen/codegen_test_minimal.cc \
     src/cpp/codegen/codegen_init.cc \
@@ -16595,7 +16637,11 @@
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/benchmark_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/report_qps_scenario_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/worker_service.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
@@ -16610,8 +16656,8 @@
 -include $(CODEGEN_TEST_MINIMAL_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 
 
 CREDENTIALS_TEST_SRC = \
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 00e313c..3c69a6b 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -85,8 +85,8 @@
     if "com_google_protobuf" not in native.existing_rules():
         native.http_archive(
             name = "com_google_protobuf",
-            strip_prefix = "protobuf-2761122b810fe8861004ae785cc3ab39f384d342",
-            url = "https://github.com/google/protobuf/archive/2761122b810fe8861004ae785cc3ab39f384d342.tar.gz",
+            strip_prefix = "protobuf-b5fbb742af122b565925987e65c08957739976a7",
+            url = "https://github.com/google/protobuf/archive/b5fbb742af122b565925987e65c08957739976a7.tar.gz",
         )
 
     if "com_github_google_googletest" not in native.existing_rules():
diff --git a/build.yaml b/build.yaml
index fde95d7..e9ad25d 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1910,7 +1910,9 @@
   - src/proto/grpc/testing/payloads.proto
   - src/proto/grpc/testing/stats.proto
   - src/proto/grpc/testing/control.proto
-  - src/proto/grpc/testing/services.proto
+  - src/proto/grpc/testing/benchmark_service.proto
+  - src/proto/grpc/testing/report_qps_scenario_service.proto
+  - src/proto/grpc/testing/worker_service.proto
   - test/cpp/qps/benchmark_config.cc
   - test/cpp/qps/client_async.cc
   - test/cpp/qps/client_sync.cc
@@ -4266,7 +4268,9 @@
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/payloads.proto
-  - src/proto/grpc/testing/services.proto
+  - src/proto/grpc/testing/benchmark_service.proto
+  - src/proto/grpc/testing/report_qps_scenario_service.proto
+  - src/proto/grpc/testing/worker_service.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_full.cc
   deps:
@@ -4285,7 +4289,9 @@
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/payloads.proto
-  - src/proto/grpc/testing/services.proto
+  - src/proto/grpc/testing/benchmark_service.proto
+  - src/proto/grpc/testing/report_qps_scenario_service.proto
+  - src/proto/grpc/testing/worker_service.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_minimal.cc
   deps:
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index ed46a48..587ab83 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -50,6 +50,7 @@
   - channel_stack_builder - traces information about channel stacks being built
   - executor - traces grpc's internal thread pool ('the executor')
   - glb - traces the grpclb load balancer
+  - handshaker - traces handshaking state
   - http - traces state in the http2 transport engine
   - http2_stream_state - traces all http2 stream state mutations.
   - http1 - traces HTTP/1.x operations performed by gRPC
diff --git a/etc/roots.pem b/etc/roots.pem
index 15d819b..5dbd1ae 100644
--- a/etc/roots.pem
+++ b/etc/roots.pem
@@ -3525,39 +3525,6 @@
 5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
 -----END CERTIFICATE-----
 
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-# Serial: 156233699172481
-# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e
-# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb
-# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78
------BEGIN CERTIFICATE-----
-MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE
-BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn
-aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg
-QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0
-MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD
-VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
-dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom
-/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR
-Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3
-4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z
-5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0
-hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID
-AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX
-SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l
-VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
-URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf
-peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF
-Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
-+qtB4Uu2NQvAmxU=
------END CERTIFICATE-----
-
 # Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
 # Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903
 # Label: "Certinomis - Root CA"
diff --git a/grpc.gyp b/grpc.gyp
index 8d9422e..a32dec1 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -1652,7 +1652,9 @@
         'src/proto/grpc/testing/payloads.proto',
         'src/proto/grpc/testing/stats.proto',
         'src/proto/grpc/testing/control.proto',
-        'src/proto/grpc/testing/services.proto',
+        'src/proto/grpc/testing/benchmark_service.proto',
+        'src/proto/grpc/testing/report_qps_scenario_service.proto',
+        'src/proto/grpc/testing/worker_service.proto',
         'test/cpp/qps/benchmark_config.cc',
         'test/cpp/qps/client_async.cc',
         'test/cpp/qps/client_sync.cc',
diff --git a/src/core/ext/filters/client_channel/OWNERS b/src/core/ext/filters/client_channel/OWNERS
index 8f5e928..c8760d9 100644
--- a/src/core/ext/filters/client_channel/OWNERS
+++ b/src/core/ext/filters/client_channel/OWNERS
@@ -1,4 +1,4 @@
 set noparent
 @markdroth
 @dgquintas
-@a11r
+@AspirinSJL
diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
index fb29fa7..4e8b8b7 100644
--- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -326,7 +326,7 @@
 
 static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
     http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
-    http_connect_handshaker_do_handshake};
+    http_connect_handshaker_do_handshake, "http_connect"};
 
 static grpc_handshaker* grpc_http_connect_handshaker_create() {
   http_connect_handshaker* handshaker =
diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc
index 66a86c2..e49d532 100644
--- a/src/core/lib/channel/channel_args.cc
+++ b/src/core/lib/channel/channel_args.cc
@@ -411,3 +411,31 @@
   arg.value.pointer.vtable = vtable;
   return arg;
 }
+
+char* grpc_channel_args_string(const grpc_channel_args* args) {
+  if (args == nullptr) return nullptr;
+  gpr_strvec v;
+  gpr_strvec_init(&v);
+  for (size_t i = 0; i < args->num_args; ++i) {
+    const grpc_arg& arg = args->args[i];
+    char* s;
+    switch (arg.type) {
+      case GRPC_ARG_INTEGER:
+        gpr_asprintf(&s, "%s=%d", arg.key, arg.value.integer);
+        break;
+      case GRPC_ARG_STRING:
+        gpr_asprintf(&s, "%s=%s", arg.key, arg.value.string);
+        break;
+      case GRPC_ARG_POINTER:
+        gpr_asprintf(&s, "%s=%p", arg.key, arg.value.pointer.p);
+        break;
+      default:
+        gpr_asprintf(&s, "arg with unknown type");
+    }
+    gpr_strvec_add(&v, s);
+  }
+  char* result =
+      gpr_strjoin_sep(const_cast<const char**>(v.strs), v.count, ", ", nullptr);
+  gpr_strvec_destroy(&v);
+  return result;
+}
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index c0d6a17..5ff303a 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -124,4 +124,8 @@
 grpc_arg grpc_channel_arg_pointer_create(char* name, void* value,
                                          const grpc_arg_pointer_vtable* vtable);
 
+// Returns a string representing channel args in human-readable form.
+// Callers takes ownership of result.
+char* grpc_channel_args_string(const grpc_channel_args* args);
+
 #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */
diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc
index 9b1af8d..9cd9782 100644
--- a/src/core/lib/channel/handshaker.cc
+++ b/src/core/lib/channel/handshaker.cc
@@ -22,11 +22,15 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/timer.h"
 
+grpc_core::TraceFlag grpc_handshaker_trace(false, "handshaker");
+
 //
 // grpc_handshaker
 //
@@ -52,6 +56,10 @@
                                    args);
 }
 
+const char* grpc_handshaker_name(grpc_handshaker* handshaker) {
+  return handshaker->vtable->name;
+}
+
 //
 // grpc_handshake_manager
 //
@@ -127,6 +135,12 @@
 
 void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
                                 grpc_handshaker* handshaker) {
+  if (grpc_handshaker_trace.enabled()) {
+    gpr_log(
+        GPR_DEBUG,
+        "handshake_manager %p: adding handshaker %s [%p] at index %" PRIuPTR,
+        mgr, grpc_handshaker_name(handshaker), handshaker, mgr->count);
+  }
   gpr_mu_lock(&mgr->mu);
   // To avoid allocating memory for each handshaker we add, we double
   // the number of elements every time we need more.
@@ -172,23 +186,56 @@
   GRPC_ERROR_UNREF(why);
 }
 
+static char* handshaker_args_string(grpc_handshaker_args* args) {
+  char* args_str = grpc_channel_args_string(args->args);
+  size_t num_args = args->args != nullptr ? args->args->num_args : 0;
+  size_t read_buffer_length =
+      args->read_buffer != nullptr ? args->read_buffer->length : 0;
+  char* str;
+  gpr_asprintf(&str,
+               "{endpoint=%p, args=%p {size=%" PRIuPTR
+               ": %s}, read_buffer=%p (length=%" PRIuPTR "), exit_early=%d}",
+               args->endpoint, args->args, num_args, args_str,
+               args->read_buffer, read_buffer_length, args->exit_early);
+  gpr_free(args_str);
+  return str;
+}
+
 // Helper function to call either the next handshaker or the
 // on_handshake_done callback.
 // Returns true if we've scheduled the on_handshake_done callback.
 static bool call_next_handshaker_locked(grpc_handshake_manager* mgr,
                                         grpc_error* error) {
+  if (grpc_handshaker_trace.enabled()) {
+    char* args_str = handshaker_args_string(&mgr->args);
+    gpr_log(GPR_DEBUG,
+            "handshake_manager %p: error=%s shutdown=%d index=%" PRIuPTR
+            ", args=%s",
+            mgr, grpc_error_string(error), mgr->shutdown, mgr->index, args_str);
+    gpr_free(args_str);
+  }
   GPR_ASSERT(mgr->index <= mgr->count);
   // If we got an error or we've been shut down or we're exiting early or
   // we've finished the last handshaker, invoke the on_handshake_done
   // callback.  Otherwise, call the next handshaker.
   if (error != GRPC_ERROR_NONE || mgr->shutdown || mgr->args.exit_early ||
       mgr->index == mgr->count) {
+    if (grpc_handshaker_trace.enabled()) {
+      gpr_log(GPR_DEBUG, "handshake_manager %p: handshaking complete", mgr);
+    }
     // Cancel deadline timer, since we're invoking the on_handshake_done
     // callback now.
     grpc_timer_cancel(&mgr->deadline_timer);
     GRPC_CLOSURE_SCHED(&mgr->on_handshake_done, error);
     mgr->shutdown = true;
   } else {
+    if (grpc_handshaker_trace.enabled()) {
+      gpr_log(
+          GPR_DEBUG,
+          "handshake_manager %p: calling handshaker %s [%p] at index %" PRIuPTR,
+          mgr, grpc_handshaker_name(mgr->handshakers[mgr->index]),
+          mgr->handshakers[mgr->index], mgr->index);
+    }
     grpc_handshaker_do_handshake(mgr->handshakers[mgr->index], mgr->acceptor,
                                  &mgr->call_next_handshaker, &mgr->args);
   }
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index dfecd81..be7fd12 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -84,6 +84,9 @@
                        grpc_tcp_server_acceptor* acceptor,
                        grpc_closure* on_handshake_done,
                        grpc_handshaker_args* args);
+
+  /// The name of the handshaker, for debugging purposes.
+  const char* name;
 } grpc_handshaker_vtable;
 
 /// Base struct.  To subclass, make this the first member of the
@@ -102,6 +105,7 @@
                                   grpc_tcp_server_acceptor* acceptor,
                                   grpc_closure* on_handshake_done,
                                   grpc_handshaker_args* args);
+const char* grpc_handshaker_name(grpc_handshaker* handshaker);
 
 ///
 /// grpc_handshake_manager
diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc
index 0c97dfa..57dd340 100644
--- a/src/core/lib/security/transport/security_handshaker.cc
+++ b/src/core/lib/security/transport/security_handshaker.cc
@@ -406,7 +406,7 @@
 
 static const grpc_handshaker_vtable security_handshaker_vtable = {
     security_handshaker_destroy, security_handshaker_shutdown,
-    security_handshaker_do_handshake};
+    security_handshaker_do_handshake, "security"};
 
 static grpc_handshaker* security_handshaker_create(
     tsi_handshaker* handshaker, grpc_security_connector* connector) {
@@ -456,7 +456,7 @@
 
 static const grpc_handshaker_vtable fail_handshaker_vtable = {
     fail_handshaker_destroy, fail_handshaker_shutdown,
-    fail_handshaker_do_handshake};
+    fail_handshaker_do_handshake, "security_fail"};
 
 static grpc_handshaker* fail_handshaker_create() {
   grpc_handshaker* h = static_cast<grpc_handshaker*>(gpr_malloc(sizeof(*h)));
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index f7a7a5c..6e28c11 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -2,6 +2,6 @@
 <Project>
   <PropertyGroup>
     <GrpcCsharpVersion>1.12.0-dev</GrpcCsharpVersion>
-    <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
+    <GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
   </PropertyGroup>
 </Project>
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs
new file mode 100644
index 0000000..11d34c6
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkService.cs
@@ -0,0 +1,46 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: src/proto/grpc/testing/benchmark_service.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  /// <summary>Holder for reflection information generated from src/proto/grpc/testing/benchmark_service.proto</summary>
+  public static partial class BenchmarkServiceReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for src/proto/grpc/testing/benchmark_service.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static BenchmarkServiceReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "Ci5zcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL2JlbmNobWFya19zZXJ2aWNlLnBy",
+            "b3RvEgxncnBjLnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVz",
+            "c2FnZXMucHJvdG8ypgMKEEJlbmNobWFya1NlcnZpY2USRgoJVW5hcnlDYWxs",
+            "EhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3Rpbmcu",
+            "U2ltcGxlUmVzcG9uc2USTgoNU3RyZWFtaW5nQ2FsbBIbLmdycGMudGVzdGlu",
+            "Zy5TaW1wbGVSZXF1ZXN0GhwuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlc3BvbnNl",
+            "KAEwARJSChNTdHJlYW1pbmdGcm9tQ2xpZW50EhsuZ3JwYy50ZXN0aW5nLlNp",
+            "bXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoARJS",
+            "ChNTdHJlYW1pbmdGcm9tU2VydmVyEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJl",
+            "cXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UwARJSChFTdHJl",
+            "YW1pbmdCb3RoV2F5cxIbLmdycGMudGVzdGluZy5TaW1wbGVSZXF1ZXN0Ghwu",
+            "Z3JwYy50ZXN0aW5nLlNpbXBsZVJlc3BvbnNlKAEwAWIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, },
+          new pbr::GeneratedClrTypeInfo(null, null));
+    }
+    #endregion
+
+  }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
new file mode 100644
index 0000000..20b933f
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
@@ -0,0 +1,329 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: src/proto/grpc/testing/benchmark_service.proto
+// </auto-generated>
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+  public static partial class BenchmarkService
+  {
+    static readonly string __ServiceName = "grpc.testing.BenchmarkService";
+
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "UnaryCall",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.DuplexStreaming,
+        __ServiceName,
+        "StreamingCall",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.ClientStreaming,
+        __ServiceName,
+        "StreamingFromClient",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.ServerStreaming,
+        __ServiceName,
+        "StreamingFromServer",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        grpc::MethodType.DuplexStreaming,
+        __ServiceName,
+        "StreamingBothWays",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.BenchmarkServiceReflection.Descriptor.Services[0]; }
+    }
+
+    /// <summary>Base class for server-side implementations of BenchmarkService</summary>
+    public abstract partial class BenchmarkServiceBase
+    {
+      /// <summary>
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Repeated sequence of one request followed by one response.
+      /// Should be called streaming ping-pong
+      /// The server returns the client payload as-is on each response
+      /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task StreamingCall(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Single-sided unbounded streaming from client to server
+      /// The server returns the client payload as-is once the client does WritesDone
+      /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Single-sided unbounded streaming from server to client
+      /// The server repeatedly returns the client payload as-is
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Two-sided unbounded streaming between server to client
+      /// Both sides send the content of their own choice to the other
+      /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task StreamingBothWays(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for BenchmarkService</summary>
+    public partial class BenchmarkServiceClient : grpc::ClientBase<BenchmarkServiceClient>
+    {
+      /// <summary>Creates a new client for BenchmarkService</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public BenchmarkServiceClient(grpc::Channel channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public BenchmarkServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected BenchmarkServiceClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
+      }
+      /// <summary>
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
+      }
+      /// <summary>
+      /// Repeated sequence of one request followed by one response.
+      /// Should be called streaming ping-pong
+      /// The server returns the client payload as-is on each response
+      /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Repeated sequence of one request followed by one response.
+      /// Should be called streaming ping-pong
+      /// The server returns the client payload as-is on each response
+      /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
+      }
+      /// <summary>
+      /// Single-sided unbounded streaming from client to server
+      /// The server returns the client payload as-is once the client does WritesDone
+      /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Single-sided unbounded streaming from client to server
+      /// The server returns the client payload as-is once the client does WritesDone
+      /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncClientStreamingCall(__Method_StreamingFromClient, null, options);
+      }
+      /// <summary>
+      /// Single-sided unbounded streaming from server to client
+      /// The server repeatedly returns the client payload as-is
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Single-sided unbounded streaming from server to client
+      /// The server repeatedly returns the client payload as-is
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncServerStreamingCall(__Method_StreamingFromServer, null, options, request);
+      }
+      /// <summary>
+      /// Two-sided unbounded streaming between server to client
+      /// Both sides send the content of their own choice to the other
+      /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Two-sided unbounded streaming between server to client
+      /// Both sides send the content of their own choice to the other
+      /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingBothWays, null, options);
+      }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+      protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new BenchmarkServiceClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
+    {
+      return grpc::ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
+          .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall)
+          .AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient)
+          .AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer)
+          .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
+    }
+
+  }
+}
+#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs
new file mode 100644
index 0000000..b82cb52
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioService.cs
@@ -0,0 +1,39 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: src/proto/grpc/testing/report_qps_scenario_service.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  /// <summary>Holder for reflection information generated from src/proto/grpc/testing/report_qps_scenario_service.proto</summary>
+  public static partial class ReportQpsScenarioServiceReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for src/proto/grpc/testing/report_qps_scenario_service.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static ReportQpsScenarioServiceReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CjhzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3JlcG9ydF9xcHNfc2NlbmFyaW9f",
+            "c2VydmljZS5wcm90bxIMZ3JwYy50ZXN0aW5nGiRzcmMvcHJvdG8vZ3JwYy90",
+            "ZXN0aW5nL2NvbnRyb2wucHJvdG8yXgoYUmVwb3J0UXBzU2NlbmFyaW9TZXJ2",
+            "aWNlEkIKDlJlcG9ydFNjZW5hcmlvEhwuZ3JwYy50ZXN0aW5nLlNjZW5hcmlv",
+            "UmVzdWx0GhIuZ3JwYy50ZXN0aW5nLlZvaWRiBnByb3RvMw=="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.ControlReflection.Descriptor, },
+          new pbr::GeneratedClrTypeInfo(null, null));
+    }
+    #endregion
+
+  }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
new file mode 100644
index 0000000..c9c6f75
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
@@ -0,0 +1,148 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: src/proto/grpc/testing/report_qps_scenario_service.proto
+// </auto-generated>
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+  public static partial class ReportQpsScenarioService
+  {
+    static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
+
+    static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+
+    static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ReportScenario",
+        __Marshaller_ScenarioResult,
+        __Marshaller_Void);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.ReportQpsScenarioServiceReflection.Descriptor.Services[0]; }
+    }
+
+    /// <summary>Base class for server-side implementations of ReportQpsScenarioService</summary>
+    public abstract partial class ReportQpsScenarioServiceBase
+    {
+      /// <summary>
+      /// Report results of a QPS test benchmark scenario.
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for ReportQpsScenarioService</summary>
+    public partial class ReportQpsScenarioServiceClient : grpc::ClientBase<ReportQpsScenarioServiceClient>
+    {
+      /// <summary>Creates a new client for ReportQpsScenarioService</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public ReportQpsScenarioServiceClient(grpc::Channel channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for ReportQpsScenarioService that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public ReportQpsScenarioServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected ReportQpsScenarioServiceClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected ReportQpsScenarioServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      /// Report results of a QPS test benchmark scenario.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Report results of a QPS test benchmark scenario.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ReportScenario, null, options, request);
+      }
+      /// <summary>
+      /// Report results of a QPS test benchmark scenario.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Report results of a QPS test benchmark scenario.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ReportScenario, null, options, request);
+      }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+      protected override ReportQpsScenarioServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new ReportQpsScenarioServiceClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(ReportQpsScenarioServiceBase serviceImpl)
+    {
+      return grpc::ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
+    }
+
+  }
+}
+#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
deleted file mode 100644
index 4b76170..0000000
--- a/src/csharp/Grpc.IntegrationTesting/Services.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: src/proto/grpc/testing/services.proto
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Grpc.Testing {
-
-  /// <summary>Holder for reflection information generated from src/proto/grpc/testing/services.proto</summary>
-  public static partial class ServicesReflection {
-
-    #region Descriptor
-    /// <summary>File descriptor for src/proto/grpc/testing/services.proto</summary>
-    public static pbr::FileDescriptor Descriptor {
-      get { return descriptor; }
-    }
-    private static pbr::FileDescriptor descriptor;
-
-    static ServicesReflection() {
-      byte[] descriptorData = global::System.Convert.FromBase64String(
-          string.Concat(
-            "CiVzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3NlcnZpY2VzLnByb3RvEgxncnBj",
-            "LnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVzc2FnZXMucHJv",
-            "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bzKmAwoQ",
-            "QmVuY2htYXJrU2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3Rpbmcu",
-            "U2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJO",
-            "Cg1TdHJlYW1pbmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa",
-            "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABElIKE1N0cmVhbWlu",
-            "Z0Zyb21DbGllbnQSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdy",
-            "cGMudGVzdGluZy5TaW1wbGVSZXNwb25zZSgBElIKE1N0cmVhbWluZ0Zyb21T",
-            "ZXJ2ZXISGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVz",
-            "dGluZy5TaW1wbGVSZXNwb25zZTABElIKEVN0cmVhbWluZ0JvdGhXYXlzEhsu",
-            "Z3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2lt",
-            "cGxlUmVzcG9uc2UoATABMpcCCg1Xb3JrZXJTZXJ2aWNlEkUKCVJ1blNlcnZl",
-            "chIYLmdycGMudGVzdGluZy5TZXJ2ZXJBcmdzGhouZ3JwYy50ZXN0aW5nLlNl",
-            "cnZlclN0YXR1cygBMAESRQoJUnVuQ2xpZW50EhguZ3JwYy50ZXN0aW5nLkNs",
-            "aWVudEFyZ3MaGi5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHVzKAEwARJCCglD",
-            "b3JlQ291bnQSGS5ncnBjLnRlc3RpbmcuQ29yZVJlcXVlc3QaGi5ncnBjLnRl",
-            "c3RpbmcuQ29yZVJlc3BvbnNlEjQKClF1aXRXb3JrZXISEi5ncnBjLnRlc3Rp",
-            "bmcuVm9pZBoSLmdycGMudGVzdGluZy5Wb2lkMl4KGFJlcG9ydFFwc1NjZW5h",
-            "cmlvU2VydmljZRJCCg5SZXBvcnRTY2VuYXJpbxIcLmdycGMudGVzdGluZy5T",
-            "Y2VuYXJpb1Jlc3VsdBoSLmdycGMudGVzdGluZy5Wb2lkYgZwcm90bzM="));
-      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
-          new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, },
-          new pbr::GeneratedClrTypeInfo(null, null));
-    }
-    #endregion
-
-  }
-}
-
-#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
deleted file mode 100644
index 46b328a..0000000
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ /dev/null
@@ -1,745 +0,0 @@
-// <auto-generated>
-//     Generated by the protocol buffer compiler.  DO NOT EDIT!
-//     source: src/proto/grpc/testing/services.proto
-// </auto-generated>
-// Original file comments:
-// Copyright 2015 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// An integration test service that covers all the method signature permutations
-// of unary/streaming requests/responses.
-#pragma warning disable 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Grpc.Testing {
-  public static partial class BenchmarkService
-  {
-    static readonly string __ServiceName = "grpc.testing.BenchmarkService";
-
-    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
-
-    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        grpc::MethodType.Unary,
-        __ServiceName,
-        "UnaryCall",
-        __Marshaller_SimpleRequest,
-        __Marshaller_SimpleResponse);
-
-    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        grpc::MethodType.DuplexStreaming,
-        __ServiceName,
-        "StreamingCall",
-        __Marshaller_SimpleRequest,
-        __Marshaller_SimpleResponse);
-
-    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        grpc::MethodType.ClientStreaming,
-        __ServiceName,
-        "StreamingFromClient",
-        __Marshaller_SimpleRequest,
-        __Marshaller_SimpleResponse);
-
-    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        grpc::MethodType.ServerStreaming,
-        __ServiceName,
-        "StreamingFromServer",
-        __Marshaller_SimpleRequest,
-        __Marshaller_SimpleResponse);
-
-    static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
-        grpc::MethodType.DuplexStreaming,
-        __ServiceName,
-        "StreamingBothWays",
-        __Marshaller_SimpleRequest,
-        __Marshaller_SimpleResponse);
-
-    /// <summary>Service descriptor</summary>
-    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
-    {
-      get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[0]; }
-    }
-
-    /// <summary>Base class for server-side implementations of BenchmarkService</summary>
-    public abstract partial class BenchmarkServiceBase
-    {
-      /// <summary>
-      /// One request followed by one response.
-      /// The server returns the client payload as-is.
-      /// </summary>
-      /// <param name="request">The request received from the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Repeated sequence of one request followed by one response.
-      /// Should be called streaming ping-pong
-      /// The server returns the client payload as-is on each response
-      /// </summary>
-      /// <param name="requestStream">Used for reading requests from the client.</param>
-      /// <param name="responseStream">Used for sending responses back to the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task StreamingCall(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Single-sided unbounded streaming from client to server
-      /// The server returns the client payload as-is once the client does WritesDone
-      /// </summary>
-      /// <param name="requestStream">Used for reading requests from the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Single-sided unbounded streaming from server to client
-      /// The server repeatedly returns the client payload as-is
-      /// </summary>
-      /// <param name="request">The request received from the client.</param>
-      /// <param name="responseStream">Used for sending responses back to the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Two-sided unbounded streaming between server to client
-      /// Both sides send the content of their own choice to the other
-      /// </summary>
-      /// <param name="requestStream">Used for reading requests from the client.</param>
-      /// <param name="responseStream">Used for sending responses back to the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task StreamingBothWays(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-    }
-
-    /// <summary>Client for BenchmarkService</summary>
-    public partial class BenchmarkServiceClient : grpc::ClientBase<BenchmarkServiceClient>
-    {
-      /// <summary>Creates a new client for BenchmarkService</summary>
-      /// <param name="channel">The channel to use to make remote calls.</param>
-      public BenchmarkServiceClient(grpc::Channel channel) : base(channel)
-      {
-      }
-      /// <summary>Creates a new client for BenchmarkService that uses a custom <c>CallInvoker</c>.</summary>
-      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public BenchmarkServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
-      {
-      }
-      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
-      protected BenchmarkServiceClient() : base()
-      {
-      }
-      /// <summary>Protected constructor to allow creation of configured clients.</summary>
-      /// <param name="configuration">The client configuration.</param>
-      protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
-      {
-      }
-
-      /// <summary>
-      /// One request followed by one response.
-      /// The server returns the client payload as-is.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// One request followed by one response.
-      /// The server returns the client payload as-is.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
-      {
-        return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
-      }
-      /// <summary>
-      /// One request followed by one response.
-      /// The server returns the client payload as-is.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// One request followed by one response.
-      /// The server returns the client payload as-is.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
-      }
-      /// <summary>
-      /// Repeated sequence of one request followed by one response.
-      /// Should be called streaming ping-pong
-      /// The server returns the client payload as-is on each response
-      /// </summary>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Repeated sequence of one request followed by one response.
-      /// Should be called streaming ping-pong
-      /// The server returns the client payload as-is on each response
-      /// </summary>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
-      }
-      /// <summary>
-      /// Single-sided unbounded streaming from client to server
-      /// The server returns the client payload as-is once the client does WritesDone
-      /// </summary>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Single-sided unbounded streaming from client to server
-      /// The server returns the client payload as-is once the client does WritesDone
-      /// </summary>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncClientStreamingCall(__Method_StreamingFromClient, null, options);
-      }
-      /// <summary>
-      /// Single-sided unbounded streaming from server to client
-      /// The server repeatedly returns the client payload as-is
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Single-sided unbounded streaming from server to client
-      /// The server repeatedly returns the client payload as-is
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncServerStreamingCall(__Method_StreamingFromServer, null, options, request);
-      }
-      /// <summary>
-      /// Two-sided unbounded streaming between server to client
-      /// Both sides send the content of their own choice to the other
-      /// </summary>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Two-sided unbounded streaming between server to client
-      /// Both sides send the content of their own choice to the other
-      /// </summary>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingBothWays, null, options);
-      }
-      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
-      protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
-      {
-        return new BenchmarkServiceClient(configuration);
-      }
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static grpc::ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
-    {
-      return grpc::ServerServiceDefinition.CreateBuilder()
-          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
-          .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall)
-          .AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient)
-          .AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer)
-          .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
-    }
-
-  }
-  public static partial class WorkerService
-  {
-    static readonly string __ServiceName = "grpc.testing.WorkerService";
-
-    static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
-
-    static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
-        grpc::MethodType.DuplexStreaming,
-        __ServiceName,
-        "RunServer",
-        __Marshaller_ServerArgs,
-        __Marshaller_ServerStatus);
-
-    static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
-        grpc::MethodType.DuplexStreaming,
-        __ServiceName,
-        "RunClient",
-        __Marshaller_ClientArgs,
-        __Marshaller_ClientStatus);
-
-    static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
-        grpc::MethodType.Unary,
-        __ServiceName,
-        "CoreCount",
-        __Marshaller_CoreRequest,
-        __Marshaller_CoreResponse);
-
-    static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
-        grpc::MethodType.Unary,
-        __ServiceName,
-        "QuitWorker",
-        __Marshaller_Void,
-        __Marshaller_Void);
-
-    /// <summary>Service descriptor</summary>
-    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
-    {
-      get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[1]; }
-    }
-
-    /// <summary>Base class for server-side implementations of WorkerService</summary>
-    public abstract partial class WorkerServiceBase
-    {
-      /// <summary>
-      /// Start server with specified workload.
-      /// First request sent specifies the ServerConfig followed by ServerStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test server
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="requestStream">Used for reading requests from the client.</param>
-      /// <param name="responseStream">Used for sending responses back to the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task RunServer(grpc::IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Start client with specified workload.
-      /// First request sent specifies the ClientConfig followed by ClientStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test client
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="requestStream">Used for reading requests from the client.</param>
-      /// <param name="responseStream">Used for sending responses back to the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>A task indicating completion of the handler.</returns>
-      public virtual global::System.Threading.Tasks.Task RunClient(grpc::IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Just return the core count - unary call
-      /// </summary>
-      /// <param name="request">The request received from the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-      /// <summary>
-      /// Quit this worker
-      /// </summary>
-      /// <param name="request">The request received from the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-    }
-
-    /// <summary>Client for WorkerService</summary>
-    public partial class WorkerServiceClient : grpc::ClientBase<WorkerServiceClient>
-    {
-      /// <summary>Creates a new client for WorkerService</summary>
-      /// <param name="channel">The channel to use to make remote calls.</param>
-      public WorkerServiceClient(grpc::Channel channel) : base(channel)
-      {
-      }
-      /// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
-      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public WorkerServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
-      {
-      }
-      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
-      protected WorkerServiceClient() : base()
-      {
-      }
-      /// <summary>Protected constructor to allow creation of configured clients.</summary>
-      /// <param name="configuration">The client configuration.</param>
-      protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
-      {
-      }
-
-      /// <summary>
-      /// Start server with specified workload.
-      /// First request sent specifies the ServerConfig followed by ServerStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test server
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Start server with specified workload.
-      /// First request sent specifies the ServerConfig followed by ServerStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test server
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
-      }
-      /// <summary>
-      /// Start client with specified workload.
-      /// First request sent specifies the ClientConfig followed by ClientStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test client
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Start client with specified workload.
-      /// First request sent specifies the ClientConfig followed by ClientStatus
-      /// response. After that, a "Mark" can be sent anytime to request the latest
-      /// stats. Closing the stream will initiate shutdown of the test client
-      /// and once the shutdown has finished, the OK status is sent to terminate
-      /// this RPC.
-      /// </summary>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
-      }
-      /// <summary>
-      /// Just return the core count - unary call
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Just return the core count - unary call
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
-      {
-        return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
-      }
-      /// <summary>
-      /// Just return the core count - unary call
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Just return the core count - unary call
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
-      }
-      /// <summary>
-      /// Quit this worker
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Quit this worker
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::CallOptions options)
-      {
-        return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
-      }
-      /// <summary>
-      /// Quit this worker
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Quit this worker
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
-      }
-      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
-      protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
-      {
-        return new WorkerServiceClient(configuration);
-      }
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static grpc::ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
-    {
-      return grpc::ServerServiceDefinition.CreateBuilder()
-          .AddMethod(__Method_RunServer, serviceImpl.RunServer)
-          .AddMethod(__Method_RunClient, serviceImpl.RunClient)
-          .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
-          .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
-    }
-
-  }
-  public static partial class ReportQpsScenarioService
-  {
-    static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
-
-    static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
-    static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
-
-    static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
-        grpc::MethodType.Unary,
-        __ServiceName,
-        "ReportScenario",
-        __Marshaller_ScenarioResult,
-        __Marshaller_Void);
-
-    /// <summary>Service descriptor</summary>
-    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
-    {
-      get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[2]; }
-    }
-
-    /// <summary>Base class for server-side implementations of ReportQpsScenarioService</summary>
-    public abstract partial class ReportQpsScenarioServiceBase
-    {
-      /// <summary>
-      /// Report results of a QPS test benchmark scenario.
-      /// </summary>
-      /// <param name="request">The request received from the client.</param>
-      /// <param name="context">The context of the server-side call handler being invoked.</param>
-      /// <returns>The response to send back to the client (wrapped by a task).</returns>
-      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::ServerCallContext context)
-      {
-        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
-      }
-
-    }
-
-    /// <summary>Client for ReportQpsScenarioService</summary>
-    public partial class ReportQpsScenarioServiceClient : grpc::ClientBase<ReportQpsScenarioServiceClient>
-    {
-      /// <summary>Creates a new client for ReportQpsScenarioService</summary>
-      /// <param name="channel">The channel to use to make remote calls.</param>
-      public ReportQpsScenarioServiceClient(grpc::Channel channel) : base(channel)
-      {
-      }
-      /// <summary>Creates a new client for ReportQpsScenarioService that uses a custom <c>CallInvoker</c>.</summary>
-      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
-      public ReportQpsScenarioServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
-      {
-      }
-      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
-      protected ReportQpsScenarioServiceClient() : base()
-      {
-      }
-      /// <summary>Protected constructor to allow creation of configured clients.</summary>
-      /// <param name="configuration">The client configuration.</param>
-      protected ReportQpsScenarioServiceClient(ClientBaseConfiguration configuration) : base(configuration)
-      {
-      }
-
-      /// <summary>
-      /// Report results of a QPS test benchmark scenario.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Report results of a QPS test benchmark scenario.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The response received from the server.</returns>
-      public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
-      {
-        return CallInvoker.BlockingUnaryCall(__Method_ReportScenario, null, options, request);
-      }
-      /// <summary>
-      /// Report results of a QPS test benchmark scenario.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
-      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
-      /// <param name="cancellationToken">An optional token for canceling the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
-      {
-        return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
-      }
-      /// <summary>
-      /// Report results of a QPS test benchmark scenario.
-      /// </summary>
-      /// <param name="request">The request to send to the server.</param>
-      /// <param name="options">The options for the call.</param>
-      /// <returns>The call object.</returns>
-      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
-      {
-        return CallInvoker.AsyncUnaryCall(__Method_ReportScenario, null, options, request);
-      }
-      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
-      protected override ReportQpsScenarioServiceClient NewInstance(ClientBaseConfiguration configuration)
-      {
-        return new ReportQpsScenarioServiceClient(configuration);
-      }
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-    public static grpc::ServerServiceDefinition BindService(ReportQpsScenarioServiceBase serviceImpl)
-    {
-      return grpc::ServerServiceDefinition.CreateBuilder()
-          .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
-    }
-
-  }
-}
-#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerService.cs b/src/csharp/Grpc.IntegrationTesting/WorkerService.cs
new file mode 100644
index 0000000..7c82954
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerService.cs
@@ -0,0 +1,43 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: src/proto/grpc/testing/worker_service.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  /// <summary>Holder for reflection information generated from src/proto/grpc/testing/worker_service.proto</summary>
+  public static partial class WorkerServiceReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for src/proto/grpc/testing/worker_service.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static WorkerServiceReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CitzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3dvcmtlcl9zZXJ2aWNlLnByb3Rv",
+            "EgxncnBjLnRlc3RpbmcaJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJv",
+            "bC5wcm90bzKXAgoNV29ya2VyU2VydmljZRJFCglSdW5TZXJ2ZXISGC5ncnBj",
+            "LnRlc3RpbmcuU2VydmVyQXJncxoaLmdycGMudGVzdGluZy5TZXJ2ZXJTdGF0",
+            "dXMoATABEkUKCVJ1bkNsaWVudBIYLmdycGMudGVzdGluZy5DbGllbnRBcmdz",
+            "GhouZ3JwYy50ZXN0aW5nLkNsaWVudFN0YXR1cygBMAESQgoJQ29yZUNvdW50",
+            "EhkuZ3JwYy50ZXN0aW5nLkNvcmVSZXF1ZXN0GhouZ3JwYy50ZXN0aW5nLkNv",
+            "cmVSZXNwb25zZRI0CgpRdWl0V29ya2VyEhIuZ3JwYy50ZXN0aW5nLlZvaWQa",
+            "Ei5ncnBjLnRlc3RpbmcuVm9pZGIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.ControlReflection.Descriptor, },
+          new pbr::GeneratedClrTypeInfo(null, null));
+    }
+    #endregion
+
+  }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
new file mode 100644
index 0000000..ede3ace
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
@@ -0,0 +1,326 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: src/proto/grpc/testing/worker_service.proto
+// </auto-generated>
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Grpc.Testing {
+  public static partial class WorkerService
+  {
+    static readonly string __ServiceName = "grpc.testing.WorkerService";
+
+    static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+
+    static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
+        grpc::MethodType.DuplexStreaming,
+        __ServiceName,
+        "RunServer",
+        __Marshaller_ServerArgs,
+        __Marshaller_ServerStatus);
+
+    static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
+        grpc::MethodType.DuplexStreaming,
+        __ServiceName,
+        "RunClient",
+        __Marshaller_ClientArgs,
+        __Marshaller_ClientStatus);
+
+    static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "CoreCount",
+        __Marshaller_CoreRequest,
+        __Marshaller_CoreResponse);
+
+    static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "QuitWorker",
+        __Marshaller_Void,
+        __Marshaller_Void);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.WorkerServiceReflection.Descriptor.Services[0]; }
+    }
+
+    /// <summary>Base class for server-side implementations of WorkerService</summary>
+    public abstract partial class WorkerServiceBase
+    {
+      /// <summary>
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task RunServer(grpc::IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
+      public virtual global::System.Threading.Tasks.Task RunClient(grpc::IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Just return the core count - unary call
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Quit this worker
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for WorkerService</summary>
+    public partial class WorkerServiceClient : grpc::ClientBase<WorkerServiceClient>
+    {
+      /// <summary>Creates a new client for WorkerService</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public WorkerServiceClient(grpc::Channel channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for WorkerService that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public WorkerServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected WorkerServiceClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
+      }
+      /// <summary>
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
+      /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
+      }
+      /// <summary>
+      /// Just return the core count - unary call
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Just return the core count - unary call
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
+      }
+      /// <summary>
+      /// Just return the core count - unary call
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Just return the core count - unary call
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
+      }
+      /// <summary>
+      /// Quit this worker
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Quit this worker
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
+      }
+      /// <summary>
+      /// Quit this worker
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Quit this worker
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
+      }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+      protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new WorkerServiceClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
+    {
+      return grpc::ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_RunServer, serviceImpl.RunServer)
+          .AddMethod(__Method_RunClient, serviceImpl.RunClient)
+          .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
+          .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
+    }
+
+  }
+}
+#endregion
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 299dc3f..1a38f86 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -42,4 +42,4 @@
 # don't match the package names. Setting -I to the correct value src/proto
 # breaks the code generation.
 $PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
-    -I . src/proto/grpc/testing/{control,echo_messages,empty,messages,metrics,payloads,services,stats,test}.proto
+    -I . src/proto/grpc/testing/{control,echo_messages,empty,messages,metrics,payloads,benchmark_service,report_qps_scenario_service,worker_service,stats,test}.proto
diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
index 6247d0b..0113d9c 100644
--- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj
@@ -168,13 +168,16 @@
 			files = (
 			);
 			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
 			);
 			name = "[CP] Check Pods Manifest.lock";
 			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-SwiftSample-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
 		A1738A987353B0BF2C64F0F7 /* [CP] Embed Pods Frameworks */ = {
@@ -183,9 +186,26 @@
 			files = (
 			);
 			inputPaths = (
+				"${SRCROOT}/Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/BoringSSL/openssl.framework",
+				"${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework",
+				"${BUILT_PRODUCTS_DIR}/RemoteTest/RemoteTest.framework",
+				"${BUILT_PRODUCTS_DIR}/gRPC/GRPCClient.framework",
+				"${BUILT_PRODUCTS_DIR}/gRPC-Core/grpc.framework",
+				"${BUILT_PRODUCTS_DIR}/gRPC-ProtoRPC/ProtoRPC.framework",
+				"${BUILT_PRODUCTS_DIR}/gRPC-RxLibrary/RxLibrary.framework",
+				"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RemoteTest.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPCClient.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpc.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ProtoRPC.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxLibrary.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
@@ -329,7 +349,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "";
-				SWIFT_VERSION = 2.3;
+				SWIFT_VERSION = 4.0;
 				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = Debug;
@@ -344,7 +364,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "";
-				SWIFT_VERSION = 2.3;
+				SWIFT_VERSION = 4.0;
 				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = Release;
diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift
index 5931914..0ba6e21 100644
--- a/src/objective-c/examples/SwiftSample/ViewController.swift
+++ b/src/objective-c/examples/SwiftSample/ViewController.swift
@@ -36,7 +36,7 @@
     // Example gRPC call using a generated proto client library:
 
     let service = RMTTestService(host: RemoteHost)
-    service.unaryCallWithRequest(request) { response, error in
+    service.unaryCall(with: request) { response, error in
       if let response = response {
         NSLog("1. Finished successfully with response:\n\(response)")
       } else {
@@ -48,7 +48,7 @@
     // Same but manipulating headers:
 
     var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block)
-    RPC = service.RPCToUnaryCallWithRequest(request) { response, error in
+    RPC = service.rpcToUnaryCall(with: request) { response, error in
       if let response = response {
         NSLog("2. Finished successfully with response:\n\(response)")
       } else {
@@ -59,23 +59,23 @@
     }
 
     // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released.
-    RPC.requestHeaders.setObject("My value", forKey: "My-Header")
+    RPC.requestHeaders["My-Header"] = "My value"
 
     RPC.start()
 
 
     // Same example call using the generic gRPC client library:
 
-    let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")
+    let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")!
 
     let requestsWriter = GRXWriter(value: request.data())
 
-    let call = GRPCCall(host: RemoteHost, path: method.HTTPPath, requestsWriter: requestsWriter)
+    let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)!
 
-    call.requestHeaders.setObject("My value", forKey: "My-Header")
+    call.requestHeaders["My-Header"] = "My value"
 
-    call.startWithWriteable(GRXWriteable { response, error in
-      if let response = response as? NSData {
+    call.start(with: GRXWriteable { response, error in
+      if let response = response as? Data {
         NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))")
       } else {
         NSLog("3. Finished with error: \(error!)")
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index af1a34a..b6e3897 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -26,8 +26,8 @@
     pod 'gRPC',           :path => GRPC_LOCAL_SRC
     pod 'gRPC-Core',      :path => GRPC_LOCAL_SRC
     pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC
-    pod 'gRPC-ProtoRPC',  :path => GRPC_LOCAL_SRC
-    pod 'RemoteTest', :path => "RemoteTestClient"
+    pod 'gRPC-ProtoRPC',  :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
+    pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true
 
     if target_name == 'InteropTestsRemoteWithCronet'
       pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php
new file mode 100644
index 0000000..906f6a2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/BenchmarkService.php
@@ -0,0 +1,41 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/benchmark_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class BenchmarkService
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0aef030a2e7372632f70726f746f2f677270632f74657374696e672f6265" .
+            "6e63686d61726b5f736572766963652e70726f746f120c677270632e7465" .
+            "7374696e6732a6030a1042656e63686d61726b5365727669636512460a09" .
+            "556e61727943616c6c121b2e677270632e74657374696e672e53696d706c" .
+            "65526571756573741a1c2e677270632e74657374696e672e53696d706c65" .
+            "526573706f6e7365124e0a0d53747265616d696e6743616c6c121b2e6772" .
+            "70632e74657374696e672e53696d706c65526571756573741a1c2e677270" .
+            "632e74657374696e672e53696d706c65526573706f6e7365280130011252" .
+            "0a1353747265616d696e6746726f6d436c69656e74121b2e677270632e74" .
+            "657374696e672e53696d706c65526571756573741a1c2e677270632e7465" .
+            "7374696e672e53696d706c65526573706f6e7365280112520a1353747265" .
+            "616d696e6746726f6d536572766572121b2e677270632e74657374696e67" .
+            "2e53696d706c65526571756573741a1c2e677270632e74657374696e672e" .
+            "53696d706c65526573706f6e7365300112520a1153747265616d696e6742" .
+            "6f746857617973121b2e677270632e74657374696e672e53696d706c6552" .
+            "6571756573741a1c2e677270632e74657374696e672e53696d706c655265" .
+            "73706f6e736528013001620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php
new file mode 100644
index 0000000..2c4fe92
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/CompilerTest.php
@@ -0,0 +1,37 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class CompilerTest
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0aa1030a2a7372632f70726f746f2f677270632f74657374696e672f636f" .
+            "6d70696c65725f746573742e70726f746f120c677270632e74657374696e" .
+            "6722090a0752657175657374220a0a08526573706f6e736532fe010a0853" .
+            "6572766963654112390a084d6574686f64413112152e677270632e746573" .
+            "74696e672e526571756573741a162e677270632e74657374696e672e5265" .
+            "73706f6e7365123b0a084d6574686f64413212152e677270632e74657374" .
+            "696e672e526571756573741a162e677270632e74657374696e672e526573" .
+            "706f6e73652801123b0a084d6574686f64413312152e677270632e746573" .
+            "74696e672e526571756573741a162e677270632e74657374696e672e5265" .
+            "73706f6e73653001123d0a084d6574686f64413412152e677270632e7465" .
+            "7374696e672e526571756573741a162e677270632e74657374696e672e52" .
+            "6573706f6e73652801300132450a08536572766963654212390a084d6574" .
+            "686f64423112152e677270632e74657374696e672e526571756573741a16" .
+            "2e677270632e74657374696e672e526573706f6e7365620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
index 9b3a752..2319bcd 100644
--- a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
@@ -17,7 +17,7 @@
         \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
         \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
         $pool->internalAddGeneratedFile(hex2bin(
-            "0aa21a0a247372632f70726f746f2f677270632f74657374696e672f636f" .
+            "0abc1a0a247372632f70726f746f2f677270632f74657374696e672f636f" .
             "6e74726f6c2e70726f746f120c677270632e74657374696e671a22737263" .
             "2f70726f746f2f677270632f74657374696e672f73746174732e70726f74" .
             "6f22250a0d506f6973736f6e506172616d7312140a0c6f6666657265645f" .
@@ -31,7 +31,7 @@
             "6f7665727269646518022001280912110a09637265645f74797065180320" .
             "012809224d0a0a4368616e6e656c417267120c0a046e616d651801200128" .
             "0912130a097374725f76616c7565180220012809480012130a09696e745f" .
-            "76616c7565180320012805480042070a0576616c756522d5040a0c436c69" .
+            "76616c7565180320012805480042070a0576616c756522ef040a0c436c69" .
             "656e74436f6e66696712160a0e7365727665725f74617267657473180120" .
             "032809122d0a0b636c69656e745f7479706518022001280e32182e677270" .
             "632e74657374696e672e436c69656e745479706512350a0f736563757269" .
@@ -51,85 +51,86 @@
             "745f617069180f20012809122e0a0c6368616e6e656c5f61726773181020" .
             "03280b32182e677270632e74657374696e672e4368616e6e656c41726712" .
             "160a0e746872656164735f7065725f6371181120012805121b0a136d6573" .
-            "73616765735f7065725f73747265616d18122001280522380a0c436c6965" .
-            "6e7453746174757312280a05737461747318012001280b32192e67727063" .
-            "2e74657374696e672e436c69656e74537461747322150a044d61726b120d" .
-            "0a05726573657418012001280822680a0a436c69656e7441726773122b0a" .
-            "05736574757018012001280b321a2e677270632e74657374696e672e436c" .
-            "69656e74436f6e666967480012220a046d61726b18022001280b32122e67" .
-            "7270632e74657374696e672e4d61726b480042090a076172677479706522" .
-            "fd020a0c536572766572436f6e666967122d0a0b7365727665725f747970" .
-            "6518012001280e32182e677270632e74657374696e672e53657276657254" .
-            "79706512350a0f73656375726974795f706172616d7318022001280b321c" .
-            "2e677270632e74657374696e672e5365637572697479506172616d73120c" .
-            "0a04706f7274180420012805121c0a146173796e635f7365727665725f74" .
-            "68726561647318072001280512120a0a636f72655f6c696d697418082001" .
-            "280512330a0e7061796c6f61645f636f6e66696718092001280b321b2e67" .
-            "7270632e74657374696e672e5061796c6f6164436f6e66696712110a0963" .
-            "6f72655f6c697374180a2003280512180a106f746865725f736572766572" .
-            "5f617069180b2001280912160a0e746872656164735f7065725f6371180c" .
-            "20012805121c0a137265736f757263655f71756f74615f73697a6518e907" .
-            "20012805122f0a0c6368616e6e656c5f6172677318ea072003280b32182e" .
-            "677270632e74657374696e672e4368616e6e656c41726722680a0a536572" .
-            "76657241726773122b0a05736574757018012001280b321a2e677270632e" .
-            "74657374696e672e536572766572436f6e666967480012220a046d61726b" .
-            "18022001280b32122e677270632e74657374696e672e4d61726b48004209" .
-            "0a076172677479706522550a0c53657276657253746174757312280a0573" .
-            "7461747318012001280b32192e677270632e74657374696e672e53657276" .
-            "65725374617473120c0a04706f7274180220012805120d0a05636f726573" .
-            "180320012805220d0a0b436f726552657175657374221d0a0c436f726552" .
-            "6573706f6e7365120d0a05636f72657318012001280522060a04566f6964" .
-            "22fd010a085363656e6172696f120c0a046e616d6518012001280912310a" .
-            "0d636c69656e745f636f6e66696718022001280b321a2e677270632e7465" .
-            "7374696e672e436c69656e74436f6e66696712130a0b6e756d5f636c6965" .
-            "6e747318032001280512310a0d7365727665725f636f6e66696718042001" .
-            "280b321a2e677270632e74657374696e672e536572766572436f6e666967" .
-            "12130a0b6e756d5f7365727665727318052001280512160a0e7761726d75" .
-            "705f7365636f6e647318062001280512190a1162656e63686d61726b5f73" .
-            "65636f6e647318072001280512200a18737061776e5f6c6f63616c5f776f" .
-            "726b65725f636f756e7418082001280522360a095363656e6172696f7312" .
-            "290a097363656e6172696f7318012003280b32162e677270632e74657374" .
-            "696e672e5363656e6172696f2284040a155363656e6172696f526573756c" .
-            "7453756d6d617279120b0a03717073180120012801121b0a137170735f70" .
-            "65725f7365727665725f636f7265180220012801121a0a12736572766572" .
-            "5f73797374656d5f74696d6518032001280112180a107365727665725f75" .
-            "7365725f74696d65180420012801121a0a12636c69656e745f7379737465" .
-            "6d5f74696d6518052001280112180a10636c69656e745f757365725f7469" .
-            "6d6518062001280112120a0a6c6174656e63795f35301807200128011212" .
-            "0a0a6c6174656e63795f393018082001280112120a0a6c6174656e63795f" .
-            "393518092001280112120a0a6c6174656e63795f3939180a200128011213" .
-            "0a0b6c6174656e63795f393939180b2001280112180a107365727665725f" .
-            "6370755f7573616765180c2001280112260a1e7375636365737366756c5f" .
-            "72657175657374735f7065725f7365636f6e64180d2001280112220a1a66" .
-            "61696c65645f72657175657374735f7065725f7365636f6e64180e200128" .
-            "0112200a18636c69656e745f706f6c6c735f7065725f7265717565737418" .
-            "0f2001280112200a187365727665725f706f6c6c735f7065725f72657175" .
-            "65737418102001280112220a1a7365727665725f717565726965735f7065" .
-            "725f6370755f73656318112001280112220a1a636c69656e745f71756572" .
-            "6965735f7065725f6370755f7365631812200128012283030a0e5363656e" .
-            "6172696f526573756c7412280a087363656e6172696f18012001280b3216" .
-            "2e677270632e74657374696e672e5363656e6172696f122e0a096c617465" .
-            "6e6369657318022001280b321b2e677270632e74657374696e672e486973" .
-            "746f6772616d44617461122f0a0c636c69656e745f737461747318032003" .
-            "280b32192e677270632e74657374696e672e436c69656e74537461747312" .
-            "2f0a0c7365727665725f737461747318042003280b32192e677270632e74" .
-            "657374696e672e536572766572537461747312140a0c7365727665725f63" .
-            "6f72657318052003280512340a0773756d6d61727918062001280b32232e" .
-            "677270632e74657374696e672e5363656e6172696f526573756c7453756d" .
-            "6d61727912160a0e636c69656e745f737563636573731807200328081216" .
-            "0a0e7365727665725f7375636365737318082003280812390a0f72657175" .
-            "6573745f726573756c747318092003280b32202e677270632e7465737469" .
-            "6e672e52657175657374526573756c74436f756e742a410a0a436c69656e" .
-            "7454797065120f0a0b53594e435f434c49454e54100012100a0c4153594e" .
-            "435f434c49454e54100112100a0c4f544845525f434c49454e5410022a5b" .
-            "0a0a53657276657254797065120f0a0b53594e435f534552564552100012" .
-            "100a0c4153594e435f534552564552100112180a144153594e435f47454e" .
-            "455249435f534552564552100212100a0c4f544845525f53455256455210" .
-            "032a720a075270635479706512090a05554e4152591000120d0a09535452" .
-            "45414d494e47100112190a1553545245414d494e475f46524f4d5f434c49" .
-            "454e54100212190a1553545245414d494e475f46524f4d5f534552564552" .
-            "100312170a1353545245414d494e475f424f54485f574159531004620670" .
-            "726f746f33"
+            "73616765735f7065725f73747265616d18122001280512180a107573655f" .
+            "636f616c657363655f61706918132001280822380a0c436c69656e745374" .
+            "6174757312280a05737461747318012001280b32192e677270632e746573" .
+            "74696e672e436c69656e74537461747322150a044d61726b120d0a057265" .
+            "73657418012001280822680a0a436c69656e7441726773122b0a05736574" .
+            "757018012001280b321a2e677270632e74657374696e672e436c69656e74" .
+            "436f6e666967480012220a046d61726b18022001280b32122e677270632e" .
+            "74657374696e672e4d61726b480042090a076172677479706522fd020a0c" .
+            "536572766572436f6e666967122d0a0b7365727665725f74797065180120" .
+            "01280e32182e677270632e74657374696e672e5365727665725479706512" .
+            "350a0f73656375726974795f706172616d7318022001280b321c2e677270" .
+            "632e74657374696e672e5365637572697479506172616d73120c0a04706f" .
+            "7274180420012805121c0a146173796e635f7365727665725f7468726561" .
+            "647318072001280512120a0a636f72655f6c696d69741808200128051233" .
+            "0a0e7061796c6f61645f636f6e66696718092001280b321b2e677270632e" .
+            "74657374696e672e5061796c6f6164436f6e66696712110a09636f72655f" .
+            "6c697374180a2003280512180a106f746865725f7365727665725f617069" .
+            "180b2001280912160a0e746872656164735f7065725f6371180c20012805" .
+            "121c0a137265736f757263655f71756f74615f73697a6518e90720012805" .
+            "122f0a0c6368616e6e656c5f6172677318ea072003280b32182e67727063" .
+            "2e74657374696e672e4368616e6e656c41726722680a0a53657276657241" .
+            "726773122b0a05736574757018012001280b321a2e677270632e74657374" .
+            "696e672e536572766572436f6e666967480012220a046d61726b18022001" .
+            "280b32122e677270632e74657374696e672e4d61726b480042090a076172" .
+            "677479706522550a0c53657276657253746174757312280a057374617473" .
+            "18012001280b32192e677270632e74657374696e672e5365727665725374" .
+            "617473120c0a04706f7274180220012805120d0a05636f72657318032001" .
+            "2805220d0a0b436f726552657175657374221d0a0c436f7265526573706f" .
+            "6e7365120d0a05636f72657318012001280522060a04566f696422fd010a" .
+            "085363656e6172696f120c0a046e616d6518012001280912310a0d636c69" .
+            "656e745f636f6e66696718022001280b321a2e677270632e74657374696e" .
+            "672e436c69656e74436f6e66696712130a0b6e756d5f636c69656e747318" .
+            "032001280512310a0d7365727665725f636f6e66696718042001280b321a" .
+            "2e677270632e74657374696e672e536572766572436f6e66696712130a0b" .
+            "6e756d5f7365727665727318052001280512160a0e7761726d75705f7365" .
+            "636f6e647318062001280512190a1162656e63686d61726b5f7365636f6e" .
+            "647318072001280512200a18737061776e5f6c6f63616c5f776f726b6572" .
+            "5f636f756e7418082001280522360a095363656e6172696f7312290a0973" .
+            "63656e6172696f7318012003280b32162e677270632e74657374696e672e" .
+            "5363656e6172696f2284040a155363656e6172696f526573756c7453756d" .
+            "6d617279120b0a03717073180120012801121b0a137170735f7065725f73" .
+            "65727665725f636f7265180220012801121a0a127365727665725f737973" .
+            "74656d5f74696d6518032001280112180a107365727665725f757365725f" .
+            "74696d65180420012801121a0a12636c69656e745f73797374656d5f7469" .
+            "6d6518052001280112180a10636c69656e745f757365725f74696d651806" .
+            "2001280112120a0a6c6174656e63795f353018072001280112120a0a6c61" .
+            "74656e63795f393018082001280112120a0a6c6174656e63795f39351809" .
+            "2001280112120a0a6c6174656e63795f3939180a2001280112130a0b6c61" .
+            "74656e63795f393939180b2001280112180a107365727665725f6370755f" .
+            "7573616765180c2001280112260a1e7375636365737366756c5f72657175" .
+            "657374735f7065725f7365636f6e64180d2001280112220a1a6661696c65" .
+            "645f72657175657374735f7065725f7365636f6e64180e2001280112200a" .
+            "18636c69656e745f706f6c6c735f7065725f72657175657374180f200128" .
+            "0112200a187365727665725f706f6c6c735f7065725f7265717565737418" .
+            "102001280112220a1a7365727665725f717565726965735f7065725f6370" .
+            "755f73656318112001280112220a1a636c69656e745f717565726965735f" .
+            "7065725f6370755f7365631812200128012283030a0e5363656e6172696f" .
+            "526573756c7412280a087363656e6172696f18012001280b32162e677270" .
+            "632e74657374696e672e5363656e6172696f122e0a096c6174656e636965" .
+            "7318022001280b321b2e677270632e74657374696e672e486973746f6772" .
+            "616d44617461122f0a0c636c69656e745f737461747318032003280b3219" .
+            "2e677270632e74657374696e672e436c69656e745374617473122f0a0c73" .
+            "65727665725f737461747318042003280b32192e677270632e7465737469" .
+            "6e672e536572766572537461747312140a0c7365727665725f636f726573" .
+            "18052003280512340a0773756d6d61727918062001280b32232e67727063" .
+            "2e74657374696e672e5363656e6172696f526573756c7453756d6d617279" .
+            "12160a0e636c69656e745f7375636365737318072003280812160a0e7365" .
+            "727665725f7375636365737318082003280812390a0f726571756573745f" .
+            "726573756c747318092003280b32202e677270632e74657374696e672e52" .
+            "657175657374526573756c74436f756e742a410a0a436c69656e74547970" .
+            "65120f0a0b53594e435f434c49454e54100012100a0c4153594e435f434c" .
+            "49454e54100112100a0c4f544845525f434c49454e5410022a5b0a0a5365" .
+            "7276657254797065120f0a0b53594e435f534552564552100012100a0c41" .
+            "53594e435f534552564552100112180a144153594e435f47454e45524943" .
+            "5f534552564552100212100a0c4f544845525f53455256455210032a720a" .
+            "075270635479706512090a05554e4152591000120d0a0953545245414d49" .
+            "4e47100112190a1553545245414d494e475f46524f4d5f434c49454e5410" .
+            "0212190a1553545245414d494e475f46524f4d5f53455256455210031217" .
+            "0a1353545245414d494e475f424f54485f574159531004620670726f746f" .
+            "33"
         ));
 
         static::$is_initialized = true;
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php
new file mode 100644
index 0000000..77c5230
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Echo.php
@@ -0,0 +1,43 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Echo
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0aa6040a217372632f70726f746f2f677270632f74657374696e672f6563" .
+            "686f2e70726f746f120c677270632e74657374696e6732f6020a0f456368" .
+            "6f5465737453657276696365123d0a044563686f12192e677270632e7465" .
+            "7374696e672e4563686f526571756573741a1a2e677270632e7465737469" .
+            "6e672e4563686f526573706f6e736512480a0d5265717565737453747265" .
+            "616d12192e677270632e74657374696e672e4563686f526571756573741a" .
+            "1a2e677270632e74657374696e672e4563686f526573706f6e7365280112" .
+            "490a0e526573706f6e736553747265616d12192e677270632e7465737469" .
+            "6e672e4563686f526571756573741a1a2e677270632e74657374696e672e" .
+            "4563686f526573706f6e7365300112470a0a4269646953747265616d1219" .
+            "2e677270632e74657374696e672e4563686f526571756573741a1a2e6772" .
+            "70632e74657374696e672e4563686f526573706f6e73652801300112460a" .
+            "0d556e696d706c656d656e74656412192e677270632e74657374696e672e" .
+            "4563686f526571756573741a1a2e677270632e74657374696e672e456368" .
+            "6f526573706f6e736532620a18556e696d706c656d656e7465644563686f" .
+            "5365727669636512460a0d556e696d706c656d656e74656412192e677270" .
+            "632e74657374696e672e4563686f526571756573741a1a2e677270632e74" .
+            "657374696e672e4563686f526573706f6e7365320e0a0c4e6f5270635365" .
+            "7276696365620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php
new file mode 100644
index 0000000..4bac8a2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/EchoMessages.php
@@ -0,0 +1,54 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class EchoMessages
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a8f070a2a7372632f70726f746f2f677270632f74657374696e672f6563" .
+            "686f5f6d657373616765732e70726f746f120c677270632e74657374696e" .
+            "6722320a094465627567496e666f12150a0d737461636b5f656e74726965" .
+            "73180120032809120e0a0664657461696c18022001280922500a0b457272" .
+            "6f72537461747573120c0a04636f646518012001280512150a0d6572726f" .
+            "725f6d657373616765180220012809121c0a1462696e6172795f6572726f" .
+            "725f64657461696c7318032001280922e2030a0d52657175657374506172" .
+            "616d7312150a0d6563686f5f646561646c696e65180120012808121e0a16" .
+            "636c69656e745f63616e63656c5f61667465725f7573180220012805121e" .
+            "0a167365727665725f63616e63656c5f61667465725f7573180320012805" .
+            "12150a0d6563686f5f6d65746164617461180420012808121a0a12636865" .
+            "636b5f617574685f636f6e74657874180520012808121f0a17726573706f" .
+            "6e73655f6d6573736167655f6c656e67746818062001280512110a096563" .
+            "686f5f7065657218072001280812200a1865787065637465645f636c6965" .
+            "6e745f6964656e74697479180820012809121c0a14736b69705f63616e63" .
+            "656c6c65645f636865636b18092001280812280a2065787065637465645f" .
+            "7472616e73706f72745f73656375726974795f74797065180a2001280912" .
+            "2b0a0a64656275675f696e666f180b2001280b32172e677270632e746573" .
+            "74696e672e4465627567496e666f12120a0a7365727665725f646965180c" .
+            "20012808121c0a1462696e6172795f6572726f725f64657461696c73180d" .
+            "2001280912310a0e65787065637465645f6572726f72180e2001280b3219" .
+            "2e677270632e74657374696e672e4572726f7253746174757312170a0f73" .
+            "65727665725f736c6565705f7573180f20012805224a0a0b4563686f5265" .
+            "7175657374120f0a076d657373616765180120012809122a0a0570617261" .
+            "6d18022001280b321b2e677270632e74657374696e672e52657175657374" .
+            "506172616d7322460a0e526573706f6e7365506172616d7312180a107265" .
+            "71756573745f646561646c696e65180120012803120c0a04686f73741802" .
+            "20012809120c0a0470656572180320012809224c0a0c4563686f52657370" .
+            "6f6e7365120f0a076d657373616765180120012809122b0a05706172616d" .
+            "18022001280b321c2e677270632e74657374696e672e526573706f6e7365" .
+            "506172616d73620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php
new file mode 100644
index 0000000..7198f7d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/GPBEmpty.php
@@ -0,0 +1,26 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/empty.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class GPBEmpty
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a430a227372632f70726f746f2f677270632f74657374696e672f656d70" .
+            "74792e70726f746f120c677270632e74657374696e6722070a05456d7074" .
+            "79620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php
new file mode 100644
index 0000000..7ac739f
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Metrics.php
@@ -0,0 +1,36 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Metrics
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0afb020a247372632f70726f746f2f677270632f74657374696e672f6d65" .
+            "74726963732e70726f746f120c677270632e74657374696e67226c0a0d47" .
+            "61756765526573706f6e7365120c0a046e616d6518012001280912140a0a" .
+            "6c6f6e675f76616c7565180220012803480012160a0c646f75626c655f76" .
+            "616c7565180320012801480012160a0c737472696e675f76616c75651804" .
+            "20012809480042070a0576616c7565221c0a0c4761756765526571756573" .
+            "74120c0a046e616d65180120012809220e0a0c456d7074794d6573736167" .
+            "6532a0010a0e4d6574726963735365727669636512490a0c476574416c6c" .
+            "476175676573121a2e677270632e74657374696e672e456d7074794d6573" .
+            "736167651a1b2e677270632e74657374696e672e4761756765526573706f" .
+            "6e7365300112430a084765744761756765121a2e677270632e7465737469" .
+            "6e672e4761756765526571756573741a1b2e677270632e74657374696e67" .
+            "2e4761756765526573706f6e7365620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php
new file mode 100644
index 0000000..35a1fb4
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ReportQpsScenarioService.php
@@ -0,0 +1,30 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/report_qps_scenario_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class ReportQpsScenarioService
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0ab0010a387372632f70726f746f2f677270632f74657374696e672f7265" .
+            "706f72745f7170735f7363656e6172696f5f736572766963652e70726f74" .
+            "6f120c677270632e74657374696e67325e0a185265706f72745170735363" .
+            "656e6172696f5365727669636512420a0e5265706f72745363656e617269" .
+            "6f121c2e677270632e74657374696e672e5363656e6172696f526573756c" .
+            "741a122e677270632e74657374696e672e566f6964620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php
new file mode 100644
index 0000000..54628cf
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Test.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/test.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Test
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\GPBEmpty::initOnce();
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a91080a217372632f70726f746f2f677270632f74657374696e672f7465" .
+            "73742e70726f746f120c677270632e74657374696e671a257372632f7072" .
+            "6f746f2f677270632f74657374696e672f6d657373616765732e70726f74" .
+            "6f32cb050a0b546573745365727669636512350a09456d70747943616c6c" .
+            "12132e677270632e74657374696e672e456d7074791a132e677270632e74" .
+            "657374696e672e456d70747912460a09556e61727943616c6c121b2e6772" .
+            "70632e74657374696e672e53696d706c65526571756573741a1c2e677270" .
+            "632e74657374696e672e53696d706c65526573706f6e7365124f0a124361" .
+            "63686561626c65556e61727943616c6c121b2e677270632e74657374696e" .
+            "672e53696d706c65526571756573741a1c2e677270632e74657374696e67" .
+            "2e53696d706c65526573706f6e7365126c0a1353747265616d696e674f75" .
+            "7470757443616c6c12282e677270632e74657374696e672e53747265616d" .
+            "696e674f757470757443616c6c526571756573741a292e677270632e7465" .
+            "7374696e672e53747265616d696e674f757470757443616c6c526573706f" .
+            "6e7365300112690a1253747265616d696e67496e70757443616c6c12272e" .
+            "677270632e74657374696e672e53747265616d696e67496e70757443616c" .
+            "6c526571756573741a282e677270632e74657374696e672e53747265616d" .
+            "696e67496e70757443616c6c526573706f6e7365280112690a0e46756c6c" .
+            "4475706c657843616c6c12282e677270632e74657374696e672e53747265" .
+            "616d696e674f757470757443616c6c526571756573741a292e677270632e" .
+            "74657374696e672e53747265616d696e674f757470757443616c6c526573" .
+            "706f6e73652801300112690a0e48616c664475706c657843616c6c12282e" .
+            "677270632e74657374696e672e53747265616d696e674f75747075744361" .
+            "6c6c526571756573741a292e677270632e74657374696e672e5374726561" .
+            "6d696e674f757470757443616c6c526573706f6e736528013001123d0a11" .
+            "556e696d706c656d656e74656443616c6c12132e677270632e7465737469" .
+            "6e672e456d7074791a132e677270632e74657374696e672e456d70747932" .
+            "550a14556e696d706c656d656e74656453657276696365123d0a11556e69" .
+            "6d706c656d656e74656443616c6c12132e677270632e74657374696e672e" .
+            "456d7074791a132e677270632e74657374696e672e456d7074793289010a" .
+            "105265636f6e6e65637453657276696365123b0a055374617274121d2e67" .
+            "7270632e74657374696e672e5265636f6e6e656374506172616d731a132e" .
+            "677270632e74657374696e672e456d70747912380a0453746f7012132e67" .
+            "7270632e74657374696e672e456d7074791a1b2e677270632e7465737469" .
+            "6e672e5265636f6e6e656374496e666f620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php
new file mode 100644
index 0000000..a8a863d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/WorkerService.php
@@ -0,0 +1,36 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/worker_service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class WorkerService
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0add020a2b7372632f70726f746f2f677270632f74657374696e672f776f" .
+            "726b65725f736572766963652e70726f746f120c677270632e7465737469" .
+            "6e673297020a0d576f726b65725365727669636512450a0952756e536572" .
+            "76657212182e677270632e74657374696e672e536572766572417267731a" .
+            "1a2e677270632e74657374696e672e536572766572537461747573280130" .
+            "0112450a0952756e436c69656e7412182e677270632e74657374696e672e" .
+            "436c69656e74417267731a1a2e677270632e74657374696e672e436c6965" .
+            "6e745374617475732801300112420a09436f7265436f756e7412192e6772" .
+            "70632e74657374696e672e436f7265526571756573741a1a2e677270632e" .
+            "74657374696e672e436f7265526573706f6e736512340a0a51756974576f" .
+            "726b657212122e677270632e74657374696e672e566f69641a122e677270" .
+            "632e74657374696e672e566f6964620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
index f7bc215..0dd3072 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
@@ -97,6 +97,12 @@
      * Generated from protobuf field <code>int32 messages_per_stream = 18;</code>
      */
     private $messages_per_stream = 0;
+    /**
+     * Use coalescing API when possible.
+     *
+     * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+     */
+    private $use_coalesce_api = false;
 
     public function __construct() {
         \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
@@ -495,5 +501,31 @@
         return $this;
     }
 
+    /**
+     * Use coalescing API when possible.
+     *
+     * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+     * @return bool
+     */
+    public function getUseCoalesceApi()
+    {
+        return $this->use_coalesce_api;
+    }
+
+    /**
+     * Use coalescing API when possible.
+     *
+     * Generated from protobuf field <code>bool use_coalesce_api = 19;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setUseCoalesceApi($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->use_coalesce_api = $var;
+
+        return $this;
+    }
+
 }
 
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php b/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php
new file mode 100644
index 0000000..805b629
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/DebugInfo.php
@@ -0,0 +1,77 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Message to be echoed back serialized in trailer.
+ *
+ * Generated from protobuf message <code>grpc.testing.DebugInfo</code>
+ */
+class DebugInfo extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+     */
+    private $stack_entries;
+    /**
+     * Generated from protobuf field <code>string detail = 2;</code>
+     */
+    private $detail = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
+     */
+    public function getStackEntries()
+    {
+        return $this->stack_entries;
+    }
+
+    /**
+     * Generated from protobuf field <code>repeated string stack_entries = 1;</code>
+     * @param string[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
+     */
+    public function setStackEntries($var)
+    {
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+        $this->stack_entries = $arr;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string detail = 2;</code>
+     * @return string
+     */
+    public function getDetail()
+    {
+        return $this->detail;
+    }
+
+    /**
+     * Generated from protobuf field <code>string detail = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setDetail($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->detail = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php
new file mode 100644
index 0000000..9aadfc5
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoRequest.php
@@ -0,0 +1,75 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EchoRequest</code>
+ */
+class EchoRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     */
+    private $message = '';
+    /**
+     * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+     */
+    private $param = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     * @return string
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setMessage($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->message = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+     * @return \Grpc\Testing\RequestParams
+     */
+    public function getParam()
+    {
+        return $this->param;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.RequestParams param = 2;</code>
+     * @param \Grpc\Testing\RequestParams $var
+     * @return $this
+     */
+    public function setParam($var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\RequestParams::class);
+        $this->param = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php
new file mode 100644
index 0000000..c4a9db3
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoResponse.php
@@ -0,0 +1,75 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EchoResponse</code>
+ */
+class EchoResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     */
+    private $message = '';
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+     */
+    private $param = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     * @return string
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * Generated from protobuf field <code>string message = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setMessage($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->message = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+     * @return \Grpc\Testing\ResponseParams
+     */
+    public function getParam()
+    {
+        return $this->param;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ResponseParams param = 2;</code>
+     * @param \Grpc\Testing\ResponseParams $var
+     * @return $this
+     */
+    public function setParam($var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ResponseParams::class);
+        $this->param = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php
new file mode 100644
index 0000000..b3dcf5b
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoTestServiceClient.php
@@ -0,0 +1,93 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+namespace Grpc\Testing;
+
+/**
+ */
+class EchoTestServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Grpc\Testing\EchoRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function Echo(\Grpc\Testing\EchoRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.EchoTestService/Echo',
+        $argument,
+        ['\Grpc\Testing\EchoResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function RequestStream($metadata = [], $options = []) {
+        return $this->_clientStreamRequest('/grpc.testing.EchoTestService/RequestStream',
+        ['\Grpc\Testing\EchoResponse','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * @param \Grpc\Testing\EchoRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function ResponseStream(\Grpc\Testing\EchoRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_serverStreamRequest('/grpc.testing.EchoTestService/ResponseStream',
+        $argument,
+        ['\Grpc\Testing\EchoResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function BidiStream($metadata = [], $options = []) {
+        return $this->_bidiRequest('/grpc.testing.EchoTestService/BidiStream',
+        ['\Grpc\Testing\EchoResponse','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * @param \Grpc\Testing\EchoRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function Unimplemented(\Grpc\Testing\EchoRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.EchoTestService/Unimplemented',
+        $argument,
+        ['\Grpc\Testing\EchoResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php b/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php
new file mode 100644
index 0000000..3da163e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EmptyMessage.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.EmptyMessage</code>
+ */
+class EmptyMessage extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php
new file mode 100644
index 0000000..cc37875
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ErrorStatus.php
@@ -0,0 +1,103 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Error status client expects to see.
+ *
+ * Generated from protobuf message <code>grpc.testing.ErrorStatus</code>
+ */
+class ErrorStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>int32 code = 1;</code>
+     */
+    private $code = 0;
+    /**
+     * Generated from protobuf field <code>string error_message = 2;</code>
+     */
+    private $error_message = '';
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 3;</code>
+     */
+    private $binary_error_details = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 code = 1;</code>
+     * @return int
+     */
+    public function getCode()
+    {
+        return $this->code;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 code = 1;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setCode($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->code = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string error_message = 2;</code>
+     * @return string
+     */
+    public function getErrorMessage()
+    {
+        return $this->error_message;
+    }
+
+    /**
+     * Generated from protobuf field <code>string error_message = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setErrorMessage($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->error_message = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 3;</code>
+     * @return string
+     */
+    public function getBinaryErrorDetails()
+    {
+        return $this->binary_error_details;
+    }
+
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 3;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setBinaryErrorDetails($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->binary_error_details = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php
new file mode 100644
index 0000000..3c28369
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeRequest.php
@@ -0,0 +1,51 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Request message containing the gauge name
+ *
+ * Generated from protobuf message <code>grpc.testing.GaugeRequest</code>
+ */
+class GaugeRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     */
+    private $name = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php
new file mode 100644
index 0000000..da658ba
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/GaugeResponse.php
@@ -0,0 +1,126 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/metrics.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Reponse message containing the gauge name and value
+ *
+ * Generated from protobuf message <code>grpc.testing.GaugeResponse</code>
+ */
+class GaugeResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     */
+    private $name = '';
+    protected $value;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Metrics::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>int64 long_value = 2;</code>
+     * @return int|string
+     */
+    public function getLongValue()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * Generated from protobuf field <code>int64 long_value = 2;</code>
+     * @param int|string $var
+     * @return $this
+     */
+    public function setLongValue($var)
+    {
+        GPBUtil::checkInt64($var);
+        $this->writeOneof(2, $var);
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>double double_value = 3;</code>
+     * @return float
+     */
+    public function getDoubleValue()
+    {
+        return $this->readOneof(3);
+    }
+
+    /**
+     * Generated from protobuf field <code>double double_value = 3;</code>
+     * @param float $var
+     * @return $this
+     */
+    public function setDoubleValue($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->writeOneof(3, $var);
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string string_value = 4;</code>
+     * @return string
+     */
+    public function getStringValue()
+    {
+        return $this->readOneof(4);
+    }
+
+    /**
+     * Generated from protobuf field <code>string string_value = 4;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setStringValue($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->writeOneof(4, $var);
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getValue()
+    {
+        return $this->whichOneof("value");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php
new file mode 100644
index 0000000..491ccbc
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/MetricsServiceClient.php
@@ -0,0 +1,69 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Contains the definitions for a metrics service and the type of metrics
+// exposed by the service.
+//
+// Currently, 'Gauge' (i.e a metric that represents the measured value of
+// something at an instant of time) is the only metric type supported by the
+// service.
+namespace Grpc\Testing;
+
+/**
+ */
+class MetricsServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * Returns the values of all the gauges that are currently being maintained by
+     * the service
+     * @param \Grpc\Testing\EmptyMessage $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function GetAllGauges(\Grpc\Testing\EmptyMessage $argument,
+      $metadata = [], $options = []) {
+        return $this->_serverStreamRequest('/grpc.testing.MetricsService/GetAllGauges',
+        $argument,
+        ['\Grpc\Testing\GaugeResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * Returns the value of one gauge
+     * @param \Grpc\Testing\GaugeRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function GetGauge(\Grpc\Testing\GaugeRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.MetricsService/GetGauge',
+        $argument,
+        ['\Grpc\Testing\GaugeResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php
new file mode 100644
index 0000000..1d58eaf
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/NoRpcServiceClient.php
@@ -0,0 +1,35 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+namespace Grpc\Testing;
+
+/**
+ * A service without any rpc defined to test coverage.
+ */
+class NoRpcServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php b/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php
new file mode 100644
index 0000000..a1fe9df
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PBEmpty.php
@@ -0,0 +1,30 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/empty.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * An empty message that you can re-use to avoid defining duplicated empty
+ * messages in your project. A typical example is to use it as argument or the
+ * return value of a service API. For instance:
+ *   service Foo {
+ *     rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
+ *   };
+ *
+ * Generated from protobuf message <code>grpc.testing.Empty</code>
+ */
+class PBEmpty extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\GPBEmpty::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php b/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php
new file mode 100644
index 0000000..94cb6c1
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PBVoid.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Void</code>
+ */
+class PBVoid extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
index 5510b57..c0e3049 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
@@ -32,11 +32,11 @@
     }
 
     /**
-     * @param \Grpc\Testing\Void $argument input argument
+     * @param \Grpc\Testing\PBVoid $argument input argument
      * @param array $metadata metadata
      * @param array $options call options
      */
-    public function GetConfig(\Grpc\Testing\Void $argument,
+    public function GetConfig(\Grpc\Testing\PBVoid $argument,
       $metadata = [], $options = []) {
         return $this->_simpleRequest('/grpc.testing.ProxyClientService/GetConfig',
         $argument,
@@ -50,7 +50,7 @@
      */
     public function ReportTime($metadata = [], $options = []) {
         return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportTime',
-        ['\Grpc\Testing\Void','decode'],
+        ['\Grpc\Testing\PBVoid','decode'],
         $metadata, $options);
     }
 
@@ -60,7 +60,7 @@
      */
     public function ReportHist($metadata = [], $options = []) {
         return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportHist',
-        ['\Grpc\Testing\Void','decode'],
+        ['\Grpc\Testing\PBVoid','decode'],
         $metadata, $options);
     }
 
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php
new file mode 100644
index 0000000..a1802e9
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectServiceClient.php
@@ -0,0 +1,64 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A service used to control reconnect server.
+ */
+class ReconnectServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Grpc\Testing\ReconnectParams $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function Start(\Grpc\Testing\ReconnectParams $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.ReconnectService/Start',
+        $argument,
+        ['\Grpc\Testing\PBEmpty', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * @param \Grpc\Testing\PBEmpty $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function Stop(\Grpc\Testing\PBEmpty $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.ReconnectService/Stop',
+        $argument,
+        ['\Grpc\Testing\ReconnectInfo', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
index 72d44ff..3abb5ab 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReportQpsScenarioServiceClient.php
@@ -43,7 +43,7 @@
       $metadata = [], $options = []) {
         return $this->_simpleRequest('/grpc.testing.ReportQpsScenarioService/ReportScenario',
         $argument,
-        ['\Grpc\Testing\Void', 'decode'],
+        ['\Grpc\Testing\PBVoid', 'decode'],
         $metadata, $options);
     }
 
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Request.php b/src/php/tests/qps/generated_code/Grpc/Testing/Request.php
new file mode 100644
index 0000000..6a20f6a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Request.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Request</code>
+ */
+class Request extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\CompilerTest::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php
new file mode 100644
index 0000000..f01f50d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RequestParams.php
@@ -0,0 +1,431 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.RequestParams</code>
+ */
+class RequestParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+     */
+    private $echo_deadline = false;
+    /**
+     * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+     */
+    private $client_cancel_after_us = 0;
+    /**
+     * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+     */
+    private $server_cancel_after_us = 0;
+    /**
+     * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+     */
+    private $echo_metadata = false;
+    /**
+     * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+     */
+    private $check_auth_context = false;
+    /**
+     * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+     */
+    private $response_message_length = 0;
+    /**
+     * Generated from protobuf field <code>bool echo_peer = 7;</code>
+     */
+    private $echo_peer = false;
+    /**
+     * will force check_auth_context.
+     *
+     * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+     */
+    private $expected_client_identity = '';
+    /**
+     * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+     */
+    private $skip_cancelled_check = false;
+    /**
+     * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+     */
+    private $expected_transport_security_type = '';
+    /**
+     * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+     */
+    private $debug_info = null;
+    /**
+     * Server should not see a request with this set.
+     *
+     * Generated from protobuf field <code>bool server_die = 12;</code>
+     */
+    private $server_die = false;
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 13;</code>
+     */
+    private $binary_error_details = '';
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+     */
+    private $expected_error = null;
+    /**
+     * Amount to sleep when invoking server
+     *
+     * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+     */
+    private $server_sleep_us = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+     * @return bool
+     */
+    public function getEchoDeadline()
+    {
+        return $this->echo_deadline;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_deadline = 1;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setEchoDeadline($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->echo_deadline = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+     * @return int
+     */
+    public function getClientCancelAfterUs()
+    {
+        return $this->client_cancel_after_us;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 client_cancel_after_us = 2;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setClientCancelAfterUs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->client_cancel_after_us = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+     * @return int
+     */
+    public function getServerCancelAfterUs()
+    {
+        return $this->server_cancel_after_us;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 server_cancel_after_us = 3;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setServerCancelAfterUs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->server_cancel_after_us = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+     * @return bool
+     */
+    public function getEchoMetadata()
+    {
+        return $this->echo_metadata;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_metadata = 4;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setEchoMetadata($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->echo_metadata = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+     * @return bool
+     */
+    public function getCheckAuthContext()
+    {
+        return $this->check_auth_context;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool check_auth_context = 5;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setCheckAuthContext($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->check_auth_context = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+     * @return int
+     */
+    public function getResponseMessageLength()
+    {
+        return $this->response_message_length;
+    }
+
+    /**
+     * Generated from protobuf field <code>int32 response_message_length = 6;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setResponseMessageLength($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->response_message_length = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_peer = 7;</code>
+     * @return bool
+     */
+    public function getEchoPeer()
+    {
+        return $this->echo_peer;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool echo_peer = 7;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setEchoPeer($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->echo_peer = $var;
+
+        return $this;
+    }
+
+    /**
+     * will force check_auth_context.
+     *
+     * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+     * @return string
+     */
+    public function getExpectedClientIdentity()
+    {
+        return $this->expected_client_identity;
+    }
+
+    /**
+     * will force check_auth_context.
+     *
+     * Generated from protobuf field <code>string expected_client_identity = 8;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setExpectedClientIdentity($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->expected_client_identity = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+     * @return bool
+     */
+    public function getSkipCancelledCheck()
+    {
+        return $this->skip_cancelled_check;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool skip_cancelled_check = 9;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setSkipCancelledCheck($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->skip_cancelled_check = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+     * @return string
+     */
+    public function getExpectedTransportSecurityType()
+    {
+        return $this->expected_transport_security_type;
+    }
+
+    /**
+     * Generated from protobuf field <code>string expected_transport_security_type = 10;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setExpectedTransportSecurityType($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->expected_transport_security_type = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+     * @return \Grpc\Testing\DebugInfo
+     */
+    public function getDebugInfo()
+    {
+        return $this->debug_info;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.DebugInfo debug_info = 11;</code>
+     * @param \Grpc\Testing\DebugInfo $var
+     * @return $this
+     */
+    public function setDebugInfo($var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\DebugInfo::class);
+        $this->debug_info = $var;
+
+        return $this;
+    }
+
+    /**
+     * Server should not see a request with this set.
+     *
+     * Generated from protobuf field <code>bool server_die = 12;</code>
+     * @return bool
+     */
+    public function getServerDie()
+    {
+        return $this->server_die;
+    }
+
+    /**
+     * Server should not see a request with this set.
+     *
+     * Generated from protobuf field <code>bool server_die = 12;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setServerDie($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->server_die = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 13;</code>
+     * @return string
+     */
+    public function getBinaryErrorDetails()
+    {
+        return $this->binary_error_details;
+    }
+
+    /**
+     * Generated from protobuf field <code>string binary_error_details = 13;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setBinaryErrorDetails($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->binary_error_details = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+     * @return \Grpc\Testing\ErrorStatus
+     */
+    public function getExpectedError()
+    {
+        return $this->expected_error;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ErrorStatus expected_error = 14;</code>
+     * @param \Grpc\Testing\ErrorStatus $var
+     * @return $this
+     */
+    public function setExpectedError($var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ErrorStatus::class);
+        $this->expected_error = $var;
+
+        return $this;
+    }
+
+    /**
+     * Amount to sleep when invoking server
+     *
+     * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+     * @return int
+     */
+    public function getServerSleepUs()
+    {
+        return $this->server_sleep_us;
+    }
+
+    /**
+     * Amount to sleep when invoking server
+     *
+     * Generated from protobuf field <code>int32 server_sleep_us = 15;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setServerSleepUs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->server_sleep_us = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Response.php b/src/php/tests/qps/generated_code/Grpc/Testing/Response.php
new file mode 100644
index 0000000..7925a7d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Response.php
@@ -0,0 +1,23 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/compiler_test.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.Response</code>
+ */
+class Response extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\CompilerTest::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php
new file mode 100644
index 0000000..d20f922
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParams.php
@@ -0,0 +1,101 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/echo_messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>grpc.testing.ResponseParams</code>
+ */
+class ResponseParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+     */
+    private $request_deadline = 0;
+    /**
+     * Generated from protobuf field <code>string host = 2;</code>
+     */
+    private $host = '';
+    /**
+     * Generated from protobuf field <code>string peer = 3;</code>
+     */
+    private $peer = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\EchoMessages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+     * @return int|string
+     */
+    public function getRequestDeadline()
+    {
+        return $this->request_deadline;
+    }
+
+    /**
+     * Generated from protobuf field <code>int64 request_deadline = 1;</code>
+     * @param int|string $var
+     * @return $this
+     */
+    public function setRequestDeadline($var)
+    {
+        GPBUtil::checkInt64($var);
+        $this->request_deadline = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string host = 2;</code>
+     * @return string
+     */
+    public function getHost()
+    {
+        return $this->host;
+    }
+
+    /**
+     * Generated from protobuf field <code>string host = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setHost($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->host = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string peer = 3;</code>
+     * @return string
+     */
+    public function getPeer()
+    {
+        return $this->peer;
+    }
+
+    /**
+     * Generated from protobuf field <code>string peer = 3;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setPeer($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->peer = $var;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php
new file mode 100644
index 0000000..df469cb
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceAClient.php
@@ -0,0 +1,97 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// File detached comment 1
+//
+// File detached comment 2
+//
+// File leading comment 1
+namespace Grpc\Testing;
+
+/**
+ * ServiceA detached comment 1
+ *
+ * ServiceA detached comment 2
+ *
+ * ServiceA leading comment 1
+ */
+class ServiceAClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * MethodA1 leading comment 1
+     * @param \Grpc\Testing\Request $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function MethodA1(\Grpc\Testing\Request $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.ServiceA/MethodA1',
+        $argument,
+        ['\Grpc\Testing\Response', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * MethodA2 detached leading comment 1
+     *
+     * Method A2 leading comment 1
+     * Method A2 leading comment 2
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function MethodA2($metadata = [], $options = []) {
+        return $this->_clientStreamRequest('/grpc.testing.ServiceA/MethodA2',
+        ['\Grpc\Testing\Response','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * Method A3 leading comment 1
+     * @param \Grpc\Testing\Request $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function MethodA3(\Grpc\Testing\Request $argument,
+      $metadata = [], $options = []) {
+        return $this->_serverStreamRequest('/grpc.testing.ServiceA/MethodA3',
+        $argument,
+        ['\Grpc\Testing\Response', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * Method A4 leading comment 1
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function MethodA4($metadata = [], $options = []) {
+        return $this->_bidiRequest('/grpc.testing.ServiceA/MethodA4',
+        ['\Grpc\Testing\Response','decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php
new file mode 100644
index 0000000..54acf63
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServiceBClient.php
@@ -0,0 +1,54 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// File detached comment 1
+//
+// File detached comment 2
+//
+// File leading comment 1
+namespace Grpc\Testing;
+
+/**
+ * ServiceB leading comment 1
+ */
+class ServiceBClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * MethodB1 leading comment 1
+     * @param \Grpc\Testing\Request $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function MethodB1(\Grpc\Testing\Request $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.ServiceB/MethodB1',
+        $argument,
+        ['\Grpc\Testing\Response', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php
new file mode 100644
index 0000000..7da9713
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/TestServiceClient.php
@@ -0,0 +1,152 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A simple service to test the various types of RPCs and experiment with
+ * performance with various types of payload.
+ */
+class TestServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * One empty request followed by one empty response.
+     * @param \Grpc\Testing\PBEmpty $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function EmptyCall(\Grpc\Testing\PBEmpty $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.TestService/EmptyCall',
+        $argument,
+        ['\Grpc\Testing\PBEmpty', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * One request followed by one response.
+     * @param \Grpc\Testing\SimpleRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function UnaryCall(\Grpc\Testing\SimpleRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.TestService/UnaryCall',
+        $argument,
+        ['\Grpc\Testing\SimpleResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * One request followed by one response. Response has cache control
+     * headers set such that a caching HTTP proxy (such as GFE) can
+     * satisfy subsequent requests.
+     * @param \Grpc\Testing\SimpleRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function CacheableUnaryCall(\Grpc\Testing\SimpleRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.TestService/CacheableUnaryCall',
+        $argument,
+        ['\Grpc\Testing\SimpleResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * @param \Grpc\Testing\StreamingOutputCallRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function StreamingOutputCall(\Grpc\Testing\StreamingOutputCallRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_serverStreamRequest('/grpc.testing.TestService/StreamingOutputCall',
+        $argument,
+        ['\Grpc\Testing\StreamingOutputCallResponse', 'decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function StreamingInputCall($metadata = [], $options = []) {
+        return $this->_clientStreamRequest('/grpc.testing.TestService/StreamingInputCall',
+        ['\Grpc\Testing\StreamingInputCallResponse','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full duplexing.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function FullDuplexCall($metadata = [], $options = []) {
+        return $this->_bidiRequest('/grpc.testing.TestService/FullDuplexCall',
+        ['\Grpc\Testing\StreamingOutputCallResponse','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function HalfDuplexCall($metadata = [], $options = []) {
+        return $this->_bidiRequest('/grpc.testing.TestService/HalfDuplexCall',
+        ['\Grpc\Testing\StreamingOutputCallResponse','decode'],
+        $metadata, $options);
+    }
+
+    /**
+     * The test server will not implement this method. It will be used
+     * to test the behavior when clients call unimplemented methods.
+     * @param \Grpc\Testing\PBEmpty $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function UnimplementedCall(\Grpc\Testing\PBEmpty $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.TestService/UnimplementedCall',
+        $argument,
+        ['\Grpc\Testing\PBEmpty', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php
new file mode 100644
index 0000000..fee0daa
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedEchoServiceClient.php
@@ -0,0 +1,47 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+namespace Grpc\Testing;
+
+/**
+ */
+class UnimplementedEchoServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Grpc\Testing\EchoRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function Unimplemented(\Grpc\Testing\EchoRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.UnimplementedEchoService/Unimplemented',
+        $argument,
+        ['\Grpc\Testing\EchoResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php
new file mode 100644
index 0000000..53b2020
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/UnimplementedServiceClient.php
@@ -0,0 +1,53 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A simple service NOT implemented at servers so clients can test for
+ * that case.
+ */
+class UnimplementedServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * A call that no server should implement
+     * @param \Grpc\Testing\PBEmpty $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function UnimplementedCall(\Grpc\Testing\PBEmpty $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.UnimplementedService/UnimplementedCall',
+        $argument,
+        ['\Grpc\Testing\PBEmpty', 'decode'],
+        $metadata, $options);
+    }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
index 98c244f..366e365 100644
--- a/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
@@ -81,15 +81,15 @@
 
     /**
      * Quit this worker
-     * @param \Grpc\Testing\Void $argument input argument
+     * @param \Grpc\Testing\PBVoid $argument input argument
      * @param array $metadata metadata
      * @param array $options call options
      */
-    public function QuitWorker(\Grpc\Testing\Void $argument,
+    public function QuitWorker(\Grpc\Testing\PBVoid $argument,
       $metadata = [], $options = []) {
         return $this->_simpleRequest('/grpc.testing.WorkerService/QuitWorker',
         $argument,
-        ['\Grpc\Testing\Void', 'decode'],
+        ['\Grpc\Testing\PBVoid', 'decode'],
         $metadata, $options);
     }
 
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 58412ed..16721ff 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -76,11 +76,26 @@
 )
 
 grpc_proto_library(
-    name = "services_proto",
-    srcs = ["services.proto"],
+    name = "benchmark_service_proto",
+    srcs = ["benchmark_service.proto"],
     deps = [
-        "control_proto",
-        "messages_proto",
+      "messages_proto",
+    ],
+)
+
+grpc_proto_library(
+    name = "report_qps_scenario_service_proto",
+    srcs = ["report_qps_scenario_service.proto"],
+    deps = [
+      "control_proto",
+    ],
+)
+
+grpc_proto_library(
+    name = "worker_service_proto",
+    srcs = ["worker_service.proto"],
+    deps = [
+      "control_proto",
     ],
 )
 
diff --git a/src/proto/grpc/testing/benchmark_service.proto b/src/proto/grpc/testing/benchmark_service.proto
new file mode 100644
index 0000000..63167a8
--- /dev/null
+++ b/src/proto/grpc/testing/benchmark_service.proto
@@ -0,0 +1,44 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/messages.proto";
+
+package grpc.testing;
+
+service BenchmarkService {
+  // One request followed by one response.
+  // The server returns the client payload as-is.
+  rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+  // Repeated sequence of one request followed by one response.
+  // Should be called streaming ping-pong
+  // The server returns the client payload as-is on each response
+  rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse);
+
+  // Single-sided unbounded streaming from client to server
+  // The server returns the client payload as-is once the client does WritesDone
+  rpc StreamingFromClient(stream SimpleRequest) returns (SimpleResponse);
+
+  // Single-sided unbounded streaming from server to client
+  // The server repeatedly returns the client payload as-is
+  rpc StreamingFromServer(SimpleRequest) returns (stream SimpleResponse);
+
+  // Two-sided unbounded streaming between server to client
+  // Both sides send the content of their own choice to the other
+  rpc StreamingBothWays(stream SimpleRequest) returns (stream SimpleResponse);
+}
diff --git a/src/proto/grpc/testing/report_qps_scenario_service.proto b/src/proto/grpc/testing/report_qps_scenario_service.proto
new file mode 100644
index 0000000..f4e5c36
--- /dev/null
+++ b/src/proto/grpc/testing/report_qps_scenario_service.proto
@@ -0,0 +1,26 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+service ReportQpsScenarioService {
+  // Report results of a QPS test benchmark scenario.
+  rpc ReportScenario(ScenarioResult) returns (Void);
+}
diff --git a/src/proto/grpc/testing/services.proto b/src/proto/grpc/testing/services.proto
deleted file mode 100644
index 93c21f4..0000000
--- a/src/proto/grpc/testing/services.proto
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// An integration test service that covers all the method signature permutations
-// of unary/streaming requests/responses.
-syntax = "proto3";
-
-import "src/proto/grpc/testing/messages.proto";
-import "src/proto/grpc/testing/control.proto";
-
-package grpc.testing;
-
-service BenchmarkService {
-  // One request followed by one response.
-  // The server returns the client payload as-is.
-  rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
-
-  // Repeated sequence of one request followed by one response.
-  // Should be called streaming ping-pong
-  // The server returns the client payload as-is on each response
-  rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse);
-
-  // Single-sided unbounded streaming from client to server
-  // The server returns the client payload as-is once the client does WritesDone
-  rpc StreamingFromClient(stream SimpleRequest) returns (SimpleResponse);
-
-  // Single-sided unbounded streaming from server to client
-  // The server repeatedly returns the client payload as-is
-  rpc StreamingFromServer(SimpleRequest) returns (stream SimpleResponse);
-
-  // Two-sided unbounded streaming between server to client
-  // Both sides send the content of their own choice to the other
-  rpc StreamingBothWays(stream SimpleRequest) returns (stream SimpleResponse);
-}
-
-service WorkerService {
-  // Start server with specified workload.
-  // First request sent specifies the ServerConfig followed by ServerStatus
-  // response. After that, a "Mark" can be sent anytime to request the latest
-  // stats. Closing the stream will initiate shutdown of the test server
-  // and once the shutdown has finished, the OK status is sent to terminate
-  // this RPC.
-  rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
-
-  // Start client with specified workload.
-  // First request sent specifies the ClientConfig followed by ClientStatus
-  // response. After that, a "Mark" can be sent anytime to request the latest
-  // stats. Closing the stream will initiate shutdown of the test client
-  // and once the shutdown has finished, the OK status is sent to terminate
-  // this RPC.
-  rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
-
-  // Just return the core count - unary call
-  rpc CoreCount(CoreRequest) returns (CoreResponse);
-
-  // Quit this worker
-  rpc QuitWorker(Void) returns (Void);
-}
-
-service ReportQpsScenarioService {
-  // Report results of a QPS test benchmark scenario.
-  rpc ReportScenario(ScenarioResult) returns (Void);
-}
diff --git a/src/proto/grpc/testing/worker_service.proto b/src/proto/grpc/testing/worker_service.proto
new file mode 100644
index 0000000..a4cde94
--- /dev/null
+++ b/src/proto/grpc/testing/worker_service.proto
@@ -0,0 +1,45 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+service WorkerService {
+  // Start server with specified workload.
+  // First request sent specifies the ServerConfig followed by ServerStatus
+  // response. After that, a "Mark" can be sent anytime to request the latest
+  // stats. Closing the stream will initiate shutdown of the test server
+  // and once the shutdown has finished, the OK status is sent to terminate
+  // this RPC.
+  rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
+
+  // Start client with specified workload.
+  // First request sent specifies the ClientConfig followed by ClientStatus
+  // response. After that, a "Mark" can be sent anytime to request the latest
+  // stats. Closing the stream will initiate shutdown of the test client
+  // and once the shutdown has finished, the OK status is sent to terminate
+  // this RPC.
+  rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
+
+  // Just return the core count - unary call
+  rpc CoreCount(CoreRequest) returns (CoreResponse);
+
+  // Quit this worker
+  rpc QuitWorker(Void) returns (Void);
+}
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 60d309e..35c0982 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -57,7 +57,7 @@
 }
 
 INSTALL_REQUIRES = (
-    'protobuf>=3.5.0.post1',
+    'protobuf>=3.5.2.post1',
     'grpcio>={version}'.format(version=grpc_version.VERSION),
 )
 
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index 10c4c38..589d0ff 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -58,7 +58,7 @@
 }
 
 INSTALL_REQUIRES = (
-    'protobuf>=3.5.0.post1',
+    'protobuf>=3.5.2.post1',
     'grpcio>={version}'.format(version=grpc_version.VERSION),
 )
 
diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py
index 5a9d593..eb480a5 100644
--- a/src/python/grpcio_testing/setup.py
+++ b/src/python/grpcio_testing/setup.py
@@ -29,7 +29,7 @@
 }
 
 INSTALL_REQUIRES = (
-    'protobuf>=3.5.0.post1',
+    'protobuf>=3.5.2.post1',
     'grpcio>={version}'.format(version=grpc_version.VERSION),
 )
 
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 4e0f672..98ac19d 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -41,7 +41,7 @@
     'grpcio>={version}'.format(version=grpc_version.VERSION),
     'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
     'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
-    'oauth2client>=1.4.7', 'protobuf>=3.5.0.post1', 'six>=1.10',
+    'oauth2client>=1.4.7', 'protobuf>=3.5.2.post1', 'six>=1.10',
     'google-auth>=1.0.0', 'requests>=2.14.2')
 
 COMMAND_CLASS = {
diff --git a/src/python/grpcio_tests/tests/_loader.py b/src/python/grpcio_tests/tests/_loader.py
index 3168091..be0af646 100644
--- a/src/python/grpcio_tests/tests/_loader.py
+++ b/src/python/grpcio_tests/tests/_loader.py
@@ -54,7 +54,7 @@
         for module in modules:
             try:
                 package_paths = module.__path__
-            except:
+            except AttributeError:
                 continue
             self.walk_packages(package_paths)
         coverage_context.stop()
diff --git a/src/python/grpcio_tests/tests/_result.py b/src/python/grpcio_tests/tests/_result.py
index 9907c4e..b105f18 100644
--- a/src/python/grpcio_tests/tests/_result.py
+++ b/src/python/grpcio_tests/tests/_result.py
@@ -46,7 +46,7 @@
       None.
   """
 
-    class Kind:
+    class Kind(object):
         UNTESTED = 'untested'
         RUNNING = 'running'
         ERROR = 'error'
@@ -257,7 +257,7 @@
         #coverage.Coverage().combine()
 
 
-class _Colors:
+class _Colors(object):
     """Namespaced constants for terminal color magic numbers."""
     HEADER = '\033[95m'
     INFO = '\033[94m'
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index 3780ed9..698c370 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -66,10 +66,6 @@
     return parser.parse_args()
 
 
-def _application_default_credentials():
-    return oauth2client_client.GoogleCredentials.get_application_default()
-
-
 def _stub(args):
     target = '{}:{}'.format(args.server_host, args.server_port)
     if args.test_case == 'oauth2_auth_token':
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
index ad0ecf0..b46e533 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
@@ -329,9 +329,7 @@
 
         _packagify(self._python_out)
 
-        with _system_path([
-                self._python_out,
-        ]):
+        with _system_path([self._python_out]):
             self._payload_pb2 = importlib.import_module(_PAYLOAD_PB2)
             self._requests_pb2 = importlib.import_module(_REQUESTS_PB2)
             self._responses_pb2 = importlib.import_module(_RESPONSES_PB2)
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py
index e6392a8..0488450 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_client.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py
@@ -22,7 +22,7 @@
 
 import grpc
 from src.proto.grpc.testing import messages_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import benchmark_service_pb2_grpc
 from tests.unit import resources
 from tests.unit import test_common
 
@@ -58,7 +58,8 @@
 
         if config.payload_config.WhichOneof('payload') == 'simple_params':
             self._generic = False
-            self._stub = services_pb2_grpc.BenchmarkServiceStub(channel)
+            self._stub = benchmark_service_pb2_grpc.BenchmarkServiceStub(
+                channel)
             payload = messages_pb2.Payload(
                 body='\0' * config.payload_config.simple_params.req_size)
             self._request = messages_pb2.SimpleRequest(
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_server.py b/src/python/grpcio_tests/tests/qps/benchmark_server.py
index bb07844..2bd89cb 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_server.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_server.py
@@ -13,10 +13,10 @@
 # limitations under the License.
 
 from src.proto.grpc.testing import messages_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import benchmark_service_pb2_grpc
 
 
-class BenchmarkServer(services_pb2_grpc.BenchmarkServiceServicer):
+class BenchmarkServer(benchmark_service_pb2_grpc.BenchmarkServiceServicer):
     """Synchronous Server implementation for the Benchmark service."""
 
     def UnaryCall(self, request, context):
@@ -29,7 +29,8 @@
             yield messages_pb2.SimpleResponse(payload=payload)
 
 
-class GenericBenchmarkServer(services_pb2_grpc.BenchmarkServiceServicer):
+class GenericBenchmarkServer(
+        benchmark_service_pb2_grpc.BenchmarkServiceServicer):
     """Generic Server implementation for the Benchmark service."""
 
     def __init__(self, resp_size):
diff --git a/src/python/grpcio_tests/tests/qps/qps_worker.py b/src/python/grpcio_tests/tests/qps/qps_worker.py
index 54f69db..c33d013 100644
--- a/src/python/grpcio_tests/tests/qps/qps_worker.py
+++ b/src/python/grpcio_tests/tests/qps/qps_worker.py
@@ -17,7 +17,7 @@
 import time
 
 import grpc
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import worker_service_pb2_grpc
 
 from tests.qps import worker_server
 from tests.unit import test_common
@@ -26,7 +26,8 @@
 def run_worker_server(port):
     server = test_common.test_server()
     servicer = worker_server.WorkerServer()
-    services_pb2_grpc.add_WorkerServiceServicer_to_server(servicer, server)
+    worker_service_pb2_grpc.add_WorkerServiceServicer_to_server(
+        servicer, server)
     server.add_insecure_port('[::]:{}'.format(port))
     server.start()
     servicer.wait_for_quit()
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 41e2403..db145fb 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -20,7 +20,7 @@
 from concurrent import futures
 import grpc
 from src.proto.grpc.testing import control_pb2
-from src.proto.grpc.testing import services_pb2_grpc
+from src.proto.grpc.testing import worker_service_pb2_grpc
 from src.proto.grpc.testing import stats_pb2
 
 from tests.qps import benchmark_client
@@ -31,7 +31,7 @@
 from tests.unit import test_common
 
 
-class WorkerServer(services_pb2_grpc.WorkerServiceServicer):
+class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
     """Python Worker Server implementation."""
 
     def __init__(self):
@@ -72,7 +72,7 @@
         server = test_common.test_server(max_workers=server_threads)
         if config.server_type == control_pb2.ASYNC_SERVER:
             servicer = benchmark_server.BenchmarkServer()
-            services_pb2_grpc.add_BenchmarkServiceServicer_to_server(
+            worker_service_pb2_grpc.add_BenchmarkServiceServicer_to_server(
                 servicer, server)
         elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
             resp_size = config.payload_config.bytebuf_params.resp_size
diff --git a/src/python/grpcio_tests/tests/stress/test_runner.py b/src/python/grpcio_tests/tests/stress/test_runner.py
index d5038e3..764cda1 100644
--- a/src/python/grpcio_tests/tests/stress/test_runner.py
+++ b/src/python/grpcio_tests/tests/stress/test_runner.py
@@ -50,7 +50,7 @@
                 test_case.test_interoperability(self._stub, None)
                 end_time = time.time()
                 self._histogram.add((end_time - start_time) * 1e9)
-            except Exception as e:
+            except Exception as e:  # pylint: disable=broad-except
                 traceback.print_exc()
                 self._exception_queue.put(
                     Exception("An exception occured during test {}"
diff --git a/src/python/grpcio_tests/tests/testing/_client_application.py b/src/python/grpcio_tests/tests/testing/_client_application.py
index 7d0d74c..3ddeba2 100644
--- a/src/python/grpcio_tests/tests/testing/_client_application.py
+++ b/src/python/grpcio_tests/tests/testing/_client_application.py
@@ -215,30 +215,6 @@
         return _UNSATISFACTORY_OUTCOME
 
 
-def run(scenario, channel):
-    stub = services_pb2_grpc.FirstServiceStub(channel)
-    try:
-        if scenario is Scenario.UNARY_UNARY:
-            return _run_unary_unary(stub)
-        elif scenario is Scenario.UNARY_STREAM:
-            return _run_unary_stream(stub)
-        elif scenario is Scenario.STREAM_UNARY:
-            return _run_stream_unary(stub)
-        elif scenario is Scenario.STREAM_STREAM:
-            return _run_stream_stream(stub)
-        elif scenario is Scenario.CONCURRENT_STREAM_UNARY:
-            return _run_concurrent_stream_unary(stub)
-        elif scenario is Scenario.CONCURRENT_STREAM_STREAM:
-            return _run_concurrent_stream_stream(stub)
-        elif scenario is Scenario.CANCEL_UNARY_UNARY:
-            return _run_cancel_unary_unary(stub)
-        elif scenario is Scenario.INFINITE_REQUEST_STREAM:
-            return _run_infinite_request_stream(stub)
-    except grpc.RpcError as rpc_error:
-        return Outcome(Outcome.Kind.RPC_ERROR, rpc_error.code(),
-                       rpc_error.details())
-
-
 _IMPLEMENTATIONS = {
     Scenario.UNARY_UNARY: _run_unary_unary,
     Scenario.UNARY_STREAM: _run_unary_stream,
diff --git a/src/python/grpcio_tests/tests/testing/_server_application.py b/src/python/grpcio_tests/tests/testing/_server_application.py
index 02769ca..243c385 100644
--- a/src/python/grpcio_tests/tests/testing/_server_application.py
+++ b/src/python/grpcio_tests/tests/testing/_server_application.py
@@ -38,7 +38,7 @@
             context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
             context.set_details('Something is wrong with your request!')
         return
-        yield services_pb2.Strange()
+        yield services_pb2.Strange()  # pylint: disable=unreachable
 
     def StreUn(self, request_iterator, context):
         context.send_initial_metadata(((
diff --git a/src/python/grpcio_tests/tests/testing/_server_test.py b/src/python/grpcio_tests/tests/testing/_server_test.py
index 4f4abd7..88e3a79 100644
--- a/src/python/grpcio_tests/tests/testing/_server_test.py
+++ b/src/python/grpcio_tests/tests/testing/_server_test.py
@@ -21,13 +21,8 @@
 from tests.testing import _application_common
 from tests.testing import _application_testing_common
 from tests.testing import _server_application
-from tests.testing.proto import services_pb2
 
 
-# TODO(https://github.com/google/protobuf/issues/3452): Drop this skip.
-@unittest.skipIf(
-    services_pb2.DESCRIPTOR.services_by_name.get('FirstService') is None,
-    'Fix protobuf issue 3452!')
 class FirstServiceServicerTest(unittest.TestCase):
 
     def setUp(self):
diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 7550cd3..0b11f03 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -52,9 +52,9 @@
         self.stream_unary = None
         self.stream_stream = None
         if self.request_streaming and self.response_streaming:
-            self.stream_stream = lambda x, y: handle_stream(x, y)
+            self.stream_stream = handle_stream
         elif not self.request_streaming and not self.response_streaming:
-            self.unary_unary = lambda x, y: handle_unary(x, y)
+            self.unary_unary = handle_unary
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
index 9045ff5..23f5ef6 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
@@ -285,7 +285,7 @@
         self.assertEqual(5, len(server_event.batch_operations))
         found_server_op_types = set()
         for server_result in server_event.batch_operations:
-            self.assertNotIn(client_result.type(), found_server_op_types)
+            self.assertNotIn(server_result.type(), found_server_op_types)
             found_server_op_types.add(server_result.type())
             if server_result.type() == cygrpc.OperationType.receive_message:
                 self.assertEqual(REQUEST, server_result.message())
diff --git a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
index 4a00b9e..7d5eaaa 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
@@ -25,7 +25,7 @@
         def wrapped_function():
             try:
                 self._result = function(*args, **kwargs)
-            except Exception as error:
+            except Exception as error:  # pylint: disable=broad-except
                 self._error = error
 
         self._result = None
@@ -41,7 +41,7 @@
         self._thread.join()
         if self._error:
             # TODO(atash): re-raise exceptions in a way that preserves tracebacks
-            raise self._error
+            raise self._error  # pylint: disable=raising-bad-type
         return self._result
 
 
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index 6e6d9de..f40f3ae 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -49,7 +49,7 @@
         for process in processes:
             try:
                 process.kill()
-            except Exception:
+            except Exception:  # pylint: disable=broad-except
                 pass
 
 
diff --git a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
index e683131..ad847ae 100644
--- a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
+++ b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py
@@ -14,7 +14,7 @@
 
 _BEFORE_IMPORT = tuple(globals())
 
-from grpc import *
+from grpc import *  # pylint: disable=wildcard-import
 
 _AFTER_IMPORT = tuple(globals())
 
diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
index e40cca8..93a5fdf 100644
--- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
@@ -165,11 +165,13 @@
 
     def __next__(self):
         if self._current >= self._high:
-            raise Exception("This is a deliberate failure in a unit test.")
+            raise test_control.Defect()
         else:
             self._current += 1
             return self._bytestring
 
+    next = __next__
+
 
 def _unary_unary_multi_callable(channel):
     return channel.unary_unary(_UNARY_UNARY)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
index 61c03f6..b43c647 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
@@ -65,7 +65,7 @@
             self._serviced = True
             self._condition.notify_all()
             return
-            yield
+            yield  # pylint: disable=unreachable
 
     def stream_unary(self, request_iterator, context):
         for request in request_iterator:
diff --git a/src/ruby/pb/generate_proto_ruby.sh b/src/ruby/pb/generate_proto_ruby.sh
index d25eff5..ec6e2ee 100755
--- a/src/ruby/pb/generate_proto_ruby.sh
+++ b/src/ruby/pb/generate_proto_ruby.sh
@@ -32,7 +32,13 @@
     --plugin=$PLUGIN
 
 $PROTOC -I . \
-    src/proto/grpc/testing/{messages,payloads,stats,services,control}.proto \
+    src/proto/grpc/core/stats.proto \
+    --grpc_out=src/ruby/qps \
+    --ruby_out=src/ruby/qps \
+    --plugin=$PLUGIN
+
+$PROTOC -I . \
+    src/proto/grpc/testing/{messages,payloads,stats,benchmark_service,report_qps_scenario_service,worker_service,control}.proto \
     --grpc_out=src/ruby/qps \
     --ruby_out=src/ruby/qps \
     --plugin=$PLUGIN
diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb
index 0426aee..d573d82 100644
--- a/src/ruby/qps/client.rb
+++ b/src/ruby/qps/client.rb
@@ -23,7 +23,7 @@
 
 require 'grpc'
 require 'histogram'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/benchmark_service_services_pb'
 
 class Poisson
   def interarrival
diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb
index 4c7c510..5f23d89 100755
--- a/src/ruby/qps/proxy-worker.rb
+++ b/src/ruby/qps/proxy-worker.rb
@@ -27,7 +27,7 @@
 require 'etc'
 require 'facter'
 require 'qps-common'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/worker_service_services_pb'
 require 'src/proto/grpc/testing/proxy-service_services_pb'
 
 class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Service
diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb
index 90218ea..dccc64e 100644
--- a/src/ruby/qps/server.rb
+++ b/src/ruby/qps/server.rb
@@ -24,7 +24,7 @@
 require 'grpc'
 require 'qps-common'
 require 'src/proto/grpc/testing/messages_pb'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/benchmark_service_services_pb'
 require 'src/proto/grpc/testing/stats_pb'
 
 class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service
diff --git a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb
new file mode 100644
index 0000000..59c0578
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb
@@ -0,0 +1,33 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/core/stats.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.core.Bucket" do
+    optional :start, :double, 1
+    optional :count, :uint64, 2
+  end
+  add_message "grpc.core.Histogram" do
+    repeated :buckets, :message, 1, "grpc.core.Bucket"
+  end
+  add_message "grpc.core.Metric" do
+    optional :name, :string, 1
+    oneof :value do
+      optional :count, :uint64, 10
+      optional :histogram, :message, 11, "grpc.core.Histogram"
+    end
+  end
+  add_message "grpc.core.Stats" do
+    repeated :metrics, :message, 1, "grpc.core.Metric"
+  end
+end
+
+module Grpc
+  module Core
+    Bucket = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Bucket").msgclass
+    Histogram = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Histogram").msgclass
+    Metric = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Metric").msgclass
+    Stats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.core.Stats").msgclass
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
similarity index 71%
rename from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
rename to src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
index 5ce13bf..0bd3625 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb
@@ -1,10 +1,9 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/benchmark_service.proto
 
 require 'google/protobuf'
 
 require 'src/proto/grpc/testing/messages_pb'
-require 'src/proto/grpc/testing/control_pb'
 Google::Protobuf::DescriptorPool.generated_pool.build do
 end
 
diff --git a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb
new file mode 100644
index 0000000..65e5a75
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_services_pb.rb
@@ -0,0 +1,56 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: src/proto/grpc/testing/benchmark_service.proto for package 'grpc.testing'
+# Original file comments:
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
+
+require 'grpc'
+require 'src/proto/grpc/testing/benchmark_service_pb'
+
+module Grpc
+  module Testing
+    module BenchmarkService
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.BenchmarkService'
+
+        # One request followed by one response.
+        # The server returns the client payload as-is.
+        rpc :UnaryCall, SimpleRequest, SimpleResponse
+        # Repeated sequence of one request followed by one response.
+        # Should be called streaming ping-pong
+        # The server returns the client payload as-is on each response
+        rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse)
+        # Single-sided unbounded streaming from client to server
+        # The server returns the client payload as-is once the client does WritesDone
+        rpc :StreamingFromClient, stream(SimpleRequest), SimpleResponse
+        # Single-sided unbounded streaming from server to client
+        # The server repeatedly returns the client payload as-is
+        rpc :StreamingFromServer, SimpleRequest, stream(SimpleResponse)
+        # Two-sided unbounded streaming between server to client
+        # Both sides send the content of their own choice to the other
+        rpc :StreamingBothWays, stream(SimpleRequest), stream(SimpleResponse)
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
index 02207a2..5acc7fc 100644
--- a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
@@ -20,6 +20,14 @@
   add_message "grpc.testing.SecurityParams" do
     optional :use_test_ca, :bool, 1
     optional :server_host_override, :string, 2
+    optional :cred_type, :string, 3
+  end
+  add_message "grpc.testing.ChannelArg" do
+    optional :name, :string, 1
+    oneof :value do
+      optional :str_value, :string, 2
+      optional :int_value, :int32, 3
+    end
   end
   add_message "grpc.testing.ClientConfig" do
     repeated :server_targets, :string, 1
@@ -35,6 +43,10 @@
     repeated :core_list, :int32, 13
     optional :core_limit, :int32, 14
     optional :other_client_api, :string, 15
+    repeated :channel_args, :message, 16, "grpc.testing.ChannelArg"
+    optional :threads_per_cq, :int32, 17
+    optional :messages_per_stream, :int32, 18
+    optional :use_coalesce_api, :bool, 19
   end
   add_message "grpc.testing.ClientStatus" do
     optional :stats, :message, 1, "grpc.testing.ClientStats"
@@ -57,6 +69,9 @@
     optional :payload_config, :message, 9, "grpc.testing.PayloadConfig"
     repeated :core_list, :int32, 10
     optional :other_server_api, :string, 11
+    optional :threads_per_cq, :int32, 12
+    optional :resource_quota_size, :int32, 1001
+    repeated :channel_args, :message, 1002, "grpc.testing.ChannelArg"
   end
   add_message "grpc.testing.ServerArgs" do
     oneof :argtype do
@@ -101,6 +116,13 @@
     optional :latency_95, :double, 9
     optional :latency_99, :double, 10
     optional :latency_999, :double, 11
+    optional :server_cpu_usage, :double, 12
+    optional :successful_requests_per_second, :double, 13
+    optional :failed_requests_per_second, :double, 14
+    optional :client_polls_per_request, :double, 15
+    optional :server_polls_per_request, :double, 16
+    optional :server_queries_per_cpu_sec, :double, 17
+    optional :client_queries_per_cpu_sec, :double, 18
   end
   add_message "grpc.testing.ScenarioResult" do
     optional :scenario, :message, 1, "grpc.testing.Scenario"
@@ -111,6 +133,7 @@
     optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary"
     repeated :client_success, :bool, 7
     repeated :server_success, :bool, 8
+    repeated :request_results, :message, 9, "grpc.testing.RequestResultCount"
   end
   add_enum "grpc.testing.ClientType" do
     value :SYNC_CLIENT, 0
@@ -126,6 +149,9 @@
   add_enum "grpc.testing.RpcType" do
     value :UNARY, 0
     value :STREAMING, 1
+    value :STREAMING_FROM_CLIENT, 2
+    value :STREAMING_FROM_SERVER, 3
+    value :STREAMING_BOTH_WAYS, 4
   end
 end
 
@@ -135,6 +161,7 @@
     ClosedLoopParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClosedLoopParams").msgclass
     LoadParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadParams").msgclass
     SecurityParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SecurityParams").msgclass
+    ChannelArg = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ChannelArg").msgclass
     ClientConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfig").msgclass
     ClientStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStatus").msgclass
     Mark = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Mark").msgclass
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
similarity index 71%
copy from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
copy to src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
index 5ce13bf..1b43e37 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb
@@ -1,9 +1,8 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/report_qps_scenario_service.proto
 
 require 'google/protobuf'
 
-require 'src/proto/grpc/testing/messages_pb'
 require 'src/proto/grpc/testing/control_pb'
 Google::Protobuf::DescriptorPool.generated_pool.build do
 end
diff --git a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb
new file mode 100644
index 0000000..ddc81be
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_services_pb.rb
@@ -0,0 +1,42 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: src/proto/grpc/testing/report_qps_scenario_service.proto for package 'grpc.testing'
+# Original file comments:
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
+
+require 'grpc'
+require 'src/proto/grpc/testing/report_qps_scenario_service_pb'
+
+module Grpc
+  module Testing
+    module ReportQpsScenarioService
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.ReportQpsScenarioService'
+
+        # Report results of a QPS test benchmark scenario.
+        rpc :ReportScenario, ScenarioResult, Void
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
index 41f75be..2069840 100644
--- a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
@@ -3,11 +3,16 @@
 
 require 'google/protobuf'
 
+require 'src/proto/grpc/core/stats_pb'
 Google::Protobuf::DescriptorPool.generated_pool.build do
   add_message "grpc.testing.ServerStats" do
     optional :time_elapsed, :double, 1
     optional :time_user, :double, 2
     optional :time_system, :double, 3
+    optional :total_cpu_time, :uint64, 4
+    optional :idle_cpu_time, :uint64, 5
+    optional :cq_poll_count, :uint64, 6
+    optional :core_stats, :message, 7, "grpc.core.Stats"
   end
   add_message "grpc.testing.HistogramParams" do
     optional :resolution, :double, 1
@@ -21,11 +26,18 @@
     optional :sum_of_squares, :double, 5
     optional :count, :double, 6
   end
+  add_message "grpc.testing.RequestResultCount" do
+    optional :status_code, :int32, 1
+    optional :count, :int64, 2
+  end
   add_message "grpc.testing.ClientStats" do
     optional :latencies, :message, 1, "grpc.testing.HistogramData"
     optional :time_elapsed, :double, 2
     optional :time_user, :double, 3
     optional :time_system, :double, 4
+    repeated :request_results, :message, 5, "grpc.testing.RequestResultCount"
+    optional :cq_poll_count, :uint64, 6
+    optional :core_stats, :message, 7, "grpc.core.Stats"
   end
 end
 
@@ -34,6 +46,7 @@
     ServerStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStats").msgclass
     HistogramParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramParams").msgclass
     HistogramData = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramData").msgclass
+    RequestResultCount = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.RequestResultCount").msgclass
     ClientStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStats").msgclass
   end
 end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
similarity index 71%
copy from src/ruby/qps/src/proto/grpc/testing/services_pb.rb
copy to src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
index 5ce13bf..18b6345 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb
@@ -1,9 +1,8 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: src/proto/grpc/testing/services.proto
+# source: src/proto/grpc/testing/worker_service.proto
 
 require 'google/protobuf'
 
-require 'src/proto/grpc/testing/messages_pb'
 require 'src/proto/grpc/testing/control_pb'
 Google::Protobuf::DescriptorPool.generated_pool.build do
 end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
similarity index 74%
rename from src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
rename to src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
index 1d8b619..a7ecc95 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_services_pb.rb
@@ -1,5 +1,5 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# Source: src/proto/grpc/testing/services.proto for package 'grpc.testing'
+# Source: src/proto/grpc/testing/worker_service.proto for package 'grpc.testing'
 # Original file comments:
 # Copyright 2015 gRPC authors.
 #
@@ -19,29 +19,10 @@
 # of unary/streaming requests/responses.
 
 require 'grpc'
-require 'src/proto/grpc/testing/services_pb'
+require 'src/proto/grpc/testing/worker_service_pb'
 
 module Grpc
   module Testing
-    module BenchmarkService
-      class Service
-
-        include GRPC::GenericService
-
-        self.marshal_class_method = :encode
-        self.unmarshal_class_method = :decode
-        self.service_name = 'grpc.testing.BenchmarkService'
-
-        # One request followed by one response.
-        # The server returns the client payload as-is.
-        rpc :UnaryCall, SimpleRequest, SimpleResponse
-        # One request followed by one response.
-        # The server returns the client payload as-is.
-        rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse)
-      end
-
-      Stub = Service.rpc_stub_class
-    end
     module WorkerService
       class Service
 
diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb
index 8258487..633ff13 100755
--- a/src/ruby/qps/worker.rb
+++ b/src/ruby/qps/worker.rb
@@ -29,7 +29,7 @@
 require 'client'
 require 'qps-common'
 require 'server'
-require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/worker_service_services_pb'
 
 class WorkerServiceImpl < Grpc::Testing::WorkerService::Service
   def cpu_cores
diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
index 5bc66e9..398b198 100755
--- a/templates/src/csharp/Grpc.Core/Version.csproj.include.template
+++ b/templates/src/csharp/Grpc.Core/Version.csproj.include.template
@@ -4,6 +4,6 @@
   <Project>
     <PropertyGroup>
       <GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion>
-      <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
+      <GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
     </PropertyGroup>
   </Project>
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc
index e3fba28..103b291 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_test.cc
@@ -70,11 +70,12 @@
 
   test_succeeds(dns, "dns:10.2.1.1");
   test_succeeds(dns, "dns:10.2.1.1:1234");
-  test_succeeds(dns, "ipv4:www.google.com");
+  test_succeeds(dns, "dns:www.google.com");
+  test_succeeds(dns, "dns:///www.google.com");
   if (grpc_resolve_address == grpc_resolve_address_ares) {
-    test_succeeds(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
+    test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888");
   } else {
-    test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888");
+    test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888");
   }
 
   {
diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc
index 2e398a7..c810345 100644
--- a/test/core/gprpp/ref_counted_ptr_test.cc
+++ b/test/core/gprpp/ref_counted_ptr_test.cc
@@ -88,7 +88,7 @@
 
 TEST(RefCountedPtr, CopyAssignmentToSelf) {
   RefCountedPtr<Foo> foo(New<Foo>());
-  foo = foo;
+  foo = *&foo;  // The "*&" avoids warnings from LLVM -Wself-assign.
 }
 
 TEST(RefCountedPtr, EnclosedScope) {
diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc
index 9788320..97e9c20 100644
--- a/test/core/handshake/readahead_handshaker_server_ssl.cc
+++ b/test/core/handshake/readahead_handshaker_server_ssl.cc
@@ -64,7 +64,7 @@
 
 const grpc_handshaker_vtable readahead_handshaker_vtable = {
     readahead_handshaker_destroy, readahead_handshaker_shutdown,
-    readahead_handshaker_do_handshake};
+    readahead_handshaker_do_handshake, "read_ahead"};
 
 static grpc_handshaker* readahead_handshaker_create() {
   grpc_handshaker* h =
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index f1abb19..a348b88 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -47,9 +47,10 @@
         "//:grpc",
         "//:grpc++",
         "//:grpc++_core_stats",
+        "//src/proto/grpc/testing:benchmark_service_proto",
         "//src/proto/grpc/testing:control_proto",
         "//src/proto/grpc/testing:payloads_proto",
-        "//src/proto/grpc/testing:services_proto",
+        "//src/proto/grpc/testing:worker_service_proto",
         "//test/core/end2end:ssl_test_data",
         "//test/core/util:gpr_test_util",
         "//test/core/util:grpc_test_util",
@@ -74,7 +75,8 @@
         "//:grpc++",
         "//src/proto/grpc/testing:control_proto",
         "//src/proto/grpc/testing:messages_proto",
-        "//src/proto/grpc/testing:services_proto",
+        "//src/proto/grpc/testing:report_qps_scenario_service_proto",
+        "//src/proto/grpc/testing:worker_service_proto",
         "//test/core/util:gpr_test_util",
         "//test/core/util:grpc_test_util",
         "//test/cpp/util:test_util",
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 77743a1..31ae6ca 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -31,8 +31,8 @@
 #include <grpcpp/support/channel_arguments.h>
 #include <grpcpp/support/slice.h>
 
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
 #include "src/proto/grpc/testing/payloads.pb.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
 
 #include "src/cpp/util/core_stats.h"
 #include "test/cpp/qps/histogram.h"
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index f9bef91..c79a10d 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -35,7 +35,7 @@
 #include <grpcpp/generic/generic_stub.h>
 
 #include "src/core/lib/surface/completion_queue.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/usage_timer.h"
 #include "test/cpp/util/create_test_channel.h"
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 5185eef..e65e3b4 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -35,7 +35,7 @@
 
 #include "src/core/lib/gpr/host_port.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/interarrival.h"
 #include "test/cpp/qps/usage_timer.h"
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 361ee43..34f1291 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -33,6 +33,7 @@
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/host_port.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/proto/grpc/testing/worker_service.grpc.pb.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/qps/client.h"
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index aaffb1d..d3f0380 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -35,7 +35,7 @@
 #include <grpcpp/server_builder.h>
 
 #include "src/core/lib/gpr/host_port.h"
-#include "src/proto/grpc/testing/services.pb.h"
+#include "src/proto/grpc/testing/worker_service.grpc.pb.h"
 #include "test/core/util/grpc_profiler.h"
 #include "test/core/util/histogram.h"
 #include "test/cpp/qps/client.h"
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 0a2565d..607f4e5 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -27,7 +27,7 @@
 
 #include <grpcpp/client_context.h>
 #include "src/cpp/util/core_stats.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index c5dd138..8e62f4f 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -28,7 +28,7 @@
 #include "test/cpp/qps/driver.h"
 
 #include <grpcpp/channel.h>
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 9cb05cd..1dfef6c 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -36,7 +36,7 @@
 
 #include "src/core/lib/gpr/host_port.h"
 #include "src/core/lib/surface/completion_queue.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/qps/server.h"
 
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 9dfd362..82a9186 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -26,7 +26,7 @@
 #include <grpcpp/server_context.h>
 
 #include "src/core/lib/gpr/host_port.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
 #include "test/cpp/qps/server.h"
 #include "test/cpp/qps/usage_timer.h"
 
diff --git a/third_party/protobuf b/third_party/protobuf
index 2761122..b5fbb74 160000
--- a/third_party/protobuf
+++ b/third_party/protobuf
@@ -1 +1 @@
-Subproject commit 2761122b810fe8861004ae785cc3ab39f384d342
+Subproject commit b5fbb742af122b565925987e65c08957739976a7
diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh
index bbacd48..307fe6c 100755
--- a/tools/distrib/pylint_code.sh
+++ b/tools/distrib/pylint_code.sh
@@ -25,6 +25,10 @@
     'src/python/grpcio_testing/grpc_testing'
 )
 
+TEST_DIRS=(
+    'src/python/grpcio_tests/tests'
+)
+
 VIRTUALENV=python_pylint_venv
 
 virtualenv $VIRTUALENV
@@ -36,4 +40,8 @@
   $PYTHON -m pylint --rcfile=.pylintrc -rn "$dir" || exit $?
 done
 
+for dir in "${TEST_DIRS[@]}"; do
+  $PYTHON -m pylint --rcfile=.pylintrc-tests -rn "$dir" || exit $?
+done
+
 exit 0
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 2c65fca..a0e1419 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -20,4 +20,4 @@
 CC_INCLUDE='third_party/protobuf/src'
 PROTO_INCLUDE='third_party/protobuf/src'
 
-PROTOBUF_SUBMODULE_VERSION="2761122b810fe8861004ae785cc3ab39f384d342"
+PROTOBUF_SUBMODULE_VERSION="b5fbb742af122b565925987e65c08957739976a7"
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index 7b4b234..730fe64 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -87,6 +87,9 @@
         {
             'v1.10.0': None
         },
+        {
+            'v1.11.0': None
+        },
     ],
     'go': [
         {
@@ -192,6 +195,9 @@
         {
             'v1.10.0': None
         },
+        {
+            'v1.11.0': None
+        },
     ],
     'node': [
         {
@@ -262,6 +268,9 @@
         {
             'v1.10.0': None
         },
+        {
+            'v1.11.0': None
+        },
     ],
     'php': [
         {
@@ -294,6 +303,9 @@
         {
             'v1.10.0': None
         },
+        {
+            'v1.11.0': None
+        },
     ],
     'csharp': [
         #{'v1.0.1': None},
@@ -324,6 +336,9 @@
         {
             'v1.10.0': None
         },
+        {
+            'v1.11.0': None
+        },
     ],
 }
 
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 8b13e76..1e4d401 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -3194,6 +3194,9 @@
       "grpc++_core_stats"
     ], 
     "headers": [
+      "src/proto/grpc/testing/benchmark_service.grpc.pb.h", 
+      "src/proto/grpc/testing/benchmark_service.pb.h", 
+      "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
       "src/proto/grpc/testing/control_mock.grpc.pb.h", 
@@ -3203,12 +3206,15 @@
       "src/proto/grpc/testing/payloads.grpc.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.pb.h", 
-      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
       "src/proto/grpc/testing/stats.pb.h", 
-      "src/proto/grpc/testing/stats_mock.grpc.pb.h"
+      "src/proto/grpc/testing/stats_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.pb.h", 
+      "src/proto/grpc/testing/worker_service_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -3228,6 +3234,9 @@
       "grpc++_core_stats"
     ], 
     "headers": [
+      "src/proto/grpc/testing/benchmark_service.grpc.pb.h", 
+      "src/proto/grpc/testing/benchmark_service.pb.h", 
+      "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
       "src/proto/grpc/testing/control_mock.grpc.pb.h", 
@@ -3237,12 +3246,15 @@
       "src/proto/grpc/testing/payloads.grpc.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.pb.h", 
-      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
       "src/proto/grpc/testing/stats.pb.h", 
-      "src/proto/grpc/testing/stats_mock.grpc.pb.h"
+      "src/proto/grpc/testing/stats_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.pb.h", 
+      "src/proto/grpc/testing/worker_service_mock.grpc.pb.h"
     ], 
     "is_filegroup": false, 
     "language": "c++", 
@@ -7451,6 +7463,9 @@
       "grpc_test_util"
     ], 
     "headers": [
+      "src/proto/grpc/testing/benchmark_service.grpc.pb.h", 
+      "src/proto/grpc/testing/benchmark_service.pb.h", 
+      "src/proto/grpc/testing/benchmark_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/control.grpc.pb.h", 
       "src/proto/grpc/testing/control.pb.h", 
       "src/proto/grpc/testing/control_mock.grpc.pb.h", 
@@ -7460,12 +7475,15 @@
       "src/proto/grpc/testing/payloads.grpc.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.pb.h", 
-      "src/proto/grpc/testing/services_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service.pb.h", 
+      "src/proto/grpc/testing/report_qps_scenario_service_mock.grpc.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
       "src/proto/grpc/testing/stats.pb.h", 
       "src/proto/grpc/testing/stats_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.grpc.pb.h", 
+      "src/proto/grpc/testing/worker_service.pb.h", 
+      "src/proto/grpc/testing/worker_service_mock.grpc.pb.h", 
       "test/cpp/qps/benchmark_config.h", 
       "test/cpp/qps/client.h", 
       "test/cpp/qps/driver.h", 
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index 0b5d331..bd95272 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -142,6 +142,11 @@
  true)
 VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
 
+# See https://github.com/grpc/grpc/issues/14815 for more context. We cannot rely
+# on pip to upgrade itself because if pip is too old, it may not have the required
+# TLS version to run `pip install`.
+curl https://bootstrap.pypa.io/get-pip.py | $VENV_PYTHON
+
 # pip-installs the directory specified. Used because on MSYS the vanilla Windows
 # Python gets confused when parsing paths.
 pip_install_dir() {
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index b22bbd6..723d185 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -31,7 +31,7 @@
  886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7)
  30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0)
  ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
- 2761122b810fe8861004ae785cc3ab39f384d342 third_party/protobuf (v3.5.0)
+ b5fbb742af122b565925987e65c08957739976a7 third_party/protobuf (v3.5.2)
  cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
  3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
  73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty