Merge pull request #10122 from ctiller/arena

Arena allocator for grpc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index faa7d52..180f416 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -607,6 +607,9 @@
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx bm_metadata)
 endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_pollset)
+endif()
 add_dependencies(buildtests_cxx channel_arguments_test)
 add_dependencies(buildtests_cxx channel_filter_test)
 add_dependencies(buildtests_cxx cli_call_test)
@@ -8083,6 +8086,45 @@
 endif()
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(bm_pollset
+  test/cpp/microbenchmarks/bm_pollset.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+
+target_include_directories(bm_pollset
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/include
+  PRIVATE third_party/googletest
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(bm_pollset
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_benchmark
+  benchmark
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
 add_executable(channel_arguments_test
   test/cpp/common/channel_arguments_test.cc
diff --git a/Makefile b/Makefile
index c620376..c39c0e7 100644
--- a/Makefile
+++ b/Makefile
@@ -1059,6 +1059,7 @@
 bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle
 bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong
 bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata
+bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset
 channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
 channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
 cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
@@ -1482,6 +1483,7 @@
   $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
   $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
   $(BINDIR)/$(CONFIG)/bm_metadata \
+  $(BINDIR)/$(CONFIG)/bm_pollset \
   $(BINDIR)/$(CONFIG)/channel_arguments_test \
   $(BINDIR)/$(CONFIG)/channel_filter_test \
   $(BINDIR)/$(CONFIG)/cli_call_test \
@@ -1598,6 +1600,7 @@
   $(BINDIR)/$(CONFIG)/bm_fullstack_trickle \
   $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \
   $(BINDIR)/$(CONFIG)/bm_metadata \
+  $(BINDIR)/$(CONFIG)/bm_pollset \
   $(BINDIR)/$(CONFIG)/channel_arguments_test \
   $(BINDIR)/$(CONFIG)/channel_filter_test \
   $(BINDIR)/$(CONFIG)/cli_call_test \
@@ -1952,6 +1955,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong || ( echo test bm_fullstack_unary_ping_pong failed ; exit 1 )
 	$(E) "[RUN]     Testing bm_metadata"
 	$(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 )
+	$(E) "[RUN]     Testing bm_pollset"
+	$(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_arguments_test"
 	$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_filter_test"
@@ -13154,6 +13159,49 @@
 endif
 
 
+BM_POLLSET_SRC = \
+    test/cpp/microbenchmarks/bm_pollset.cc \
+
+BM_POLLSET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_POLLSET_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/bm_pollset: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/bm_pollset: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(BM_POLLSET_OBJS:.o=.dep)
+endif
+endif
+
+
 CHANNEL_ARGUMENTS_TEST_SRC = \
     test/cpp/common/channel_arguments_test.cc \
 
diff --git a/build.yaml b/build.yaml
index e799928..d6b33ac 100644
--- a/build.yaml
+++ b/build.yaml
@@ -2599,6 +2599,8 @@
   - grpc
   - gpr_test_util
   - gpr
+  exclude_iomgrs:
+  - uv
   platforms:
   - mac
   - linux
@@ -3298,6 +3300,26 @@
   - mac
   - linux
   - posix
+- name: bm_pollset
+  build: test
+  language: c++
+  src:
+  - test/cpp/microbenchmarks/bm_pollset.cc
+  deps:
+  - grpc_benchmark
+  - benchmark
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  args:
+  - --benchmark_min_time=0
+  platforms:
+  - mac
+  - linux
+  - posix
 - name: channel_arguments_test
   gtest: true
   build: test
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 4841da8..242ce06 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -101,18 +101,20 @@
 // TODO(https://github.com/google/protobuf/issues/888):
 // Export `ModuleName` from protobuf's
 // `src/google/protobuf/compiler/python/python_generator.cc` file.
-grpc::string ModuleName(const grpc::string& filename) {
+grpc::string ModuleName(const grpc::string& filename,
+                        const grpc::string& import_prefix) {
   grpc::string basename = StripProto(filename);
   basename = StringReplace(basename, "-", "_");
   basename = StringReplace(basename, "/", ".");
-  return basename + "_pb2";
+  return import_prefix + basename + "_pb2";
 }
 
 // TODO(https://github.com/google/protobuf/issues/888):
 // Export `ModuleAlias` from protobuf's
 // `src/google/protobuf/compiler/python/python_generator.cc` file.
-grpc::string ModuleAlias(const grpc::string& filename) {
-  grpc::string module_name = ModuleName(filename);
+grpc::string ModuleAlias(const grpc::string& filename,
+                         const grpc::string& import_prefix) {
+  grpc::string module_name = ModuleName(filename, import_prefix);
   // We can't have dots in the module name, so we replace each with _dot_.
   // But that could lead to a collision between a.b and a_dot_b, so we also
   // duplicate each underscore.
@@ -189,7 +191,7 @@
   grpc::string generator_file_name = file->name();
   grpc::string module;
   if (generator_file_name != file_name || generate_in_pb2_grpc) {
-    module = ModuleAlias(file_name) + ".";
+    module = ModuleAlias(file_name, config.import_prefix) + ".";
   } else {
     module = "";
   }
@@ -666,8 +668,10 @@
         for (int k = 0; k < 2; ++k) {
           const Descriptor* type = types[k];
           grpc::string type_file_name = type->file()->name();
-          grpc::string module_name = ModuleName(type_file_name);
-          grpc::string module_alias = ModuleAlias(type_file_name);
+          grpc::string module_name =
+              ModuleName(type_file_name, config.import_prefix);
+          grpc::string module_alias =
+              ModuleAlias(type_file_name, config.import_prefix);
           imports_set.insert(std::make_tuple(module_name, module_alias));
         }
       }
@@ -766,7 +770,9 @@
 }  // namespace
 
 GeneratorConfiguration::GeneratorConfiguration()
-    : grpc_package_root("grpc"), beta_package_root("grpc.beta") {}
+    : grpc_package_root("grpc"),
+      beta_package_root("grpc.beta"),
+      import_prefix("") {}
 
 PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
     : config_(config) {}
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index 6a95255..b91059f 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -45,7 +45,10 @@
 struct GeneratorConfiguration {
   GeneratorConfiguration();
   grpc::string grpc_package_root;
+  // TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
   grpc::string beta_package_root;
+  // TODO(https://github.com/google/protobuf/issues/888): Drop this.
+  grpc::string import_prefix;
 };
 
 class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index bf64f84..f2475cf 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -71,7 +71,8 @@
  */
 
 typedef enum {
-  WAIT_FOR_READY_UNSET,
+  /* zero so it can be default initialized */
+  WAIT_FOR_READY_UNSET = 0,
   WAIT_FOR_READY_FALSE,
   WAIT_FOR_READY_TRUE
 } wait_for_ready_value;
@@ -631,7 +632,8 @@
 #define CANCELLED_CALL ((grpc_subchannel_call *)1)
 
 typedef enum {
-  GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
+  /* zero so that it can be default-initialized */
+  GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
   GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
 } subchannel_creation_phase;
 
@@ -653,7 +655,6 @@
   gpr_timespec call_start_time;
   gpr_timespec deadline;
   method_parameters *method_params;
-  grpc_closure read_service_config;
 
   grpc_error *cancel_error;
 
@@ -726,6 +727,47 @@
   gpr_free(ops);
 }
 
+// Sets calld->method_params.
+// If the method params specify a timeout, populates
+// *per_method_deadline and returns true.
+static bool set_call_method_params_from_service_config_locked(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    gpr_timespec *per_method_deadline) {
+  channel_data *chand = elem->channel_data;
+  call_data *calld = elem->call_data;
+  if (chand->method_params_table != NULL) {
+    calld->method_params = grpc_method_config_table_get(
+        exec_ctx, chand->method_params_table, calld->path);
+    if (calld->method_params != NULL) {
+      method_parameters_ref(calld->method_params);
+      if (gpr_time_cmp(calld->method_params->timeout,
+                       gpr_time_0(GPR_TIMESPAN)) != 0) {
+        *per_method_deadline =
+            gpr_time_add(calld->call_start_time, calld->method_params->timeout);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
+                                             grpc_call_element *elem) {
+  /* apply service-config level configuration to the call (now that we're
+   * certain it exists) */
+  call_data *calld = elem->call_data;
+  gpr_timespec per_method_deadline;
+  if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
+                                                        &per_method_deadline)) {
+    // If the deadline from the service config is shorter than the one
+    // from the client API, reset the deadline timer.
+    if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
+      calld->deadline = per_method_deadline;
+      grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
+    }
+  }
+}
+
 static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                     grpc_error *error) {
   grpc_call_element *elem = arg;
@@ -851,6 +893,7 @@
   }
   GPR_ASSERT(error == GRPC_ERROR_NONE);
   if (chand->lb_policy != NULL) {
+    apply_final_configuration_locked(exec_ctx, elem);
     grpc_lb_policy *lb_policy = chand->lb_policy;
     GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
     // If the application explicitly set wait_for_ready, use that.
@@ -1060,114 +1103,18 @@
   GPR_TIMER_END("cc_start_transport_stream_op", 0);
 }
 
-// Sets calld->method_params.
-// If the method params specify a timeout, populates
-// *per_method_deadline and returns true.
-static bool set_call_method_params_from_service_config_locked(
-    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-    gpr_timespec *per_method_deadline) {
-  channel_data *chand = elem->channel_data;
-  call_data *calld = elem->call_data;
-  if (chand->method_params_table != NULL) {
-    calld->method_params = grpc_method_config_table_get(
-        exec_ctx, chand->method_params_table, calld->path);
-    if (calld->method_params != NULL) {
-      method_parameters_ref(calld->method_params);
-      if (gpr_time_cmp(calld->method_params->timeout,
-                       gpr_time_0(GPR_TIMESPAN)) != 0) {
-        *per_method_deadline =
-            gpr_time_add(calld->call_start_time, calld->method_params->timeout);
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-// Gets data from the service config.  Invoked when the resolver returns
-// its initial result.
-static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg,
-                                       grpc_error *error) {
-  grpc_call_element *elem = arg;
-  call_data *calld = elem->call_data;
-  // If this is an error, there's no point in looking at the service config.
-  if (error == GRPC_ERROR_NONE) {
-    gpr_timespec per_method_deadline;
-    if (set_call_method_params_from_service_config_locked(
-            exec_ctx, elem, &per_method_deadline)) {
-      // If the deadline from the service config is shorter than the one
-      // from the client API, reset the deadline timer.
-      if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
-        calld->deadline = per_method_deadline;
-        grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
-      }
-    }
-  }
-  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
-}
-
-static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx,
-                                               void *arg,
-                                               grpc_error *error_ignored) {
-  grpc_call_element *elem = arg;
-  channel_data *chand = elem->channel_data;
-  call_data *calld = elem->call_data;
-  // If the resolver has already returned results, then we can access
-  // the service config parameters immediately.  Otherwise, we need to
-  // defer that work until the resolver returns an initial result.
-  if (chand->lb_policy != NULL) {
-    // We already have a resolver result, so check for service config.
-    gpr_timespec per_method_deadline;
-    if (set_call_method_params_from_service_config_locked(
-            exec_ctx, elem, &per_method_deadline)) {
-      calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
-    }
-  } else {
-    // We don't yet have a resolver result, so register a callback to
-    // get the service config data once the resolver returns.
-    // Take a reference to the call stack to be owned by the callback.
-    GRPC_CALL_STACK_REF(calld->owning_call, "read_service_config");
-    grpc_closure_init(&calld->read_service_config, read_service_config_locked,
-                      elem, grpc_combiner_scheduler(chand->combiner, false));
-    grpc_closure_list_append(&chand->waiting_for_config_closures,
-                             &calld->read_service_config, GRPC_ERROR_NONE);
-  }
-  // Start the deadline timer with the current deadline value.  If we
-  // do not yet have service config data, then the timer may be reset
-  // later.
-  grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
-  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
-                        "initial_read_service_config");
-}
-
 /* Constructor for call_data */
 static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      const grpc_call_element_args *args) {
-  channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
   // Initialize data members.
   grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
   calld->path = grpc_slice_ref_internal(args->path);
   calld->call_start_time = args->start_time;
   calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
-  calld->method_params = NULL;
-  calld->cancel_error = GRPC_ERROR_NONE;
-  gpr_atm_rel_store(&calld->subchannel_call, 0);
-  calld->connected_subchannel = NULL;
-  calld->waiting_ops = NULL;
-  calld->waiting_ops_count = 0;
-  calld->waiting_ops_capacity = 0;
-  calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   calld->owning_call = args->call_stack;
-  calld->pollent = NULL;
-  GRPC_CALL_STACK_REF(calld->owning_call, "initial_read_service_config");
-  grpc_closure_sched(
-      exec_ctx,
-      grpc_closure_init(&calld->read_service_config,
-                        initial_read_service_config_locked, elem,
-                        grpc_combiner_scheduler(chand->combiner, false)),
-      GRPC_ERROR_NONE);
+  grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/ext/client_channel/parse_address.c b/src/core/ext/client_channel/parse_address.c
index 8ae15fc..cd1b2cd 100644
--- a/src/core/ext/client_channel/parse_address.c
+++ b/src/core/ext/client_channel/parse_address.c
@@ -128,6 +128,7 @@
     GPR_ASSERT(host_end >= host);
     char host_without_scope[INET6_ADDRSTRLEN];
     size_t host_without_scope_len = (size_t)(host_end - host);
+    uint32_t sin6_scope_id = 0;
     strncpy(host_without_scope, host, host_without_scope_len);
     host_without_scope[host_without_scope_len] = '\0';
     if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) {
@@ -136,10 +137,12 @@
     }
     if (gpr_parse_bytes_to_uint32(host_end + 1,
                                   strlen(host) - host_without_scope_len - 1,
-                                  &in6->sin6_scope_id) == 0) {
+                                  &sin6_scope_id) == 0) {
       gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
       goto done;
     }
+    // Handle "sin6_scope_id" being type "u_long". See grpc issue ##10027.
+    in6->sin6_scope_id = sin6_scope_id;
   } else {
     if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
       gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index da4c7dc..a368453 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -511,6 +511,10 @@
                                    grpc_chttp2_transport *t,
                                    grpc_error *error) {
   if (!t->closed) {
+    if (!grpc_error_has_clear_grpc_status(error)) {
+      error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
+                                 GRPC_STATUS_UNAVAILABLE);
+    }
     if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) {
       if (t->close_transport_on_writes_finished == NULL) {
         t->close_transport_on_writes_finished =
@@ -520,10 +524,6 @@
           grpc_error_add_child(t->close_transport_on_writes_finished, error);
       return;
     }
-    if (!grpc_error_has_clear_grpc_status(error)) {
-      error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
-                                 GRPC_STATUS_UNAVAILABLE);
-    }
     t->closed = 1;
     connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN,
                            GRPC_ERROR_REF(error), "close_transport");
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.c b/src/core/ext/transport/chttp2/transport/frame_ping.c
index f487533..9b4b1a7 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.c
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.c
@@ -91,7 +91,7 @@
   grpc_chttp2_ping_parser *p = parser;
 
   while (p->byte != 8 && cur != end) {
-    p->opaque_8bytes |= (((uint64_t)*cur) << (8 * p->byte));
+    p->opaque_8bytes |= (((uint64_t)*cur) << (56 - 8 * p->byte));
     cur++;
     p->byte++;
   }
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 01a0353..fabfaf8 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -54,6 +54,7 @@
 #include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
 
 #define GRPC_HEADER_SIZE_IN_BYTES 5
+#define GRPC_FLUSH_READ_SIZE 4096
 
 #define CRONET_LOG(...)                          \
   do {                                           \
@@ -151,11 +152,17 @@
 struct op_state {
   bool state_op_done[OP_NUM_OPS];
   bool state_callback_received[OP_NUM_OPS];
+  /* A non-zero gRPC status code has been seen */
   bool fail_state;
+  /* Transport is discarding all buffered messages */
   bool flush_read;
   bool flush_cronet_when_ready;
   bool pending_write_for_trailer;
-  bool unprocessed_send_message;
+  bool pending_send_message;
+  /* User requested RECV_TRAILING_METADATA */
+  bool pending_recv_trailing_metadata;
+  /* Cronet has not issued a callback of a bidirectional read */
+  bool pending_read_from_cronet;
   grpc_error *cancel_error;
   /* data structure for storing data coming from server */
   struct read_state rs;
@@ -248,11 +255,35 @@
   return "UNKNOWN";
 }
 
-static void free_read_buffer(stream_obj *s) {
+static void null_and_maybe_free_read_buffer(stream_obj *s) {
   if (s->state.rs.read_buffer &&
       s->state.rs.read_buffer != s->state.rs.grpc_header_bytes) {
     gpr_free(s->state.rs.read_buffer);
-    s->state.rs.read_buffer = NULL;
+  }
+  s->state.rs.read_buffer = NULL;
+}
+
+static void maybe_flush_read(stream_obj *s) {
+  /* To enter flush read state (discarding all the buffered messages in
+   * transport layer), two conditions must be satisfied: 1) non-zero grpc status
+   * has been received, and 2) an op requesting the status code
+   * (RECV_TRAILING_METADATA) is issued by the user. (See
+   * doc/status_ordering.md) */
+  /* Whenever the evaluation of any of the two condition is changed, we check
+   * whether we should enter the flush read state. */
+  if (s->state.pending_recv_trailing_metadata && s->state.fail_state) {
+    if (!s->state.flush_read) {
+      CRONET_LOG(GPR_DEBUG, "%p: Flush read", s);
+      s->state.flush_read = true;
+      null_and_maybe_free_read_buffer(s);
+      s->state.rs.read_buffer = gpr_malloc(GRPC_FLUSH_READ_SIZE);
+      if (!s->state.pending_read_from_cronet) {
+        CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
+        bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
+                                  GRPC_FLUSH_READ_SIZE);
+        s->state.pending_read_from_cronet = true;
+      }
+    }
   }
 }
 
@@ -279,7 +310,11 @@
   storage->head = new_op;
   storage->num_pending_ops++;
   if (op->send_message) {
-    s->state.unprocessed_send_message = true;
+    s->state.pending_send_message = true;
+  }
+  if (op->recv_trailing_metadata) {
+    s->state.pending_recv_trailing_metadata = true;
+    maybe_flush_read(s);
   }
   CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op,
              storage->num_pending_ops);
@@ -367,7 +402,7 @@
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -390,7 +425,7 @@
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -405,7 +440,7 @@
   bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_SUCCEEDED] = true;
   s->cbs = NULL;
-  free_read_buffer(s);
+  null_and_maybe_free_read_buffer(s);
   gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
@@ -473,6 +508,7 @@
     CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
     bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
                               s->state.rs.remaining_bytes);
+    s->state.pending_read_from_cronet = true;
   }
   gpr_mu_unlock(&s->mu);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -504,10 +540,13 @@
   CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
              count);
   gpr_mu_lock(&s->mu);
+  s->state.pending_read_from_cronet = false;
   s->state.state_callback_received[OP_RECV_MESSAGE] = true;
   if (count > 0 && s->state.flush_read) {
     CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
-    bidirectional_stream_read(s->cbs, s->state.rs.read_buffer, 4096);
+    bidirectional_stream_read(s->cbs, s->state.rs.read_buffer,
+                              GRPC_FLUSH_READ_SIZE);
+    s->state.pending_read_from_cronet = true;
     gpr_mu_unlock(&s->mu);
   } else if (count > 0) {
     s->state.rs.received_bytes += count;
@@ -518,16 +557,14 @@
       bidirectional_stream_read(
           s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
           s->state.rs.remaining_bytes);
+      s->state.pending_read_from_cronet = true;
       gpr_mu_unlock(&s->mu);
     } else {
       gpr_mu_unlock(&s->mu);
       execute_from_storage(s);
     }
   } else {
-    if (s->state.flush_read) {
-      gpr_free(s->state.rs.read_buffer);
-      s->state.rs.read_buffer = NULL;
-    }
+    null_and_maybe_free_read_buffer(s);
     s->state.rs.read_stream_closed = true;
     gpr_mu_unlock(&s->mu);
     execute_from_storage(s);
@@ -564,6 +601,7 @@
     if (0 == strcmp(trailers->headers[i].key, "grpc-status") &&
         0 != strcmp(trailers->headers[i].value, "0")) {
       s->state.fail_state = true;
+      maybe_flush_read(s);
     }
   }
   s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
@@ -778,7 +816,7 @@
     else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
       result = false;
     /* we haven't sent message yet */
-    else if (stream_state->unprocessed_send_message &&
+    else if (stream_state->pending_send_message &&
              !stream_state->state_op_done[OP_SEND_MESSAGE])
       result = false;
     /* we haven't got on_write_completed for the send yet */
@@ -900,7 +938,7 @@
   } else if (stream_op->send_message &&
              op_can_be_run(stream_op, s, &oas->state, OP_SEND_MESSAGE)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_MESSAGE", oas);
-    stream_state->unprocessed_send_message = false;
+    stream_state->pending_send_message = false;
     if (stream_state->state_callback_received[OP_FAILED]) {
       result = NO_ACTION_POSSIBLE;
       CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
@@ -1009,6 +1047,13 @@
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
+    } else if (stream_state->flush_read) {
+      CRONET_LOG(GPR_DEBUG, "flush read");
+      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
+                         GRPC_ERROR_NONE);
+      stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+      oas->state.state_op_done[OP_RECV_MESSAGE] = true;
+      result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->rs.length_field_received == false) {
       if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES &&
           stream_state->rs.remaining_bytes == 0) {
@@ -1029,6 +1074,7 @@
               true; /* Indicates that at least one read request has been made */
           bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                     stream_state->rs.remaining_bytes);
+          stream_state->pending_read_from_cronet = true;
           result = ACTION_TAKEN_WITH_CALLBACK;
         } else {
           stream_state->rs.remaining_bytes = 0;
@@ -1047,11 +1093,13 @@
           stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
           stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
           stream_state->rs.received_bytes = 0;
+          stream_state->rs.length_field_received = false;
           CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
           stream_state->state_op_done[OP_READ_REQ_MADE] =
               true; /* Indicates that at least one read request has been made */
           bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                     stream_state->rs.remaining_bytes);
+          stream_state->pending_read_from_cronet = true;
           result = ACTION_TAKEN_NO_CALLBACK;
         }
       } else if (stream_state->rs.remaining_bytes == 0) {
@@ -1064,6 +1112,7 @@
             true; /* Indicates that at least one read request has been made */
         bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                   stream_state->rs.remaining_bytes);
+        stream_state->pending_read_from_cronet = true;
         result = ACTION_TAKEN_WITH_CALLBACK;
       } else {
         result = NO_ACTION_POSSIBLE;
@@ -1075,7 +1124,7 @@
       uint8_t *dst_p = GRPC_SLICE_START_PTR(read_data_slice);
       memcpy(dst_p, stream_state->rs.read_buffer,
              (size_t)stream_state->rs.length_field);
-      free_read_buffer(s);
+      null_and_maybe_free_read_buffer(s);
       grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer);
       grpc_slice_buffer_add(&stream_state->rs.read_slice_buffer,
                             read_data_slice);
@@ -1096,6 +1145,7 @@
       CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
       bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                 stream_state->rs.remaining_bytes);
+      stream_state->pending_read_from_cronet = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     }
   } else if (stream_op->recv_trailing_metadata &&
@@ -1153,15 +1203,6 @@
       make a note */
     if (stream_op->recv_message)
       stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true;
-  } else if (stream_state->fail_state && !stream_state->flush_read) {
-    CRONET_LOG(GPR_DEBUG, "running: %p  flush read", oas);
-    if (stream_state->rs.read_buffer &&
-        stream_state->rs.read_buffer != stream_state->rs.grpc_header_bytes) {
-      gpr_free(stream_state->rs.read_buffer);
-      stream_state->rs.read_buffer = NULL;
-    }
-    stream_state->rs.read_buffer = gpr_malloc(4096);
-    stream_state->flush_read = true;
   } else {
     result = NO_ACTION_POSSIBLE;
   }
@@ -1190,7 +1231,9 @@
   s->state.fail_state = s->state.flush_read = false;
   s->state.cancel_error = NULL;
   s->state.flush_cronet_when_ready = s->state.pending_write_for_trailer = false;
-  s->state.unprocessed_send_message = false;
+  s->state.pending_send_message = false;
+  s->state.pending_recv_trailing_metadata = false;
+  s->state.pending_read_from_cronet = false;
 
   s->curr_gs = gs;
   s->curr_ct = (grpc_cronet_transport *)gt;
@@ -1209,37 +1252,30 @@
 static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                               grpc_stream *gs, grpc_transport_stream_op *op) {
   CRONET_LOG(GPR_DEBUG, "perform_stream_op");
-  stream_obj *s = (stream_obj *)gs;
-  add_to_storage(s, op);
   if (op->send_initial_metadata &&
       header_has_authority(op->send_initial_metadata->list.head)) {
     /* Cronet does not support :authority header field. We cancel the call when
-       this field is present in metadata */
-    bidirectional_stream_header_array header_array;
-    bidirectional_stream_header *header;
-    bidirectional_stream cbs;
-    CRONET_LOG(GPR_DEBUG,
-               ":authority header is provided but not supported;"
-               " cancel operations");
-    /* Notify application that operation is cancelled by forging trailers */
-    header_array.count = 1;
-    header_array.capacity = 1;
-    header_array.headers = gpr_malloc(sizeof(bidirectional_stream_header));
-    header = (bidirectional_stream_header *)header_array.headers;
-    header->key = "grpc-status";
-    header->value = "1"; /* Return status GRPC_STATUS_CANCELLED */
-    cbs.annotation = (void *)s;
-    s->state.state_op_done[OP_CANCEL_ERROR] = true;
-    on_response_trailers_received(&cbs, &header_array);
-    gpr_free(header_array.headers);
-  } else {
-    execute_from_storage(s);
+     this field is present in metadata */
+    if (op->recv_initial_metadata_ready) {
+      grpc_closure_sched(exec_ctx, op->recv_initial_metadata_ready,
+                         GRPC_ERROR_CANCELLED);
+    }
+    if (op->recv_message_ready) {
+      grpc_closure_sched(exec_ctx, op->recv_message_ready,
+                         GRPC_ERROR_CANCELLED);
+    }
+    grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED);
+    return;
   }
+  stream_obj *s = (stream_obj *)gs;
+  add_to_storage(s, op);
+  execute_from_storage(s);
 }
 
 static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                            grpc_stream *gs, void *and_free_memory) {
   stream_obj *s = (stream_obj *)gs;
+  null_and_maybe_free_read_buffer(s);
   GRPC_ERROR_UNREF(s->state.cancel_error);
 }
 
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 7cdbe30..1127fff 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -140,14 +140,16 @@
                            const char *func) {
   if (grpc_error_is_special(err)) return err;
   gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
-          err->refs.count, err->refs.count + 1, file, line, func);
-  gpr_ref(&err->refs);
+          gpr_atm_no_barrier_load(&err->atomics.refs.count),
+          gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line,
+          func);
+  gpr_ref(&err->atomics.refs);
   return err;
 }
 #else
 grpc_error *grpc_error_ref(grpc_error *err) {
   if (grpc_error_is_special(err)) return err;
-  gpr_ref(&err->refs);
+  gpr_ref(&err->atomics.refs);
   return err;
 }
 #endif
@@ -182,7 +184,7 @@
   GPR_ASSERT(!grpc_error_is_special(err));
   unref_errs(err);
   unref_strs(err);
-  gpr_free((void *)gpr_atm_acq_load(&err->error_string));
+  gpr_free((void *)gpr_atm_acq_load(&err->atomics.error_string));
   gpr_free(err);
 }
 
@@ -191,15 +193,17 @@
                       const char *func) {
   if (grpc_error_is_special(err)) return;
   gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
-          err->refs.count, err->refs.count - 1, file, line, func);
-  if (gpr_unref(&err->refs)) {
+          gpr_atm_no_barrier_load(&err->atomics.refs.count),
+          gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line,
+          func);
+  if (gpr_unref(&err->atomics.refs)) {
     error_destroy(err);
   }
 }
 #else
 void grpc_error_unref(grpc_error *err) {
   if (grpc_error_is_special(err)) return;
-  if (gpr_unref(&err->refs)) {
+  if (gpr_unref(&err->atomics.refs)) {
     error_destroy(err);
   }
 }
@@ -328,8 +332,8 @@
 
   internal_set_time(&err, GRPC_ERROR_TIME_CREATED, gpr_now(GPR_CLOCK_REALTIME));
 
-  gpr_atm_no_barrier_store(&err->error_string, 0);
-  gpr_ref_init(&err->refs, 1);
+  gpr_atm_no_barrier_store(&err->atomics.error_string, 0);
+  gpr_ref_init(&err->atomics.refs, 1);
   GPR_TIMER_END("grpc_error_create", 0);
   return err;
 }
@@ -369,7 +373,7 @@
                        grpc_slice_from_static_string("cancelled"));
       internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
     }
-  } else if (gpr_ref_is_unique(&in->refs)) {
+  } else if (gpr_ref_is_unique(&in->atomics.refs)) {
     out = in;
   } else {
     uint8_t new_arena_capacity = in->arena_capacity;
@@ -382,10 +386,14 @@
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
     gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
 #endif
-    memcpy(out, in, sizeof(*in) + in->arena_size * sizeof(intptr_t));
+    // bulk memcpy of the rest of the struct.
+    size_t skip = sizeof(&out->atomics);
+    memcpy((void *)((uintptr_t)out + skip), (void *)((uintptr_t)in + skip),
+           sizeof(*in) + (in->arena_size * sizeof(intptr_t)) - skip);
+    // manually set the atomics and the new capacity
+    gpr_atm_no_barrier_store(&out->atomics.error_string, 0);
+    gpr_ref_init(&out->atomics.refs, 1);
     out->arena_capacity = new_arena_capacity;
-    gpr_atm_no_barrier_store(&out->error_string, 0);
-    gpr_ref_init(&out->refs, 1);
     ref_strs(out);
     ref_errs(out);
     GRPC_ERROR_UNREF(in);
@@ -692,7 +700,7 @@
   if (err == GRPC_ERROR_OOM) return oom_error_string;
   if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
 
-  void *p = (void *)gpr_atm_acq_load(&err->error_string);
+  void *p = (void *)gpr_atm_acq_load(&err->atomics.error_string);
   if (p != NULL) {
     GPR_TIMER_END("grpc_error_string", 0);
     return p;
@@ -712,9 +720,9 @@
 
   char *out = finish_kvs(&kvs);
 
-  if (!gpr_atm_rel_cas(&err->error_string, 0, (gpr_atm)out)) {
+  if (!gpr_atm_rel_cas(&err->atomics.error_string, 0, (gpr_atm)out)) {
     gpr_free(out);
-    out = (char *)gpr_atm_no_barrier_load(&err->error_string);
+    out = (char *)gpr_atm_no_barrier_load(&err->atomics.error_string);
   }
 
   GPR_TIMER_END("grpc_error_string", 0);
diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h
index fb4814e..7f204df 100644
--- a/src/core/lib/iomgr/error_internal.h
+++ b/src/core/lib/iomgr/error_internal.h
@@ -46,14 +46,25 @@
   uint8_t next;
 };
 
+// c core representation of an error. See error.h for high level description of
+// this object.
 struct grpc_error {
-  gpr_refcount refs;
+  // All atomics in grpc_error must be stored in this nested struct. The rest of
+  // the object is memcpy-ed in bulk in copy_and_unref.
+  struct atomics {
+    gpr_refcount refs;
+    gpr_atm error_string;
+  } atomics;
+  // These arrays index into dynamic arena at the bottom of the struct.
+  // UINT8_MAX is used as a sentinel value.
   uint8_t ints[GRPC_ERROR_INT_MAX];
   uint8_t strs[GRPC_ERROR_STR_MAX];
   uint8_t times[GRPC_ERROR_TIME_MAX];
+  // The child errors are stored in the arena, but are effectively a linked list
+  // structure, since they are contained withing grpc_linked_error objects.
   uint8_t first_err;
   uint8_t last_err;
-  gpr_atm error_string;
+  // The arena is dynamically reallocated with a grow factor of 1.5.
   uint8_t arena_size;
   uint8_t arena_capacity;
   intptr_t arena[0];
diff --git a/src/core/lib/iomgr/pollset_uv.c b/src/core/lib/iomgr/pollset_uv.c
index af33949..a2f81bc 100644
--- a/src/core/lib/iomgr/pollset_uv.c
+++ b/src/core/lib/iomgr/pollset_uv.c
@@ -39,6 +39,7 @@
 
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
@@ -61,25 +62,30 @@
    immediately in the next loop iteration.
    Note: In the future, if there is a bug that involves missing wakeups in the
    future, try adding a uv_async_t to kick the loop differently */
-uv_timer_t dummy_uv_handle;
+uv_timer_t *dummy_uv_handle;
 
 size_t grpc_pollset_size() { return sizeof(grpc_pollset); }
 
 void dummy_timer_cb(uv_timer_t *handle) {}
 
+void dummy_handle_close_cb(uv_handle_t *handle) { gpr_free(handle); }
+
 void grpc_pollset_global_init(void) {
   gpr_mu_init(&grpc_polling_mu);
-  uv_timer_init(uv_default_loop(), &dummy_uv_handle);
+  dummy_uv_handle = gpr_malloc(sizeof(uv_timer_t));
+  uv_timer_init(uv_default_loop(), dummy_uv_handle);
   grpc_pollset_work_run_loop = 1;
 }
 
-static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
-
 void grpc_pollset_global_shutdown(void) {
   gpr_mu_destroy(&grpc_polling_mu);
-  uv_close((uv_handle_t *)&dummy_uv_handle, timer_close_cb);
+  uv_close((uv_handle_t *)dummy_uv_handle, dummy_handle_close_cb);
 }
 
+static void timer_run_cb(uv_timer_t *timer) {}
+
+static void timer_close_cb(uv_handle_t *handle) { handle->data = (void *)1; }
+
 void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
   *mu = &grpc_polling_mu;
   uv_timer_init(uv_default_loop(), &pollset->timer);
@@ -95,7 +101,7 @@
     uv_run(uv_default_loop(), UV_RUN_NOWAIT);
   } else {
     // kick the loop once
-    uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0);
+    uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
   }
   grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
 }
@@ -111,8 +117,6 @@
   }
 }
 
-static void timer_run_cb(uv_timer_t *timer) {}
-
 grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                               grpc_pollset_worker **worker_hdl,
                               gpr_timespec now, gpr_timespec deadline) {
@@ -145,7 +149,7 @@
 
 grpc_error *grpc_pollset_kick(grpc_pollset *pollset,
                               grpc_pollset_worker *specific_worker) {
-  uv_timer_start(&dummy_uv_handle, dummy_timer_cb, 0, 0);
+  uv_timer_start(dummy_uv_handle, dummy_timer_cb, 0, 0);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c
index 79ff910..4d715be 100644
--- a/src/core/lib/iomgr/resolve_address_uv.c
+++ b/src/core/lib/iomgr/resolve_address_uv.c
@@ -40,6 +40,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/error.h"
@@ -54,8 +55,36 @@
   grpc_closure *on_done;
   grpc_resolved_addresses **addresses;
   struct addrinfo *hints;
+  char *host;
+  char *port;
 } request;
 
+static int retry_named_port_failure(int status, request *r,
+                                    uv_getaddrinfo_cb getaddrinfo_cb) {
+  if (status != 0) {
+    // This loop is copied from resolve_address_posix.c
+    char *svc[][2] = {{"http", "80"}, {"https", "443"}};
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
+      if (strcmp(r->port, svc[i][0]) == 0) {
+        int retry_status;
+        uv_getaddrinfo_t *req = gpr_malloc(sizeof(uv_getaddrinfo_t));
+        req->data = r;
+        retry_status = uv_getaddrinfo(uv_default_loop(), req, getaddrinfo_cb,
+                                      r->host, svc[i][1], r->hints);
+        if (retry_status < 0 || getaddrinfo_cb == NULL) {
+          // The callback will not be called
+          gpr_free(req);
+        }
+        return retry_status;
+      }
+    }
+  }
+  /* If this function calls uv_getaddrinfo, it will return that function's
+     return value. That function only returns numbers <=0, so we can safely
+     return 1 to indicate that we never retried */
+  return 1;
+}
+
 static grpc_error *handle_addrinfo_result(int status, struct addrinfo *result,
                                           grpc_resolved_addresses **addresses) {
   struct addrinfo *resp;
@@ -97,13 +126,21 @@
   request *r = (request *)req->data;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_error *error;
+  int retry_status;
+
+  gpr_free(req);
+  retry_status = retry_named_port_failure(status, r, getaddrinfo_callback);
+  if (retry_status == 0) {
+    // The request is being retried. Nothing should be done here
+    return;
+  }
+  /* Either no retry was attempted, or the retry failed. Either way, the
+     original error probably has more interesting information */
   error = handle_addrinfo_result(status, res, r->addresses);
   grpc_closure_sched(&exec_ctx, r->on_done, error);
   grpc_exec_ctx_finish(&exec_ctx);
-
   gpr_free(r->hints);
   gpr_free(r);
-  gpr_free(req);
   uv_freeaddrinfo(res);
 }
 
@@ -143,6 +180,7 @@
   uv_getaddrinfo_t req;
   int s;
   grpc_error *err;
+  int retry_status;
 
   req.addrinfo = NULL;
 
@@ -158,6 +196,12 @@
   hints.ai_flags = AI_PASSIVE;     /* for wildcard IP address */
 
   s = uv_getaddrinfo(uv_default_loop(), &req, NULL, host, port, &hints);
+  request r = {
+      .addresses = addresses, .hints = &hints, .host = host, .port = port};
+  retry_status = retry_named_port_failure(s, &r, NULL);
+  if (retry_status <= 0) {
+    s = retry_status;
+  }
   err = handle_addrinfo_result(s, req.addrinfo, addresses);
 
 done:
@@ -200,6 +244,8 @@
   r = gpr_malloc(sizeof(request));
   r->on_done = on_done;
   r->addresses = addrs;
+  r->host = host;
+  r->port = port;
   req = gpr_malloc(sizeof(uv_getaddrinfo_t));
   req->data = r;
 
@@ -222,6 +268,8 @@
     gpr_free(r);
     gpr_free(req);
     gpr_free(hints);
+    gpr_free(host);
+    gpr_free(port);
   }
 }
 
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index ae66577..618483d 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -76,7 +76,6 @@
     const char *str = grpc_error_string(error);
     gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s",
             connect->addr_name, str);
-    grpc_error_free_string(str);
   }
   if (error == GRPC_ERROR_NONE) {
     /* error == NONE implies that the timer ran out, and wasn't cancelled. If
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index d1bcd89..71e2957 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -109,8 +109,8 @@
   grpc_pollset **pollsets;
   /* number of pollsets in the pollsets array */
   size_t pollset_count;
-  /* The parent grpc server */
-  grpc_server *grpc_server;
+  /* opaque object to pass to callbacks */
+  void *user_data;
 };
 
 grpc_udp_server *grpc_udp_server_create(void) {
@@ -178,7 +178,7 @@
       /* Call the orphan_cb to signal that the FD is about to be closed and
        * should no longer be used. */
       GPR_ASSERT(sp->orphan_cb);
-      sp->orphan_cb(exec_ctx, sp->emfd);
+      sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data);
 
       grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
                      "udp_listener_shutdown");
@@ -204,7 +204,7 @@
   if (s->active_ports) {
     for (sp = s->head; sp; sp = sp->next) {
       GPR_ASSERT(sp->orphan_cb);
-      sp->orphan_cb(exec_ctx, sp->emfd);
+      sp->orphan_cb(exec_ctx, sp->emfd, sp->server->user_data);
       grpc_fd_shutdown(exec_ctx, sp->emfd,
                        GRPC_ERROR_CREATE("Server destroyed"));
     }
@@ -299,7 +299,7 @@
 
   /* Tell the registered callback that data is available to read. */
   GPR_ASSERT(sp->read_cb);
-  sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server);
+  sp->read_cb(exec_ctx, sp->emfd, sp->server->user_data);
 
   /* Re-arm the notification event so we get another chance to read. */
   grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
@@ -322,7 +322,7 @@
 
   /* Tell the registered callback that the socket is writeable. */
   GPR_ASSERT(sp->write_cb);
-  sp->write_cb(exec_ctx, sp->emfd);
+  sp->write_cb(exec_ctx, sp->emfd, sp->server->user_data);
 
   /* Re-arm the notification event so we get another chance to write. */
   grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
@@ -464,13 +464,13 @@
 
 void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
                            grpc_pollset **pollsets, size_t pollset_count,
-                           grpc_server *server) {
+                           void *user_data) {
   size_t i;
   gpr_mu_lock(&s->mu);
   grpc_udp_listener *sp;
   GPR_ASSERT(s->active_ports == 0);
   s->pollsets = pollsets;
-  s->grpc_server = server;
+  s->user_data = user_data;
 
   sp = s->head;
   while (sp != NULL) {
diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h
index ed63fa7..90842a4 100644
--- a/src/core/lib/iomgr/udp_server.h
+++ b/src/core/lib/iomgr/udp_server.h
@@ -47,23 +47,23 @@
 
 /* Called when data is available to read from the socket. */
 typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
-                                        struct grpc_server *server);
+                                        void *user_data);
 
 /* Called when the socket is writeable. */
-typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx,
-                                         grpc_fd *emfd);
+typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                                         void *user_data);
 
 /* Called when the grpc_fd is about to be orphaned (and the FD closed). */
 typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx,
-                                          grpc_fd *emfd);
+                                          grpc_fd *emfd, void *user_data);
 
 /* Create a server, initially not bound to any ports */
 grpc_udp_server *grpc_udp_server_create(void);
 
-/* Start listening to bound ports */
+/* Start listening to bound ports. user_data is passed to callbacks. */
 void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server,
                            grpc_pollset **pollsets, size_t pollset_count,
-                           struct grpc_server *server);
+                           void *user_data);
 
 int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index);
 
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 8a7eff5..a5a0ea2 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -728,7 +728,7 @@
  *     method implementation for the provided service.
  */
 Server.prototype.addService = function(service, implementation) {
-  if (!_.isObjectLike(service) || !_.isObjectLike(implementation)) {
+  if (!_.isObject(service) || !_.isObject(implementation)) {
     throw new Error('addService requires two objects as arguments');
   }
   if (_.keys(service).length === 0) {
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index 5584246..d964f53 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -90,6 +90,9 @@
   return nil;
 }
 
+// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
+// message. The number varies as different message.proto is used on different servers. The actual
+// number for each interop server is overridden in corresponding derived test classes.
 - (int32_t)encodingOverhead {
   return 0;
 }
@@ -169,8 +172,6 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
-#ifndef GRPC_COMPILE_WITH_CRONET
-// TODO (mxyan): Fix this test
 - (void)testResponsesOverMaxSizeFailWithActionableMessage {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"];
@@ -191,7 +192,6 @@
 
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
-#endif
 
 - (void)testResponsesOver4MBAreAcceptedIfOptedIn {
   XCTAssertNotNil(self.class.host);
@@ -327,8 +327,6 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
-#ifndef GRPC_COMPILE_WITH_CRONET
-// TODO(makdharma@): Fix this test
 - (void)testEmptyStreamRPC {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
@@ -342,7 +340,6 @@
   }];
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
-#endif
 
 - (void)testCancelAfterBeginRPC {
   XCTAssertNotNil(self.class.host);
diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m
index b41210f..4987660 100644
--- a/src/objective-c/tests/InteropTestsLocalCleartext.m
+++ b/src/objective-c/tests/InteropTestsLocalCleartext.m
@@ -37,6 +37,10 @@
 
 static NSString * const kLocalCleartextHost = @"localhost:5050";
 
+// The Protocol Buffers encoding overhead of local interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kLocalInteropServerOverhead = 10;
+
 /** Tests in InteropTests.m, sending the RPCs to a local cleartext server. */
 @interface InteropTestsLocalCleartext : InteropTests
 @end
@@ -48,7 +52,7 @@
 }
 
 - (int32_t)encodingOverhead {
-  return 10; // bytes
+  return kLocalInteropServerOverhead; // bytes
 }
 
 - (void)setUp {
diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m
index 1479c58..934d500 100644
--- a/src/objective-c/tests/InteropTestsLocalSSL.m
+++ b/src/objective-c/tests/InteropTestsLocalSSL.m
@@ -37,6 +37,10 @@
 
 static NSString * const kLocalSSLHost = @"localhost:5051";
 
+// The Protocol Buffers encoding overhead of local interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kLocalInteropServerOverhead = 10;
+
 /** Tests in InteropTests.m, sending the RPCs to a local SSL server. */
 @interface InteropTestsLocalSSL : InteropTests
 @end
@@ -48,7 +52,7 @@
 }
 
 - (int32_t)encodingOverhead {
-  return 10; // bytes
+  return kLocalInteropServerOverhead; // bytes
 }
 
 - (void)setUp {
diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m
index 70f8475..9fb30aa 100644
--- a/src/objective-c/tests/InteropTestsRemote.m
+++ b/src/objective-c/tests/InteropTestsRemote.m
@@ -37,6 +37,10 @@
 
 static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
 
+// The Protocol Buffers encoding overhead of remote interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kRemoteInteropServerOverhead = 12;
+
 /** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */
 @interface InteropTestsRemote : InteropTests
 @end
@@ -48,7 +52,7 @@
 }
 
 - (int32_t)encodingOverhead {
-  return 12; // bytes
+  return kRemoteInteropServerOverhead; // bytes
 }
 
 @end
diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
index fab8ad8..005bac0 100644
--- a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
+++ b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
@@ -37,6 +37,10 @@
 
 static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
 
+// The Protocol Buffers encoding overhead of remote interop server. Acquired
+// by experiment. Adjust this when server's proto file changes.
+static int32_t kRemoteInteropServerOverhead = 12;
+
 /** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */
 @interface InteropTestsRemoteWithCronet : InteropTests
 @end
@@ -47,4 +51,8 @@
   return kRemoteSSLHost;
 }
 
+- (int32_t)encodingOverhead {
+  return kRemoteInteropServerOverhead; // bytes
+}
+
 @end
diff --git a/src/php/tests/qps/client.php b/src/php/tests/qps/client.php
new file mode 100644
index 0000000..d9ca35b
--- /dev/null
+++ b/src/php/tests/qps/client.php
@@ -0,0 +1,166 @@
+<?php
+/*
+ *
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * PHP client for QPS testing works as follows:
+ * 1. Gets initiated by a call from a proxy that implements the worker service. The
+ *    argument to this client is the proxy connection information
+ * 2. Initiate an RPC to the proxy to get ClientConfig
+ * 3. Initiate a client-side telemetry RPC to the proxy
+ * 4. Parse the client config, which includes server target information and then start
+ *    a unary or streaming test as appropriate.
+ * 5. After each completed RPC, send its timing to the proxy. The proxy does all histogramming
+ * 6. Proxy will respond on the timing channel when it's time to complete. Our
+ *    next timing write will fail and we know that it's time to stop
+ * The above complex dance is since threading and async are not idiomatic and we
+ * shouldn't ever be waiting to read a mark
+ *
+ * This test only supports a single channel since threading/async is not idiomatic
+ * This test supports unary or streaming ping-pongs, as well as open-loop
+ * 
+ */
+
+require dirname(__FILE__).'/vendor/autoload.php';
+
+/**
+ * Assertion function that always exits with an error code if the assertion is
+ * falsy.
+ *
+ * @param $value Assertion value. Should be true.
+ * @param $error_message Message to display if the assertion is false
+ */
+function hardAssert($value, $error_message)
+{
+    if (!$value) {
+        echo $error_message."\n";
+        exit(1);
+    }
+}
+
+function hardAssertIfStatusOk($status)
+{
+    if ($status->code !== Grpc\STATUS_OK) {
+        echo "Call did not complete successfully. Status object:\n";
+        var_dump($status);
+        exit(1);
+    }
+}
+
+/* Start the actual client */
+
+function qps_client_main($proxy_address) {
+    echo "Initiating php client\n";
+
+    $proxystubopts = [];
+    $proxystubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
+    $proxystub = new Grpc\Testing\ProxyClientServiceClient($proxy_address, $proxystubopts);
+    list($config, $status) = $proxystub->GetConfig(new Grpc\Testing\Void())->wait();
+    hardAssertIfStatusOk($status);
+    hardAssert($config->getClientChannels() == 1, "Only 1 channel supported");
+    hardAssert($config->getOutstandingRpcsPerChannel() == 1, "Only 1 outstanding RPC supported");
+
+    echo "Got configuration from proxy, target is " . $config->getServerTargets()[0] . "\n";
+
+    $stubopts = [];
+    if ($config->getSecurityParams()) {
+        if ($config->getSecurityParams()->getUseTestCa()) {
+            $stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(
+                file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
+        } else {
+            $stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(null);
+        }
+        $override = $config->getSecurityParams()->getServerHostOverride();
+        if ($override) {
+            $stubopts['grpc.ssl_target_name_override'] = $override;
+            $stubopts['grpc.default_authority'] = $override;
+        }
+    } else {
+        $stubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
+    }
+    echo "Initiating php benchmarking client\n";
+
+    $stub = new Grpc\Testing\BenchmarkServiceClient(
+        $config->getServerTargets()[0], $stubopts);
+    $req = new Grpc\Testing\SimpleRequest();
+
+    $req->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
+    $req->setResponseSize($config->getPayloadConfig()->getSimpleParams()->getRespSize());
+    $payload = new Grpc\Testing\Payload();
+    $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
+    $payload->setBody(str_repeat("\0", $config->getPayloadConfig()->getSimpleParams()->getReqSize()));
+    $req->setPayload($payload);
+
+    /* TODO(stanley-cheung): Enable the following by removing the 0&& once protobuf
+     * properly supports oneof in PHP */
+    if (0 && $config->getLoadParams()->getLoad() == "poisson") {
+        $poisson = true;
+        $lamrecip = 1.0/($config->getLoadParams()->getPoisson()->getOfferedLoad());
+        $issue = microtime(true) + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+    } else {
+        $poisson = false;
+    }
+    $metric = new Grpc\Testing\ProxyStat;
+    $telemetry = $proxystub->ReportTime();
+    if ($config->getRpcType() == Grpc\Testing\RpcType::UNARY) {
+        while (1) {
+            if ($poisson) {
+                time_sleep_until($issue);
+                $issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+            }
+            $startreq = microtime(true);
+            list($resp,$status) = $stub->UnaryCall($req)->wait();
+            hardAssertIfStatusOk($status);
+            $metric->setLatency(microtime(true)-$startreq);
+            $telemetry->write($metric);
+        }
+    } else {
+        $stream = $stub->StreamingCall();
+        while (1) {
+            if ($poisson) {
+                time_sleep_until($issue);
+                $issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
+            }
+            $startreq = microtime(true);
+            $stream->write($req);
+            $resp = $stream->read();
+            $metric->setLatency(microtime(true)-$startreq);
+            $telemetry->write($metric);
+        }
+    }
+}
+
+ini_set('display_startup_errors', 1);
+ini_set('display_errors', 1);
+error_reporting(-1);
+qps_client_main($argv[1]);
diff --git a/src/php/tests/qps/composer.json b/src/php/tests/qps/composer.json
new file mode 100644
index 0000000..0fc8709
--- /dev/null
+++ b/src/php/tests/qps/composer.json
@@ -0,0 +1,11 @@
+{
+  "minimum-stability": "dev",
+  "require": {
+    "grpc/grpc": "dev-master"
+  },
+  "autoload": {
+    "psr-4": {
+      "": "generated_code/"
+    }
+  }
+}
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
new file mode 100644
index 0000000..efca18a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Control.php
@@ -0,0 +1,127 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Control
+{
+    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\Payloads::initOnce();
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0add170a247372632f70726f746f2f677270632f74657374696e672f636f" .
+            "6e74726f6c2e70726f746f120c677270632e74657374696e671a25737263" .
+            "2f70726f746f2f677270632f74657374696e672f7061796c6f6164732e70" .
+            "726f746f1a227372632f70726f746f2f677270632f74657374696e672f73" .
+            "746174732e70726f746f22250a0d506f6973736f6e506172616d7312140a" .
+            "0c6f6666657265645f6c6f616418012001280122120a10436c6f7365644c" .
+            "6f6f70506172616d73227b0a0a4c6f6164506172616d7312350a0b636c6f" .
+            "7365645f6c6f6f7018012001280b321e2e677270632e74657374696e672e" .
+            "436c6f7365644c6f6f70506172616d734800122e0a07706f6973736f6e18" .
+            "022001280b321b2e677270632e74657374696e672e506f6973736f6e5061" .
+            "72616d73480042060a046c6f616422430a0e536563757269747950617261" .
+            "6d7312130a0b7573655f746573745f6361180120012808121c0a14736572" .
+            "7665725f686f73745f6f76657272696465180220012809224d0a0a436861" .
+            "6e6e656c417267120c0a046e616d6518012001280912130a097374725f76" .
+            "616c7565180220012809480012130a09696e745f76616c75651803200128" .
+            "05480042070a0576616c756522a0040a0c436c69656e74436f6e66696712" .
+            "160a0e7365727665725f74617267657473180120032809122d0a0b636c69" .
+            "656e745f7479706518022001280e32182e677270632e74657374696e672e" .
+            "436c69656e745479706512350a0f73656375726974795f706172616d7318" .
+            "032001280b321c2e677270632e74657374696e672e536563757269747950" .
+            "6172616d7312240a1c6f75747374616e64696e675f727063735f7065725f" .
+            "6368616e6e656c18042001280512170a0f636c69656e745f6368616e6e65" .
+            "6c73180520012805121c0a146173796e635f636c69656e745f7468726561" .
+            "647318072001280512270a087270635f7479706518082001280e32152e67" .
+            "7270632e74657374696e672e52706354797065122d0a0b6c6f61645f7061" .
+            "72616d73180a2001280b32182e677270632e74657374696e672e4c6f6164" .
+            "506172616d7312330a0e7061796c6f61645f636f6e666967180b2001280b" .
+            "321b2e677270632e74657374696e672e5061796c6f6164436f6e66696712" .
+            "370a10686973746f6772616d5f706172616d73180c2001280b321d2e6772" .
+            "70632e74657374696e672e486973746f6772616d506172616d7312110a09" .
+            "636f72655f6c697374180d2003280512120a0a636f72655f6c696d697418" .
+            "0e2001280512180a106f746865725f636c69656e745f617069180f200128" .
+            "09122e0a0c6368616e6e656c5f6172677318102003280b32182e67727063" .
+            "2e74657374696e672e4368616e6e656c41726722380a0c436c69656e7453" .
+            "746174757312280a05737461747318012001280b32192e677270632e7465" .
+            "7374696e672e436c69656e74537461747322150a044d61726b120d0a0572" .
+            "6573657418012001280822680a0a436c69656e7441726773122b0a057365" .
+            "74757018012001280b321a2e677270632e74657374696e672e436c69656e" .
+            "74436f6e666967480012220a046d61726b18022001280b32122e67727063" .
+            "2e74657374696e672e4d61726b480042090a076172677479706522b4020a" .
+            "0c536572766572436f6e666967122d0a0b7365727665725f747970651801" .
+            "2001280e32182e677270632e74657374696e672e53657276657254797065" .
+            "12350a0f73656375726974795f706172616d7318022001280b321c2e6772" .
+            "70632e74657374696e672e5365637572697479506172616d73120c0a0470" .
+            "6f7274180420012805121c0a146173796e635f7365727665725f74687265" .
+            "61647318072001280512120a0a636f72655f6c696d697418082001280512" .
+            "330a0e7061796c6f61645f636f6e66696718092001280b321b2e67727063" .
+            "2e74657374696e672e5061796c6f6164436f6e66696712110a09636f7265" .
+            "5f6c697374180a2003280512180a106f746865725f7365727665725f6170" .
+            "69180b20012809121c0a137265736f757263655f71756f74615f73697a65" .
+            "18e9072001280522680a0a53657276657241726773122b0a057365747570" .
+            "18012001280b321a2e677270632e74657374696e672e536572766572436f" .
+            "6e666967480012220a046d61726b18022001280b32122e677270632e7465" .
+            "7374696e672e4d61726b480042090a076172677479706522550a0c536572" .
+            "76657253746174757312280a05737461747318012001280b32192e677270" .
+            "632e74657374696e672e5365727665725374617473120c0a04706f727418" .
+            "0220012805120d0a05636f726573180320012805220d0a0b436f72655265" .
+            "7175657374221d0a0c436f7265526573706f6e7365120d0a05636f726573" .
+            "18012001280522060a04566f696422fd010a085363656e6172696f120c0a" .
+            "046e616d6518012001280912310a0d636c69656e745f636f6e6669671802" .
+            "2001280b321a2e677270632e74657374696e672e436c69656e74436f6e66" .
+            "696712130a0b6e756d5f636c69656e747318032001280512310a0d736572" .
+            "7665725f636f6e66696718042001280b321a2e677270632e74657374696e" .
+            "672e536572766572436f6e66696712130a0b6e756d5f7365727665727318" .
+            "052001280512160a0e7761726d75705f7365636f6e647318062001280512" .
+            "190a1162656e63686d61726b5f7365636f6e647318072001280512200a18" .
+            "737061776e5f6c6f63616c5f776f726b65725f636f756e74180820012805" .
+            "22360a095363656e6172696f7312290a097363656e6172696f7318012003" .
+            "280b32162e677270632e74657374696e672e5363656e6172696f22f8020a" .
+            "155363656e6172696f526573756c7453756d6d617279120b0a0371707318" .
+            "0120012801121b0a137170735f7065725f7365727665725f636f72651802" .
+            "20012801121a0a127365727665725f73797374656d5f74696d6518032001" .
+            "280112180a107365727665725f757365725f74696d65180420012801121a" .
+            "0a12636c69656e745f73797374656d5f74696d6518052001280112180a10" .
+            "636c69656e745f757365725f74696d6518062001280112120a0a6c617465" .
+            "6e63795f353018072001280112120a0a6c6174656e63795f393018082001" .
+            "280112120a0a6c6174656e63795f393518092001280112120a0a6c617465" .
+            "6e63795f3939180a2001280112130a0b6c6174656e63795f393939180b20" .
+            "01280112180a107365727665725f6370755f7573616765180c2001280112" .
+            "260a1e7375636365737366756c5f72657175657374735f7065725f736563" .
+            "6f6e64180d2001280112220a1a6661696c65645f72657175657374735f70" .
+            "65725f7365636f6e64180e200128012283030a0e5363656e6172696f5265" .
+            "73756c7412280a087363656e6172696f18012001280b32162e677270632e" .
+            "74657374696e672e5363656e6172696f122e0a096c6174656e6369657318" .
+            "022001280b321b2e677270632e74657374696e672e486973746f6772616d" .
+            "44617461122f0a0c636c69656e745f737461747318032003280b32192e67" .
+            "7270632e74657374696e672e436c69656e745374617473122f0a0c736572" .
+            "7665725f737461747318042003280b32192e677270632e74657374696e67" .
+            "2e536572766572537461747312140a0c7365727665725f636f7265731805" .
+            "2003280512340a0773756d6d61727918062001280b32232e677270632e74" .
+            "657374696e672e5363656e6172696f526573756c7453756d6d6172791216" .
+            "0a0e636c69656e745f7375636365737318072003280812160a0e73657276" .
+            "65725f7375636365737318082003280812390a0f726571756573745f7265" .
+            "73756c747318092003280b32202e677270632e74657374696e672e526571" .
+            "75657374526573756c74436f756e742a410a0a436c69656e745479706512" .
+            "0f0a0b53594e435f434c49454e54100012100a0c4153594e435f434c4945" .
+            "4e54100112100a0c4f544845525f434c49454e5410022a5b0a0a53657276" .
+            "657254797065120f0a0b53594e435f534552564552100012100a0c415359" .
+            "4e435f534552564552100112180a144153594e435f47454e455249435f53" .
+            "4552564552100212100a0c4f544845525f53455256455210032a230a0752" .
+            "70635479706512090a05554e4152591000120d0a0953545245414d494e47" .
+            "1001620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php
new file mode 100644
index 0000000..c088002
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php
@@ -0,0 +1,69 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Messages
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0ad50a0a257372632f70726f746f2f677270632f74657374696e672f6d65" .
+            "7373616765732e70726f746f120c677270632e74657374696e67221a0a09" .
+            "426f6f6c56616c7565120d0a0576616c756518012001280822400a075061" .
+            "796c6f616412270a047479706518012001280e32192e677270632e746573" .
+            "74696e672e5061796c6f616454797065120c0a04626f647918022001280c" .
+            "222b0a0a4563686f537461747573120c0a04636f6465180120012805120f" .
+            "0a076d65737361676518022001280922ce020a0d53696d706c6552657175" .
+            "65737412300a0d726573706f6e73655f7479706518012001280e32192e67" .
+            "7270632e74657374696e672e5061796c6f61645479706512150a0d726573" .
+            "706f6e73655f73697a6518022001280512260a077061796c6f6164180320" .
+            "01280b32152e677270632e74657374696e672e5061796c6f616412150a0d" .
+            "66696c6c5f757365726e616d6518042001280812180a1066696c6c5f6f61" .
+            "7574685f73636f706518052001280812340a13726573706f6e73655f636f" .
+            "6d7072657373656418062001280b32172e677270632e74657374696e672e" .
+            "426f6f6c56616c756512310a0f726573706f6e73655f7374617475731807" .
+            "2001280b32182e677270632e74657374696e672e4563686f537461747573" .
+            "12320a116578706563745f636f6d7072657373656418082001280b32172e" .
+            "677270632e74657374696e672e426f6f6c56616c7565225f0a0e53696d70" .
+            "6c65526573706f6e736512260a077061796c6f616418012001280b32152e" .
+            "677270632e74657374696e672e5061796c6f616412100a08757365726e61" .
+            "6d6518022001280912130a0b6f617574685f73636f706518032001280922" .
+            "770a1953747265616d696e67496e70757443616c6c526571756573741226" .
+            "0a077061796c6f616418012001280b32152e677270632e74657374696e67" .
+            "2e5061796c6f616412320a116578706563745f636f6d7072657373656418" .
+            "022001280b32172e677270632e74657374696e672e426f6f6c56616c7565" .
+            "223d0a1a53747265616d696e67496e70757443616c6c526573706f6e7365" .
+            "121f0a17616767726567617465645f7061796c6f61645f73697a65180120" .
+            "01280522640a12526573706f6e7365506172616d6574657273120c0a0473" .
+            "697a6518012001280512130a0b696e74657276616c5f7573180220012805" .
+            "122b0a0a636f6d7072657373656418032001280b32172e677270632e7465" .
+            "7374696e672e426f6f6c56616c756522e8010a1a53747265616d696e674f" .
+            "757470757443616c6c5265717565737412300a0d726573706f6e73655f74" .
+            "79706518012001280e32192e677270632e74657374696e672e5061796c6f" .
+            "616454797065123d0a13726573706f6e73655f706172616d657465727318" .
+            "022003280b32202e677270632e74657374696e672e526573706f6e736550" .
+            "6172616d657465727312260a077061796c6f616418032001280b32152e67" .
+            "7270632e74657374696e672e5061796c6f616412310a0f726573706f6e73" .
+            "655f73746174757318072001280b32182e677270632e74657374696e672e" .
+            "4563686f53746174757322450a1b53747265616d696e674f757470757443" .
+            "616c6c526573706f6e736512260a077061796c6f616418012001280b3215" .
+            "2e677270632e74657374696e672e5061796c6f616422330a0f5265636f6e" .
+            "6e656374506172616d7312200a186d61785f7265636f6e6e6563745f6261" .
+            "636b6f66665f6d7318012001280522330a0d5265636f6e6e656374496e66" .
+            "6f120e0a0670617373656418012001280812120a0a6261636b6f66665f6d" .
+            "731802200328052a1f0a0b5061796c6f61645479706512100a0c434f4d50" .
+            "5245535341424c451000620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php
new file mode 100644
index 0000000..279fe00
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Payloads.php
@@ -0,0 +1,37 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Payloads
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0a93030a257372632f70726f746f2f677270632f74657374696e672f7061" .
+            "796c6f6164732e70726f746f120c677270632e74657374696e6722370a10" .
+            "42797465427566666572506172616d7312100a087265715f73697a651801" .
+            "2001280512110a09726573705f73697a6518022001280522380a1153696d" .
+            "706c6550726f746f506172616d7312100a087265715f73697a6518012001" .
+            "280512110a09726573705f73697a6518022001280522140a12436f6d706c" .
+            "657850726f746f506172616d7322ca010a0d5061796c6f6164436f6e6669" .
+            "6712380a0e627974656275665f706172616d7318012001280b321e2e6772" .
+            "70632e74657374696e672e42797465427566666572506172616d73480012" .
+            "380a0d73696d706c655f706172616d7318022001280b321f2e677270632e" .
+            "74657374696e672e53696d706c6550726f746f506172616d734800123a0a" .
+            "0e636f6d706c65785f706172616d7318032001280b32202e677270632e74" .
+            "657374696e672e436f6d706c657850726f746f506172616d73480042090a" .
+            "077061796c6f6164620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php
new file mode 100644
index 0000000..e35944e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/ProxyService.php
@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class ProxyService
+{
+    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(
+            "0a97020a2a7372632f70726f746f2f677270632f74657374696e672f7072" .
+            "6f78792d736572766963652e70726f746f120c677270632e74657374696e" .
+            "671a247372632f70726f746f2f677270632f74657374696e672f636f6e74" .
+            "726f6c2e70726f746f221c0a0950726f787953746174120f0a076c617465" .
+            "6e6379180120012801328e010a1250726f7879436c69656e745365727669" .
+            "6365123b0a09476574436f6e66696712122e677270632e74657374696e67" .
+            "2e566f69641a1a2e677270632e74657374696e672e436c69656e74436f6e" .
+            "666967123b0a0a5265706f727454696d6512172e677270632e7465737469" .
+            "6e672e50726f7879537461741a122e677270632e74657374696e672e566f" .
+            "69642801620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php
new file mode 100644
index 0000000..7a9439a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Services.php
@@ -0,0 +1,45 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/services.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Services
+{
+    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();
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0ad1040a257372632f70726f746f2f677270632f74657374696e672f7365" .
+            "7276696365732e70726f746f120c677270632e74657374696e671a257372" .
+            "632f70726f746f2f677270632f74657374696e672f6d657373616765732e" .
+            "70726f746f1a247372632f70726f746f2f677270632f74657374696e672f" .
+            "636f6e74726f6c2e70726f746f32aa010a1042656e63686d61726b536572" .
+            "7669636512460a09556e61727943616c6c121b2e677270632e7465737469" .
+            "6e672e53696d706c65526571756573741a1c2e677270632e74657374696e" .
+            "672e53696d706c65526573706f6e7365124e0a0d53747265616d696e6743" .
+            "616c6c121b2e677270632e74657374696e672e53696d706c655265717565" .
+            "73741a1c2e677270632e74657374696e672e53696d706c65526573706f6e" .
+            "7365280130013297020a0d576f726b65725365727669636512450a095275" .
+            "6e53657276657212182e677270632e74657374696e672e53657276657241" .
+            "7267731a1a2e677270632e74657374696e672e5365727665725374617475" .
+            "732801300112450a0952756e436c69656e7412182e677270632e74657374" .
+            "696e672e436c69656e74417267731a1a2e677270632e74657374696e672e" .
+            "436c69656e745374617475732801300112420a09436f7265436f756e7412" .
+            "192e677270632e74657374696e672e436f7265526571756573741a1a2e67" .
+            "7270632e74657374696e672e436f7265526573706f6e736512340a0a5175" .
+            "6974576f726b657212122e677270632e74657374696e672e566f69641a12" .
+            "2e677270632e74657374696e672e566f6964620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php
new file mode 100644
index 0000000..99c0000
--- /dev/null
+++ b/src/php/tests/qps/generated_code/GPBMetadata/Src/Proto/Grpc/Testing/Stats.php
@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace GPBMetadata\Src\Proto\Grpc\Testing;
+
+class Stats
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(hex2bin(
+            "0adf040a227372632f70726f746f2f677270632f74657374696e672f7374" .
+            "6174732e70726f746f120c677270632e74657374696e67227a0a0b536572" .
+            "766572537461747312140a0c74696d655f656c6170736564180120012801" .
+            "12110a0974696d655f7573657218022001280112130a0b74696d655f7379" .
+            "7374656d18032001280112160a0e746f74616c5f6370755f74696d651804" .
+            "2001280412150a0d69646c655f6370755f74696d65180520012804223b0a" .
+            "0f486973746f6772616d506172616d7312120a0a7265736f6c7574696f6e" .
+            "18012001280112140a0c6d61785f706f737369626c651802200128012277" .
+            "0a0d486973746f6772616d44617461120e0a066275636b65741801200328" .
+            "0d12100a086d696e5f7365656e18022001280112100a086d61785f736565" .
+            "6e180320012801120b0a0373756d18042001280112160a0e73756d5f6f66" .
+            "5f73717561726573180520012801120d0a05636f756e7418062001280122" .
+            "380a1252657175657374526573756c74436f756e7412130a0b7374617475" .
+            "735f636f6465180120012805120d0a05636f756e7418022001280322b601" .
+            "0a0b436c69656e745374617473122e0a096c6174656e6369657318012001" .
+            "280b321b2e677270632e74657374696e672e486973746f6772616d446174" .
+            "6112140a0c74696d655f656c617073656418022001280112110a0974696d" .
+            "655f7573657218032001280112130a0b74696d655f73797374656d180420" .
+            "01280112390a0f726571756573745f726573756c747318052003280b3220" .
+            "2e677270632e74657374696e672e52657175657374526573756c74436f75" .
+            "6e74620670726f746f33"
+        ));
+
+        static::$is_initialized = true;
+    }
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php
new file mode 100644
index 0000000..daf1780
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/BenchmarkServiceClient.php
@@ -0,0 +1,78 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+namespace Grpc\Testing {
+
+  class BenchmarkServiceClient 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 request followed by one response.
+     * The server returns the client payload as-is.
+     * @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.BenchmarkService/UnaryCall',
+      $argument,
+      ['\Grpc\Testing\SimpleResponse', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function StreamingCall($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.BenchmarkService/StreamingCall',
+      ['\Grpc\Testing\SimpleResponse','decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php b/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php
new file mode 100644
index 0000000..f0497ac
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/BoolValue.php
@@ -0,0 +1,62 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * TODO(dgq): Go back to using well-known types once
+ * https://github.com/grpc/grpc/issues/6980 has been fixed.
+ * import "google/protobuf/wrappers.proto";
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.BoolValue</code>
+ */
+class BoolValue extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    private $value = false;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * <pre>
+     * The bool value.
+     * </pre>
+     *
+     * <code>bool value = 1;</code>
+     */
+    public function setValue($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->value = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php
new file mode 100644
index 0000000..0057d38
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ByteBufferParams.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ByteBufferParams</code>
+ */
+class ByteBufferParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    private $req_size = 0;
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    private $resp_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function getReqSize()
+    {
+        return $this->req_size;
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function setReqSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->req_size = $var;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function getRespSize()
+    {
+        return $this->resp_size;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function setRespSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resp_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php b/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php
new file mode 100644
index 0000000..d2fe3ae
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ChannelArg.php
@@ -0,0 +1,84 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ChannelArg</code>
+ */
+class ChannelArg extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>string name = 1;</code>
+     */
+    private $name = '';
+    protected $value;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>string name = 1;</code>
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * <code>string name = 1;</code>
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+    }
+
+    /**
+     * <code>string str_value = 2;</code>
+     */
+    public function getStrValue()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>string str_value = 2;</code>
+     */
+    public function setStrValue($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->writeOneof(2, $var);
+    }
+
+    /**
+     * <code>int32 int_value = 3;</code>
+     */
+    public function getIntValue()
+    {
+        return $this->readOneof(3);
+    }
+
+    /**
+     * <code>int32 int_value = 3;</code>
+     */
+    public function setIntValue($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->writeOneof(3, $var);
+    }
+
+    public function getValue()
+    {
+        return $this->whichOneof("value");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php
new file mode 100644
index 0000000..c878c5a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientArgs.php
@@ -0,0 +1,63 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientArgs</code>
+ */
+class ClientArgs extends \Google\Protobuf\Internal\Message
+{
+    protected $argtype;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClientConfig setup = 1;</code>
+     */
+    public function getSetup()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ClientConfig setup = 1;</code>
+     */
+    public function setSetup(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientConfig::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function getMark()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function setMark(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Mark::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getArgtype()
+    {
+        return $this->whichOneof("argtype");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
new file mode 100644
index 0000000..52d6a75
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientConfig.php
@@ -0,0 +1,407 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientConfig</code>
+ */
+class ClientConfig extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    private $server_targets;
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    private $client_type = 0;
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    private $security_params = null;
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    private $outstanding_rpcs_per_channel = 0;
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    private $client_channels = 0;
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    private $async_client_threads = 0;
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    private $rpc_type = 0;
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    private $load_params = null;
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    private $payload_config = null;
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    private $histogram_params = null;
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    private $core_list;
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    private $core_limit = 0;
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    private $other_client_api = '';
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    private $channel_args;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    public function getServerTargets()
+    {
+        return $this->server_targets;
+    }
+
+    /**
+     * <pre>
+     * List of targets to connect to. At least one target needs to be specified.
+     * </pre>
+     *
+     * <code>repeated string server_targets = 1;</code>
+     */
+    public function setServerTargets(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+        $this->server_targets = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    public function getClientType()
+    {
+        return $this->client_type;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientType client_type = 2;</code>
+     */
+    public function setClientType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\ClientType::class);
+        $this->client_type = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    public function getSecurityParams()
+    {
+        return $this->security_params;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 3;</code>
+     */
+    public function setSecurityParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SecurityParams::class);
+        $this->security_params = $var;
+    }
+
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    public function getOutstandingRpcsPerChannel()
+    {
+        return $this->outstanding_rpcs_per_channel;
+    }
+
+    /**
+     * <pre>
+     * How many concurrent RPCs to start for each channel.
+     * For synchronous client, use a separate thread for each outstanding RPC.
+     * </pre>
+     *
+     * <code>int32 outstanding_rpcs_per_channel = 4;</code>
+     */
+    public function setOutstandingRpcsPerChannel($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->outstanding_rpcs_per_channel = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    public function getClientChannels()
+    {
+        return $this->client_channels;
+    }
+
+    /**
+     * <pre>
+     * Number of independent client channels to create.
+     * i-th channel will connect to server_target[i % server_targets.size()]
+     * </pre>
+     *
+     * <code>int32 client_channels = 5;</code>
+     */
+    public function setClientChannels($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->client_channels = $var;
+    }
+
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    public function getAsyncClientThreads()
+    {
+        return $this->async_client_threads;
+    }
+
+    /**
+     * <pre>
+     * Only for async client. Number of threads to use to start/manage RPCs.
+     * </pre>
+     *
+     * <code>int32 async_client_threads = 7;</code>
+     */
+    public function setAsyncClientThreads($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->async_client_threads = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    public function getRpcType()
+    {
+        return $this->rpc_type;
+    }
+
+    /**
+     * <code>.grpc.testing.RpcType rpc_type = 8;</code>
+     */
+    public function setRpcType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\RpcType::class);
+        $this->rpc_type = $var;
+    }
+
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    public function getLoadParams()
+    {
+        return $this->load_params;
+    }
+
+    /**
+     * <pre>
+     * The requested load for the entire client (aggregated over all the threads).
+     * </pre>
+     *
+     * <code>.grpc.testing.LoadParams load_params = 10;</code>
+     */
+    public function setLoadParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\LoadParams::class);
+        $this->load_params = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    public function getPayloadConfig()
+    {
+        return $this->payload_config;
+    }
+
+    /**
+     * <code>.grpc.testing.PayloadConfig payload_config = 11;</code>
+     */
+    public function setPayloadConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PayloadConfig::class);
+        $this->payload_config = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    public function getHistogramParams()
+    {
+        return $this->histogram_params;
+    }
+
+    /**
+     * <code>.grpc.testing.HistogramParams histogram_params = 12;</code>
+     */
+    public function setHistogramParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramParams::class);
+        $this->histogram_params = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    public function getCoreList()
+    {
+        return $this->core_list;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the client on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 13;</code>
+     */
+    public function setCoreList(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->core_list = $var;
+    }
+
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    public function getCoreLimit()
+    {
+        return $this->core_limit;
+    }
+
+    /**
+     * <code>int32 core_limit = 14;</code>
+     */
+    public function setCoreLimit($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->core_limit = $var;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    public function getOtherClientApi()
+    {
+        return $this->other_client_api;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_CLIENT client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_client_api = 15;</code>
+     */
+    public function setOtherClientApi($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->other_client_api = $var;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    public function getChannelArgs()
+    {
+        return $this->channel_args;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.ChannelArg channel_args = 16;</code>
+     */
+    public function setChannelArgs(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ChannelArg::class);
+        $this->channel_args = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php
new file mode 100644
index 0000000..8b9a0c3
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStats.php
@@ -0,0 +1,164 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientStats</code>
+ */
+class ClientStats extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    private $latencies = null;
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    private $time_elapsed = 0.0;
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    private $time_user = 0.0;
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    private $time_system = 0.0;
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    private $request_results;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    public function getLatencies()
+    {
+        return $this->latencies;
+    }
+
+    /**
+     * <pre>
+     * Latency histogram. Data points are in nanoseconds.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 1;</code>
+     */
+    public function setLatencies(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramData::class);
+        $this->latencies = $var;
+    }
+
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    public function getTimeElapsed()
+    {
+        return $this->time_elapsed;
+    }
+
+    /**
+     * <pre>
+     * See ServerStats for details.
+     * </pre>
+     *
+     * <code>double time_elapsed = 2;</code>
+     */
+    public function setTimeElapsed($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_elapsed = $var;
+    }
+
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    public function getTimeUser()
+    {
+        return $this->time_user;
+    }
+
+    /**
+     * <code>double time_user = 3;</code>
+     */
+    public function setTimeUser($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_user = $var;
+    }
+
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    public function getTimeSystem()
+    {
+        return $this->time_system;
+    }
+
+    /**
+     * <code>double time_system = 4;</code>
+     */
+    public function setTimeSystem($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_system = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    public function getRequestResults()
+    {
+        return $this->request_results;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 5;</code>
+     */
+    public function setRequestResults(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\RequestResultCount::class);
+        $this->request_results = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php
new file mode 100644
index 0000000..a59f87a
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientStatus.php
@@ -0,0 +1,44 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ClientStatus</code>
+ */
+class ClientStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    private $stats = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    public function getStats()
+    {
+        return $this->stats;
+    }
+
+    /**
+     * <code>.grpc.testing.ClientStats stats = 1;</code>
+     */
+    public function setStats(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientStats::class);
+        $this->stats = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php
new file mode 100644
index 0000000..4f59da9
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClientType.php
@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.ClientType</code>
+ */
+class ClientType
+{
+    /**
+     * <pre>
+     * Many languages support a basic distinction between using
+     * sync or async client, and this allows the specification
+     * </pre>
+     *
+     * <code>SYNC_CLIENT = 0;</code>
+     */
+    const SYNC_CLIENT = 0;
+    /**
+     * <code>ASYNC_CLIENT = 1;</code>
+     */
+    const ASYNC_CLIENT = 1;
+    /**
+     * <pre>
+     * used for some language-specific variants
+     * </pre>
+     *
+     * <code>OTHER_CLIENT = 2;</code>
+     */
+    const OTHER_CLIENT = 2;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php
new file mode 100644
index 0000000..53f2948
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ClosedLoopParams.php
@@ -0,0 +1,28 @@
+<?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;
+
+/**
+ * <pre>
+ * Once an RPC finishes, immediately start a new one.
+ * No configuration parameters needed.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ClosedLoopParams</code>
+ */
+class ClosedLoopParams 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/ComplexProtoParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ComplexProtoParams.php
new file mode 100644
index 0000000..6d990f1
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ComplexProtoParams.php
@@ -0,0 +1,28 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * TODO (vpai): Fill this in once the details of complex, representative
+ *              protos are decided
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ComplexProtoParams</code>
+ */
+class ComplexProtoParams extends \Google\Protobuf\Internal\Message
+{
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.php
new file mode 100644
index 0000000..2e078b3
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/CoreRequest.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;
+
+/**
+ * Protobuf type <code>grpc.testing.CoreRequest</code>
+ */
+class CoreRequest 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/CoreResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/CoreResponse.php
new file mode 100644
index 0000000..85cb341
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/CoreResponse.php
@@ -0,0 +1,56 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.CoreResponse</code>
+ */
+class CoreResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    private $cores = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    public function getCores()
+    {
+        return $this->cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available on the server
+     * </pre>
+     *
+     * <code>int32 cores = 1;</code>
+     */
+    public function setCores($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->cores = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php
new file mode 100644
index 0000000..27340fb
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/EchoStatus.php
@@ -0,0 +1,70 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A protobuf representation for grpc status. This is used by test
+ * clients to specify a status that the server should attempt to return.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.EchoStatus</code>
+ */
+class EchoStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    private $code = 0;
+    /**
+     * <code>string message = 2;</code>
+     */
+    private $message = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    public function getCode()
+    {
+        return $this->code;
+    }
+
+    /**
+     * <code>int32 code = 1;</code>
+     */
+    public function setCode($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->code = $var;
+    }
+
+    /**
+     * <code>string message = 2;</code>
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * <code>string message = 2;</code>
+     */
+    public function setMessage($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->message = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php
new file mode 100644
index 0000000..056da6e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramData.php
@@ -0,0 +1,153 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Histogram data based on grpc/support/histogram.c
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.HistogramData</code>
+ */
+class HistogramData extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    private $bucket;
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    private $min_seen = 0.0;
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    private $max_seen = 0.0;
+    /**
+     * <code>double sum = 4;</code>
+     */
+    private $sum = 0.0;
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    private $sum_of_squares = 0.0;
+    /**
+     * <code>double count = 6;</code>
+     */
+    private $count = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    public function getBucket()
+    {
+        return $this->bucket;
+    }
+
+    /**
+     * <code>repeated uint32 bucket = 1;</code>
+     */
+    public function setBucket(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::UINT32);
+        $this->bucket = $var;
+    }
+
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    public function getMinSeen()
+    {
+        return $this->min_seen;
+    }
+
+    /**
+     * <code>double min_seen = 2;</code>
+     */
+    public function setMinSeen($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->min_seen = $var;
+    }
+
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    public function getMaxSeen()
+    {
+        return $this->max_seen;
+    }
+
+    /**
+     * <code>double max_seen = 3;</code>
+     */
+    public function setMaxSeen($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->max_seen = $var;
+    }
+
+    /**
+     * <code>double sum = 4;</code>
+     */
+    public function getSum()
+    {
+        return $this->sum;
+    }
+
+    /**
+     * <code>double sum = 4;</code>
+     */
+    public function setSum($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->sum = $var;
+    }
+
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    public function getSumOfSquares()
+    {
+        return $this->sum_of_squares;
+    }
+
+    /**
+     * <code>double sum_of_squares = 5;</code>
+     */
+    public function setSumOfSquares($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->sum_of_squares = $var;
+    }
+
+    /**
+     * <code>double count = 6;</code>
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+
+    /**
+     * <code>double count = 6;</code>
+     */
+    public function setCount($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php
new file mode 100644
index 0000000..836c94b
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/HistogramParams.php
@@ -0,0 +1,93 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Histogram params based on grpc/support/histogram.c
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.HistogramParams</code>
+ */
+class HistogramParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    private $resolution = 0.0;
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    private $max_possible = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    public function getResolution()
+    {
+        return $this->resolution;
+    }
+
+    /**
+     * <pre>
+     * first bucket is [0, 1 + resolution)
+     * </pre>
+     *
+     * <code>double resolution = 1;</code>
+     */
+    public function setResolution($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->resolution = $var;
+    }
+
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    public function getMaxPossible()
+    {
+        return $this->max_possible;
+    }
+
+    /**
+     * <pre>
+     * use enough buckets to allow this value
+     * </pre>
+     *
+     * <code>double max_possible = 2;</code>
+     */
+    public function setMaxPossible($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->max_possible = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php
new file mode 100644
index 0000000..1f32e49
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/LoadParams.php
@@ -0,0 +1,63 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.LoadParams</code>
+ */
+class LoadParams extends \Google\Protobuf\Internal\Message
+{
+    protected $load;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ClosedLoopParams closed_loop = 1;</code>
+     */
+    public function getClosedLoop()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ClosedLoopParams closed_loop = 1;</code>
+     */
+    public function setClosedLoop(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClosedLoopParams::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.PoissonParams poisson = 2;</code>
+     */
+    public function getPoisson()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.PoissonParams poisson = 2;</code>
+     */
+    public function setPoisson(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PoissonParams::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getLoad()
+    {
+        return $this->whichOneof("load");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php b/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php
new file mode 100644
index 0000000..ce006ef
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Mark.php
@@ -0,0 +1,60 @@
+<?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;
+
+/**
+ * <pre>
+ * Request current stats
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Mark</code>
+ */
+class Mark extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    private $reset = false;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    public function getReset()
+    {
+        return $this->reset;
+    }
+
+    /**
+     * <pre>
+     * if true, the stats will be reset after taking their snapshot.
+     * </pre>
+     *
+     * <code>bool reset = 1;</code>
+     */
+    public function setReset($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->reset = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php b/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php
new file mode 100644
index 0000000..d17c271
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Payload.php
@@ -0,0 +1,96 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * A block of data, to simply increase gRPC message size.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Payload</code>
+ */
+class Payload extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    private $type = 0;
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    private $body = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * The type of data in body.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType type = 1;</code>
+     */
+    public function setType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->type = $var;
+    }
+
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    public function getBody()
+    {
+        return $this->body;
+    }
+
+    /**
+     * <pre>
+     * Primary contents of payload.
+     * </pre>
+     *
+     * <code>bytes body = 2;</code>
+     */
+    public function setBody($var)
+    {
+        GPBUtil::checkString($var, False);
+        $this->body = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php
new file mode 100644
index 0000000..a2fe710
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadConfig.php
@@ -0,0 +1,80 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.PayloadConfig</code>
+ */
+class PayloadConfig extends \Google\Protobuf\Internal\Message
+{
+    protected $payload;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ByteBufferParams bytebuf_params = 1;</code>
+     */
+    public function getBytebufParams()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ByteBufferParams bytebuf_params = 1;</code>
+     */
+    public function setBytebufParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ByteBufferParams::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.SimpleProtoParams simple_params = 2;</code>
+     */
+    public function getSimpleParams()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.SimpleProtoParams simple_params = 2;</code>
+     */
+    public function setSimpleParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SimpleProtoParams::class);
+        $this->writeOneof(2, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.ComplexProtoParams complex_params = 3;</code>
+     */
+    public function getComplexParams()
+    {
+        return $this->readOneof(3);
+    }
+
+    /**
+     * <code>.grpc.testing.ComplexProtoParams complex_params = 3;</code>
+     */
+    public function setComplexParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ComplexProtoParams::class);
+        $this->writeOneof(3, $var);
+    }
+
+    public function getPayload()
+    {
+        return $this->whichOneof("payload");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php
new file mode 100644
index 0000000..189ef03
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PayloadType.php
@@ -0,0 +1,26 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+/**
+ * <pre>
+ * DEPRECATED, don't use. To be removed shortly.
+ * The type of payload that should be returned.
+ * </pre>
+ *
+ * Protobuf enum <code>grpc.testing.PayloadType</code>
+ */
+class PayloadType
+{
+    /**
+     * <pre>
+     * Compressable text format.
+     * </pre>
+     *
+     * <code>COMPRESSABLE = 0;</code>
+     */
+    const COMPRESSABLE = 0;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php
new file mode 100644
index 0000000..d64edd4
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/PoissonParams.php
@@ -0,0 +1,61 @@
+<?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;
+
+/**
+ * <pre>
+ * Parameters of poisson process distribution, which is a good representation
+ * of activity coming in from independent identical stationary sources.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.PoissonParams</code>
+ */
+class PoissonParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    private $offered_load = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    public function getOfferedLoad()
+    {
+        return $this->offered_load;
+    }
+
+    /**
+     * <pre>
+     * The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+     * </pre>
+     *
+     * <code>double offered_load = 1;</code>
+     */
+    public function setOfferedLoad($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->offered_load = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
new file mode 100644
index 0000000..23c041b
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyClientServiceClient.php
@@ -0,0 +1,72 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2017, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+namespace Grpc\Testing {
+
+  class ProxyClientServiceClient 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\Void $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function GetConfig(\Grpc\Testing\Void $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.ProxyClientService/GetConfig',
+      $argument,
+      ['\Grpc\Testing\ClientConfig', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function ReportTime($metadata = [], $options = []) {
+      return $this->_clientStreamRequest('/grpc.testing.ProxyClientService/ReportTime',
+      ['\Grpc\Testing\Void','decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php
new file mode 100644
index 0000000..ed43be9
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ProxyStat.php
@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ProxyStat</code>
+ */
+class ProxyStat extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>double latency = 1;</code>
+     */
+    private $latency = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\ProxyService::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>double latency = 1;</code>
+     */
+    public function getLatency()
+    {
+        return $this->latency;
+    }
+
+    /**
+     * <code>double latency = 1;</code>
+     */
+    public function setLatency($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php
new file mode 100644
index 0000000..dfaaa60
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectInfo.php
@@ -0,0 +1,71 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * For reconnect interop test only.
+ * Server tells client whether its reconnects are following the spec and the
+ * reconnect backoffs it saw.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ReconnectInfo</code>
+ */
+class ReconnectInfo extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    private $passed = false;
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    private $backoff_ms;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    public function getPassed()
+    {
+        return $this->passed;
+    }
+
+    /**
+     * <code>bool passed = 1;</code>
+     */
+    public function setPassed($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->passed = $var;
+    }
+
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    public function getBackoffMs()
+    {
+        return $this->backoff_ms;
+    }
+
+    /**
+     * <code>repeated int32 backoff_ms = 2;</code>
+     */
+    public function setBackoffMs(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->backoff_ms = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php
new file mode 100644
index 0000000..9715855
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ReconnectParams.php
@@ -0,0 +1,49 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * For reconnect interop test only.
+ * Client tells server what reconnection parameters it used.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ReconnectParams</code>
+ */
+class ReconnectParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    private $max_reconnect_backoff_ms = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    public function getMaxReconnectBackoffMs()
+    {
+        return $this->max_reconnect_backoff_ms;
+    }
+
+    /**
+     * <code>int32 max_reconnect_backoff_ms = 1;</code>
+     */
+    public function setMaxReconnectBackoffMs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->max_reconnect_backoff_ms = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php b/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php
new file mode 100644
index 0000000..1be42b2
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RequestResultCount.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.RequestResultCount</code>
+ */
+class RequestResultCount extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    private $status_code = 0;
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    private $count = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    public function getStatusCode()
+    {
+        return $this->status_code;
+    }
+
+    /**
+     * <code>int32 status_code = 1;</code>
+     */
+    public function setStatusCode($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->status_code = $var;
+    }
+
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+
+    /**
+     * <code>int64 count = 2;</code>
+     */
+    public function setCount($var)
+    {
+        GPBUtil::checkInt64($var);
+        $this->count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php
new file mode 100644
index 0000000..b7a8e5e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ResponseParameters.php
@@ -0,0 +1,138 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Configuration for a particular response.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ResponseParameters</code>
+ */
+class ResponseParameters extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    private $size = 0;
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    private $interval_us = 0;
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    private $compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    /**
+     * <pre>
+     * Desired payload sizes in responses from the server.
+     * </pre>
+     *
+     * <code>int32 size = 1;</code>
+     */
+    public function setSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->size = $var;
+    }
+
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    public function getIntervalUs()
+    {
+        return $this->interval_us;
+    }
+
+    /**
+     * <pre>
+     * Desired interval between consecutive responses in the response stream in
+     * microseconds.
+     * </pre>
+     *
+     * <code>int32 interval_us = 2;</code>
+     */
+    public function setIntervalUs($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->interval_us = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    public function getCompressed()
+    {
+        return $this->compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue compressed = 3;</code>
+     */
+    public function setCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php b/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php
new file mode 100644
index 0000000..2e664ff
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/RpcType.php
@@ -0,0 +1,21 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.RpcType</code>
+ */
+class RpcType
+{
+    /**
+     * <code>UNARY = 0;</code>
+     */
+    const UNARY = 0;
+    /**
+     * <code>STREAMING = 1;</code>
+     */
+    const STREAMING = 1;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php b/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php
new file mode 100644
index 0000000..136ed29
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Scenario.php
@@ -0,0 +1,291 @@
+<?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;
+
+/**
+ * <pre>
+ * A single performance scenario: input to qps_json_driver
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Scenario</code>
+ */
+class Scenario extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    private $name = '';
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    private $client_config = null;
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    private $num_clients = 0;
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    private $server_config = null;
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    private $num_servers = 0;
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    private $warmup_seconds = 0;
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    private $benchmark_seconds = 0;
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    private $spawn_local_worker_count = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * <pre>
+     * Human readable name for this scenario
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+    }
+
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    public function getClientConfig()
+    {
+        return $this->client_config;
+    }
+
+    /**
+     * <pre>
+     * Client configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ClientConfig client_config = 2;</code>
+     */
+    public function setClientConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ClientConfig::class);
+        $this->client_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    public function getNumClients()
+    {
+        return $this->num_clients;
+    }
+
+    /**
+     * <pre>
+     * Number of clients to start for the test
+     * </pre>
+     *
+     * <code>int32 num_clients = 3;</code>
+     */
+    public function setNumClients($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->num_clients = $var;
+    }
+
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    public function getServerConfig()
+    {
+        return $this->server_config;
+    }
+
+    /**
+     * <pre>
+     * Server configuration
+     * </pre>
+     *
+     * <code>.grpc.testing.ServerConfig server_config = 4;</code>
+     */
+    public function setServerConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerConfig::class);
+        $this->server_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    public function getNumServers()
+    {
+        return $this->num_servers;
+    }
+
+    /**
+     * <pre>
+     * Number of servers to start for the test
+     * </pre>
+     *
+     * <code>int32 num_servers = 5;</code>
+     */
+    public function setNumServers($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->num_servers = $var;
+    }
+
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    public function getWarmupSeconds()
+    {
+        return $this->warmup_seconds;
+    }
+
+    /**
+     * <pre>
+     * Warmup period, in seconds
+     * </pre>
+     *
+     * <code>int32 warmup_seconds = 6;</code>
+     */
+    public function setWarmupSeconds($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->warmup_seconds = $var;
+    }
+
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    public function getBenchmarkSeconds()
+    {
+        return $this->benchmark_seconds;
+    }
+
+    /**
+     * <pre>
+     * Benchmark time, in seconds
+     * </pre>
+     *
+     * <code>int32 benchmark_seconds = 7;</code>
+     */
+    public function setBenchmarkSeconds($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->benchmark_seconds = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    public function getSpawnLocalWorkerCount()
+    {
+        return $this->spawn_local_worker_count;
+    }
+
+    /**
+     * <pre>
+     * Number of workers to spawn locally (usually zero)
+     * </pre>
+     *
+     * <code>int32 spawn_local_worker_count = 8;</code>
+     */
+    public function setSpawnLocalWorkerCount($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->spawn_local_worker_count = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php
new file mode 100644
index 0000000..809cd96
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResult.php
@@ -0,0 +1,312 @@
+<?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;
+
+/**
+ * <pre>
+ * Results of a single benchmark scenario.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ScenarioResult</code>
+ */
+class ScenarioResult extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    private $scenario = null;
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    private $latencies = null;
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    private $client_stats;
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    private $server_stats;
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    private $server_cores;
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    private $summary = null;
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    private $client_success;
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    private $server_success;
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    private $request_results;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    public function getScenario()
+    {
+        return $this->scenario;
+    }
+
+    /**
+     * <pre>
+     * Inputs used to run the scenario.
+     * </pre>
+     *
+     * <code>.grpc.testing.Scenario scenario = 1;</code>
+     */
+    public function setScenario(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Scenario::class);
+        $this->scenario = $var;
+    }
+
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    public function getLatencies()
+    {
+        return $this->latencies;
+    }
+
+    /**
+     * <pre>
+     * Histograms from all clients merged into one histogram.
+     * </pre>
+     *
+     * <code>.grpc.testing.HistogramData latencies = 2;</code>
+     */
+    public function setLatencies(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\HistogramData::class);
+        $this->latencies = $var;
+    }
+
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    public function getClientStats()
+    {
+        return $this->client_stats;
+    }
+
+    /**
+     * <pre>
+     * Client stats for each client
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ClientStats client_stats = 3;</code>
+     */
+    public function setClientStats(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ClientStats::class);
+        $this->client_stats = $var;
+    }
+
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    public function getServerStats()
+    {
+        return $this->server_stats;
+    }
+
+    /**
+     * <pre>
+     * Server stats for each server
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ServerStats server_stats = 4;</code>
+     */
+    public function setServerStats(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ServerStats::class);
+        $this->server_stats = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    public function getServerCores()
+    {
+        return $this->server_cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to each server
+     * </pre>
+     *
+     * <code>repeated int32 server_cores = 5;</code>
+     */
+    public function setServerCores(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->server_cores = $var;
+    }
+
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    public function getSummary()
+    {
+        return $this->summary;
+    }
+
+    /**
+     * <pre>
+     * An after-the-fact computed summary
+     * </pre>
+     *
+     * <code>.grpc.testing.ScenarioResultSummary summary = 6;</code>
+     */
+    public function setSummary(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ScenarioResultSummary::class);
+        $this->summary = $var;
+    }
+
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    public function getClientSuccess()
+    {
+        return $this->client_success;
+    }
+
+    /**
+     * <pre>
+     * Information on success or failure of each worker
+     * </pre>
+     *
+     * <code>repeated bool client_success = 7;</code>
+     */
+    public function setClientSuccess(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::BOOL);
+        $this->client_success = $var;
+    }
+
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    public function getServerSuccess()
+    {
+        return $this->server_success;
+    }
+
+    /**
+     * <code>repeated bool server_success = 8;</code>
+     */
+    public function setServerSuccess(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::BOOL);
+        $this->server_success = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    public function getRequestResults()
+    {
+        return $this->request_results;
+    }
+
+    /**
+     * <pre>
+     * Number of failed requests (one row per status code seen)
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.RequestResultCount request_results = 9;</code>
+     */
+    public function setRequestResults(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\RequestResultCount::class);
+        $this->request_results = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php
new file mode 100644
index 0000000..7520cff
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ScenarioResultSummary.php
@@ -0,0 +1,430 @@
+<?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;
+
+/**
+ * <pre>
+ * Basic summary that can be computed from ClientStats and ServerStats
+ * once the scenario has finished.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.ScenarioResultSummary</code>
+ */
+class ScenarioResultSummary extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    private $qps = 0.0;
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    private $qps_per_server_core = 0.0;
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    private $server_system_time = 0.0;
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    private $server_user_time = 0.0;
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    private $client_system_time = 0.0;
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    private $client_user_time = 0.0;
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    private $latency_50 = 0.0;
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    private $latency_90 = 0.0;
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    private $latency_95 = 0.0;
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    private $latency_99 = 0.0;
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    private $latency_999 = 0.0;
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    private $server_cpu_usage = 0.0;
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    private $successful_requests_per_second = 0.0;
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    private $failed_requests_per_second = 0.0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    public function getQps()
+    {
+        return $this->qps;
+    }
+
+    /**
+     * <pre>
+     * Total number of operations per second over all clients.
+     * </pre>
+     *
+     * <code>double qps = 1;</code>
+     */
+    public function setQps($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->qps = $var;
+    }
+
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    public function getQpsPerServerCore()
+    {
+        return $this->qps_per_server_core;
+    }
+
+    /**
+     * <pre>
+     * QPS per one server core.
+     * </pre>
+     *
+     * <code>double qps_per_server_core = 2;</code>
+     */
+    public function setQpsPerServerCore($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->qps_per_server_core = $var;
+    }
+
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    public function getServerSystemTime()
+    {
+        return $this->server_system_time;
+    }
+
+    /**
+     * <pre>
+     * server load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_system_time = 3;</code>
+     */
+    public function setServerSystemTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_system_time = $var;
+    }
+
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    public function getServerUserTime()
+    {
+        return $this->server_user_time;
+    }
+
+    /**
+     * <pre>
+     * server load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double server_user_time = 4;</code>
+     */
+    public function setServerUserTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_user_time = $var;
+    }
+
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    public function getClientSystemTime()
+    {
+        return $this->client_system_time;
+    }
+
+    /**
+     * <pre>
+     * client load based on system_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_system_time = 5;</code>
+     */
+    public function setClientSystemTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->client_system_time = $var;
+    }
+
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    public function getClientUserTime()
+    {
+        return $this->client_user_time;
+    }
+
+    /**
+     * <pre>
+     * client load based on user_time (0.85 =&gt; 85%)
+     * </pre>
+     *
+     * <code>double client_user_time = 6;</code>
+     */
+    public function setClientUserTime($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->client_user_time = $var;
+    }
+
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    public function getLatency50()
+    {
+        return $this->latency_50;
+    }
+
+    /**
+     * <pre>
+     * X% latency percentiles (in nanoseconds)
+     * </pre>
+     *
+     * <code>double latency_50 = 7;</code>
+     */
+    public function setLatency50($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_50 = $var;
+    }
+
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    public function getLatency90()
+    {
+        return $this->latency_90;
+    }
+
+    /**
+     * <code>double latency_90 = 8;</code>
+     */
+    public function setLatency90($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_90 = $var;
+    }
+
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    public function getLatency95()
+    {
+        return $this->latency_95;
+    }
+
+    /**
+     * <code>double latency_95 = 9;</code>
+     */
+    public function setLatency95($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_95 = $var;
+    }
+
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    public function getLatency99()
+    {
+        return $this->latency_99;
+    }
+
+    /**
+     * <code>double latency_99 = 10;</code>
+     */
+    public function setLatency99($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_99 = $var;
+    }
+
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    public function getLatency999()
+    {
+        return $this->latency_999;
+    }
+
+    /**
+     * <code>double latency_999 = 11;</code>
+     */
+    public function setLatency999($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->latency_999 = $var;
+    }
+
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    public function getServerCpuUsage()
+    {
+        return $this->server_cpu_usage;
+    }
+
+    /**
+     * <pre>
+     * server cpu usage percentage
+     * </pre>
+     *
+     * <code>double server_cpu_usage = 12;</code>
+     */
+    public function setServerCpuUsage($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->server_cpu_usage = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    public function getSuccessfulRequestsPerSecond()
+    {
+        return $this->successful_requests_per_second;
+    }
+
+    /**
+     * <pre>
+     * Number of requests that succeeded/failed
+     * </pre>
+     *
+     * <code>double successful_requests_per_second = 13;</code>
+     */
+    public function setSuccessfulRequestsPerSecond($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->successful_requests_per_second = $var;
+    }
+
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    public function getFailedRequestsPerSecond()
+    {
+        return $this->failed_requests_per_second;
+    }
+
+    /**
+     * <code>double failed_requests_per_second = 14;</code>
+     */
+    public function setFailedRequestsPerSecond($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->failed_requests_per_second = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php b/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php
new file mode 100644
index 0000000..278f555
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Scenarios.php
@@ -0,0 +1,48 @@
+<?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;
+
+/**
+ * <pre>
+ * A set of scenarios to be run with qps_json_driver
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.Scenarios</code>
+ */
+class Scenarios extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    private $scenarios;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    public function getScenarios()
+    {
+        return $this->scenarios;
+    }
+
+    /**
+     * <code>repeated .grpc.testing.Scenario scenarios = 1;</code>
+     */
+    public function setScenarios(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\Scenario::class);
+        $this->scenarios = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php
new file mode 100644
index 0000000..27a5b95
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SecurityParams.php
@@ -0,0 +1,69 @@
+<?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;
+
+/**
+ * <pre>
+ * presence of SecurityParams implies use of TLS
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SecurityParams</code>
+ */
+class SecurityParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    private $use_test_ca = false;
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    private $server_host_override = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    public function getUseTestCa()
+    {
+        return $this->use_test_ca;
+    }
+
+    /**
+     * <code>bool use_test_ca = 1;</code>
+     */
+    public function setUseTestCa($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->use_test_ca = $var;
+    }
+
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    public function getServerHostOverride()
+    {
+        return $this->server_host_override;
+    }
+
+    /**
+     * <code>string server_host_override = 2;</code>
+     */
+    public function setServerHostOverride($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->server_host_override = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php
new file mode 100644
index 0000000..0d84b80
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerArgs.php
@@ -0,0 +1,63 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerArgs</code>
+ */
+class ServerArgs extends \Google\Protobuf\Internal\Message
+{
+    protected $argtype;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerConfig setup = 1;</code>
+     */
+    public function getSetup()
+    {
+        return $this->readOneof(1);
+    }
+
+    /**
+     * <code>.grpc.testing.ServerConfig setup = 1;</code>
+     */
+    public function setSetup(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerConfig::class);
+        $this->writeOneof(1, $var);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function getMark()
+    {
+        return $this->readOneof(2);
+    }
+
+    /**
+     * <code>.grpc.testing.Mark mark = 2;</code>
+     */
+    public function setMark(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Mark::class);
+        $this->writeOneof(2, $var);
+    }
+
+    public function getArgtype()
+    {
+        return $this->whichOneof("argtype");
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php
new file mode 100644
index 0000000..e2bcede
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerConfig.php
@@ -0,0 +1,305 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerConfig</code>
+ */
+class ServerConfig extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    private $server_type = 0;
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    private $security_params = null;
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    private $port = 0;
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    private $async_server_threads = 0;
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    private $core_limit = 0;
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    private $payload_config = null;
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    private $core_list;
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    private $other_server_api = '';
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    private $resource_quota_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    public function getServerType()
+    {
+        return $this->server_type;
+    }
+
+    /**
+     * <code>.grpc.testing.ServerType server_type = 1;</code>
+     */
+    public function setServerType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\ServerType::class);
+        $this->server_type = $var;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    public function getSecurityParams()
+    {
+        return $this->security_params;
+    }
+
+    /**
+     * <code>.grpc.testing.SecurityParams security_params = 2;</code>
+     */
+    public function setSecurityParams(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\SecurityParams::class);
+        $this->security_params = $var;
+    }
+
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    public function getPort()
+    {
+        return $this->port;
+    }
+
+    /**
+     * <pre>
+     * Port on which to listen. Zero means pick unused port.
+     * </pre>
+     *
+     * <code>int32 port = 4;</code>
+     */
+    public function setPort($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->port = $var;
+    }
+
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    public function getAsyncServerThreads()
+    {
+        return $this->async_server_threads;
+    }
+
+    /**
+     * <pre>
+     * Only for async server. Number of threads used to serve the requests.
+     * </pre>
+     *
+     * <code>int32 async_server_threads = 7;</code>
+     */
+    public function setAsyncServerThreads($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->async_server_threads = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    public function getCoreLimit()
+    {
+        return $this->core_limit;
+    }
+
+    /**
+     * <pre>
+     * Specify the number of cores to limit server to, if desired
+     * </pre>
+     *
+     * <code>int32 core_limit = 8;</code>
+     */
+    public function setCoreLimit($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->core_limit = $var;
+    }
+
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    public function getPayloadConfig()
+    {
+        return $this->payload_config;
+    }
+
+    /**
+     * <pre>
+     * payload config, used in generic server.
+     * Note this must NOT be used in proto (non-generic) servers. For proto servers,
+     * 'response sizes' must be configured from the 'response_size' field of the
+     * 'SimpleRequest' objects in RPC requests.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadConfig payload_config = 9;</code>
+     */
+    public function setPayloadConfig(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\PayloadConfig::class);
+        $this->payload_config = $var;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    public function getCoreList()
+    {
+        return $this->core_list;
+    }
+
+    /**
+     * <pre>
+     * Specify the cores we should run the server on, if desired
+     * </pre>
+     *
+     * <code>repeated int32 core_list = 10;</code>
+     */
+    public function setCoreList(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->core_list = $var;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    public function getOtherServerApi()
+    {
+        return $this->other_server_api;
+    }
+
+    /**
+     * <pre>
+     * If we use an OTHER_SERVER client_type, this string gives more detail
+     * </pre>
+     *
+     * <code>string other_server_api = 11;</code>
+     */
+    public function setOtherServerApi($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->other_server_api = $var;
+    }
+
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    public function getResourceQuotaSize()
+    {
+        return $this->resource_quota_size;
+    }
+
+    /**
+     * <pre>
+     * Buffer pool size (no buffer pool specified if unset)
+     * </pre>
+     *
+     * <code>int32 resource_quota_size = 1001;</code>
+     */
+    public function setResourceQuotaSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resource_quota_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php
new file mode 100644
index 0000000..98b2af7
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStats.php
@@ -0,0 +1,191 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/stats.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerStats</code>
+ */
+class ServerStats extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    private $time_elapsed = 0.0;
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    private $time_user = 0.0;
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    private $time_system = 0.0;
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    private $total_cpu_time = 0;
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    private $idle_cpu_time = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Stats::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    public function getTimeElapsed()
+    {
+        return $this->time_elapsed;
+    }
+
+    /**
+     * <pre>
+     * wall clock time change in seconds since last reset
+     * </pre>
+     *
+     * <code>double time_elapsed = 1;</code>
+     */
+    public function setTimeElapsed($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_elapsed = $var;
+    }
+
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    public function getTimeUser()
+    {
+        return $this->time_user;
+    }
+
+    /**
+     * <pre>
+     * change in user time (in seconds) used by the server since last reset
+     * </pre>
+     *
+     * <code>double time_user = 2;</code>
+     */
+    public function setTimeUser($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_user = $var;
+    }
+
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    public function getTimeSystem()
+    {
+        return $this->time_system;
+    }
+
+    /**
+     * <pre>
+     * change in server time (in seconds) used by the server process and all
+     * threads since last reset
+     * </pre>
+     *
+     * <code>double time_system = 3;</code>
+     */
+    public function setTimeSystem($var)
+    {
+        GPBUtil::checkDouble($var);
+        $this->time_system = $var;
+    }
+
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    public function getTotalCpuTime()
+    {
+        return $this->total_cpu_time;
+    }
+
+    /**
+     * <pre>
+     * change in total cpu time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 total_cpu_time = 4;</code>
+     */
+    public function setTotalCpuTime($var)
+    {
+        GPBUtil::checkUint64($var);
+        $this->total_cpu_time = $var;
+    }
+
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    public function getIdleCpuTime()
+    {
+        return $this->idle_cpu_time;
+    }
+
+    /**
+     * <pre>
+     * change in idle time of the server (data from proc/stat)
+     * </pre>
+     *
+     * <code>uint64 idle_cpu_time = 5;</code>
+     */
+    public function setIdleCpuTime($var)
+    {
+        GPBUtil::checkUint64($var);
+        $this->idle_cpu_time = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php
new file mode 100644
index 0000000..d293f03
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerStatus.php
@@ -0,0 +1,110 @@
+<?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;
+
+/**
+ * Protobuf type <code>grpc.testing.ServerStatus</code>
+ */
+class ServerStatus extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    private $stats = null;
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    private $port = 0;
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    private $cores = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Control::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    public function getStats()
+    {
+        return $this->stats;
+    }
+
+    /**
+     * <code>.grpc.testing.ServerStats stats = 1;</code>
+     */
+    public function setStats(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\ServerStats::class);
+        $this->stats = $var;
+    }
+
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    public function getPort()
+    {
+        return $this->port;
+    }
+
+    /**
+     * <pre>
+     * the port bound by the server
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    public function setPort($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->port = $var;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    public function getCores()
+    {
+        return $this->cores;
+    }
+
+    /**
+     * <pre>
+     * Number of cores available to the server
+     * </pre>
+     *
+     * <code>int32 cores = 3;</code>
+     */
+    public function setCores($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->cores = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php b/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php
new file mode 100644
index 0000000..605c83c
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/ServerType.php
@@ -0,0 +1,33 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/control.proto
+
+namespace Grpc\Testing;
+
+/**
+ * Protobuf enum <code>grpc.testing.ServerType</code>
+ */
+class ServerType
+{
+    /**
+     * <code>SYNC_SERVER = 0;</code>
+     */
+    const SYNC_SERVER = 0;
+    /**
+     * <code>ASYNC_SERVER = 1;</code>
+     */
+    const ASYNC_SERVER = 1;
+    /**
+     * <code>ASYNC_GENERIC_SERVER = 2;</code>
+     */
+    const ASYNC_GENERIC_SERVER = 2;
+    /**
+     * <pre>
+     * used for some language-specific variants
+     * </pre>
+     *
+     * <code>OTHER_SERVER = 3;</code>
+     */
+    const OTHER_SERVER = 3;
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php
new file mode 100644
index 0000000..29834a3
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleProtoParams.php
@@ -0,0 +1,65 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/payloads.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Protobuf type <code>grpc.testing.SimpleProtoParams</code>
+ */
+class SimpleProtoParams extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    private $req_size = 0;
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    private $resp_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Payloads::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function getReqSize()
+    {
+        return $this->req_size;
+    }
+
+    /**
+     * <code>int32 req_size = 1;</code>
+     */
+    public function setReqSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->req_size = $var;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function getRespSize()
+    {
+        return $this->resp_size;
+    }
+
+    /**
+     * <code>int32 resp_size = 2;</code>
+     */
+    public function setRespSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->resp_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php
new file mode 100644
index 0000000..f84c953
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleRequest.php
@@ -0,0 +1,306 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Unary request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SimpleRequest</code>
+ */
+class SimpleRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    private $response_type = 0;
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    private $response_size = 0;
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    private $fill_username = false;
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    private $fill_oauth_scope = false;
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    private $response_compressed = null;
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    private $response_status = null;
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    private $expect_compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function getResponseType()
+    {
+        return $this->response_type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, server randomly chooses one from other formats.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function setResponseType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->response_type = $var;
+    }
+
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    public function getResponseSize()
+    {
+        return $this->response_size;
+    }
+
+    /**
+     * <pre>
+     * Desired payload size in the response from the server.
+     * </pre>
+     *
+     * <code>int32 response_size = 2;</code>
+     */
+    public function setResponseSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->response_size = $var;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    public function getFillUsername()
+    {
+        return $this->fill_username;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include username.
+     * </pre>
+     *
+     * <code>bool fill_username = 4;</code>
+     */
+    public function setFillUsername($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->fill_username = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    public function getFillOauthScope()
+    {
+        return $this->fill_oauth_scope;
+    }
+
+    /**
+     * <pre>
+     * Whether SimpleResponse should include OAuth scope.
+     * </pre>
+     *
+     * <code>bool fill_oauth_scope = 5;</code>
+     */
+    public function setFillOauthScope($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->fill_oauth_scope = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    public function getResponseCompressed()
+    {
+        return $this->response_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether to request the server to compress the response. This field is
+     * "nullable" in order to interoperate seamlessly with clients not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the response's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue response_compressed = 6;</code>
+     */
+    public function setResponseCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->response_compressed = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function getResponseStatus()
+    {
+        return $this->response_status;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function setResponseStatus(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\EchoStatus::class);
+        $this->response_status = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    public function getExpectCompressed()
+    {
+        return $this->expect_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 8;</code>
+     */
+    public function setExpectCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->expect_compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php
new file mode 100644
index 0000000..ccc628e
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/SimpleResponse.php
@@ -0,0 +1,129 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Unary response, as configured by the request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.SimpleResponse</code>
+ */
+class SimpleResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    private $username = '';
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    private $oauth_scope = '';
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Payload to increase message size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    public function getUsername()
+    {
+        return $this->username;
+    }
+
+    /**
+     * <pre>
+     * The user the request came from, for verifying authentication was
+     * successful when the client expected it.
+     * </pre>
+     *
+     * <code>string username = 2;</code>
+     */
+    public function setUsername($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->username = $var;
+    }
+
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    public function getOauthScope()
+    {
+        return $this->oauth_scope;
+    }
+
+    /**
+     * <pre>
+     * OAuth scope.
+     * </pre>
+     *
+     * <code>string oauth_scope = 3;</code>
+     */
+    public function setOauthScope($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->oauth_scope = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php
new file mode 100644
index 0000000..d7bbc70
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallRequest.php
@@ -0,0 +1,102 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Client-streaming request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingInputCallRequest</code>
+ */
+class StreamingInputCallRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    private $expect_compressed = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    public function getExpectCompressed()
+    {
+        return $this->expect_compressed;
+    }
+
+    /**
+     * <pre>
+     * Whether the server should expect this request to be compressed. This field
+     * is "nullable" in order to interoperate seamlessly with servers not able to
+     * implement the full compression tests by introspecting the call to verify
+     * the request's compression status.
+     * </pre>
+     *
+     * <code>.grpc.testing.BoolValue expect_compressed = 2;</code>
+     */
+    public function setExpectCompressed(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\BoolValue::class);
+        $this->expect_compressed = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php
new file mode 100644
index 0000000..fdd1d0d
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingInputCallResponse.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Client-streaming response.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingInputCallResponse</code>
+ */
+class StreamingInputCallResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    private $aggregated_payload_size = 0;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    public function getAggregatedPayloadSize()
+    {
+        return $this->aggregated_payload_size;
+    }
+
+    /**
+     * <pre>
+     * Aggregated size of payloads received from the client.
+     * </pre>
+     *
+     * <code>int32 aggregated_payload_size = 1;</code>
+     */
+    public function setAggregatedPayloadSize($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->aggregated_payload_size = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php
new file mode 100644
index 0000000..2aab5fa
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallRequest.php
@@ -0,0 +1,171 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Server-streaming request.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingOutputCallRequest</code>
+ */
+class StreamingOutputCallRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    private $response_type = 0;
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    private $response_parameters;
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    private $payload = null;
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    private $response_status = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function getResponseType()
+    {
+        return $this->response_type;
+    }
+
+    /**
+     * <pre>
+     * DEPRECATED, don't use. To be removed shortly.
+     * Desired payload type in the response from the server.
+     * If response_type is RANDOM, the payload from each response in the stream
+     * might be of different types. This is to simulate a mixed type of payload
+     * stream.
+     * </pre>
+     *
+     * <code>.grpc.testing.PayloadType response_type = 1;</code>
+     */
+    public function setResponseType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\PayloadType::class);
+        $this->response_type = $var;
+    }
+
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    public function getResponseParameters()
+    {
+        return $this->response_parameters;
+    }
+
+    /**
+     * <pre>
+     * Configuration for each expected response message.
+     * </pre>
+     *
+     * <code>repeated .grpc.testing.ResponseParameters response_parameters = 2;</code>
+     */
+    public function setResponseParameters(&$var)
+    {
+        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ResponseParameters::class);
+        $this->response_parameters = $var;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Optional input payload sent along with the request.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 3;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function getResponseStatus()
+    {
+        return $this->response_status;
+    }
+
+    /**
+     * <pre>
+     * Whether server should return a given status
+     * </pre>
+     *
+     * <code>.grpc.testing.EchoStatus response_status = 7;</code>
+     */
+    public function setResponseStatus(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\EchoStatus::class);
+        $this->response_status = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php
new file mode 100644
index 0000000..c06c78c
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/StreamingOutputCallResponse.php
@@ -0,0 +1,60 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * <pre>
+ * Server-streaming response, as configured by the request and parameters.
+ * </pre>
+ *
+ * Protobuf type <code>grpc.testing.StreamingOutputCallResponse</code>
+ */
+class StreamingOutputCallResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    private $payload = null;
+
+    public function __construct() {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct();
+    }
+
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * <pre>
+     * Payload to increase response size.
+     * </pre>
+     *
+     * <code>.grpc.testing.Payload payload = 1;</code>
+     */
+    public function setPayload(&$var)
+    {
+        GPBUtil::checkMessage($var, \Grpc\Testing\Payload::class);
+        $this->payload = $var;
+    }
+
+}
+
diff --git a/src/php/tests/qps/generated_code/Grpc/Testing/Void.php b/src/php/tests/qps/generated_code/Grpc/Testing/Void.php
new file mode 100644
index 0000000..38c1008
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/Void.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;
+
+/**
+ * Protobuf type <code>grpc.testing.Void</code>
+ */
+class Void 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/WorkerServiceClient.php b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
new file mode 100644
index 0000000..0a68e41
--- /dev/null
+++ b/src/php/tests/qps/generated_code/Grpc/Testing/WorkerServiceClient.php
@@ -0,0 +1,111 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+namespace Grpc\Testing {
+
+  class WorkerServiceClient 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);
+    }
+
+    /**
+     * 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.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function RunServer($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.WorkerService/RunServer',
+      ['\Grpc\Testing\ServerStatus','decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * 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.
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function RunClient($metadata = [], $options = []) {
+      return $this->_bidiRequest('/grpc.testing.WorkerService/RunClient',
+      ['\Grpc\Testing\ClientStatus','decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * Just return the core count - unary call
+     * @param \Grpc\Testing\CoreRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function CoreCount(\Grpc\Testing\CoreRequest $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.WorkerService/CoreCount',
+      $argument,
+      ['\Grpc\Testing\CoreResponse', 'decode'],
+      $metadata, $options);
+    }
+
+    /**
+     * Quit this worker
+     * @param \Grpc\Testing\Void $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     */
+    public function QuitWorker(\Grpc\Testing\Void $argument,
+      $metadata = [], $options = []) {
+      return $this->_simpleRequest('/grpc.testing.WorkerService/QuitWorker',
+      $argument,
+      ['\Grpc\Testing\Void', 'decode'],
+      $metadata, $options);
+    }
+
+  }
+
+}
diff --git a/src/proto/grpc/testing/proxy-service.proto b/src/proto/grpc/testing/proxy-service.proto
new file mode 100644
index 0000000..7b7de8d
--- /dev/null
+++ b/src/proto/grpc/testing/proxy-service.proto
@@ -0,0 +1,44 @@
+// Copyright 2017, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+import "src/proto/grpc/testing/control.proto";
+
+package grpc.testing;
+
+message ProxyStat {
+  double latency = 1;
+}
+
+service ProxyClientService {
+  rpc GetConfig(Void) returns (ClientConfig);
+  rpc ReportTime(stream ProxyStat) returns (Void);
+}
+
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
index db938e6..6f9269d 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
@@ -42,6 +42,7 @@
 import tempfile
 import threading
 import unittest
+import platform
 
 import grpc
 from grpc_tools import protoc
@@ -150,6 +151,8 @@
         self.assertEqual(expected_response, response)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
 
     def setUp(self):
@@ -191,6 +194,8 @@
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SameCommonTest(unittest.TestCase, CommonTestMixin):
 
     def setUp(self):
@@ -228,6 +233,8 @@
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SplitCommonTest(unittest.TestCase, CommonTestMixin):
 
     def setUp(self):
@@ -277,6 +284,8 @@
         shutil.rmtree(self.directory)
 
 
+@unittest.skipIf(platform.python_implementation() == "PyPy",
+                 "Skip test if run with PyPy")
 class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
 
     def setUp(self):
diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb
new file mode 100755
index 0000000..077920d
--- /dev/null
+++ b/src/ruby/qps/proxy-worker.rb
@@ -0,0 +1,160 @@
+#!/usr/bin/env ruby
+
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Proxy of worker service implementation for running a PHP client
+
+this_dir = File.expand_path(File.dirname(__FILE__))
+lib_dir = File.join(File.dirname(this_dir), 'lib')
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+
+require 'grpc'
+require 'optparse'
+require 'histogram'
+require 'etc'
+require 'facter'
+require 'qps-common'
+require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/proxy-service_services_pb'
+
+class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Service
+  def initialize(port)
+    @mytarget = "localhost:" + port.to_s
+  end
+  def setup(config)
+    @config = config
+    @histres = config.histogram_params.resolution
+    @histmax = config.histogram_params.max_possible
+    @histogram = Histogram.new(@histres, @histmax)
+    @start_time = Time.now
+    # TODO(vjpai): Support multiple client channels by spawning off a PHP client per channel
+    command = "php " + File.expand_path(File.dirname(__FILE__)) + "/../../php/tests/qps/client.php " + @mytarget
+    puts "Starting command: " + command
+    @php_pid = spawn(command)
+  end
+  def stop
+    Process.kill("TERM", @php_pid)
+    Process.wait(@php_pid)
+  end
+  def get_config(_args, _call)
+    puts "Answering get_config"
+    @config
+  end
+  def report_time(call)
+    puts "Starting a time reporting stream"
+    call.each_remote_read do |lat|
+      @histogram.add((lat.latency)*1e9)
+    end
+    Grpc::Testing::Void.new
+  end
+  def mark(reset)
+    lat = Grpc::Testing::HistogramData.new(
+      bucket: @histogram.contents,
+      min_seen: @histogram.minimum,
+      max_seen: @histogram.maximum,
+      sum: @histogram.sum,
+      sum_of_squares: @histogram.sum_of_squares,
+      count: @histogram.count
+    )
+    elapsed = Time.now-@start_time
+    if reset
+      @start_time = Time.now
+      @histogram = Histogram.new(@histres, @histmax)
+    end
+    Grpc::Testing::ClientStats.new(latencies: lat, time_elapsed: elapsed)
+  end
+end
+
+class ProxyWorkerServiceImpl < Grpc::Testing::WorkerService::Service
+  def cpu_cores
+    Facter.value('processors')['count']
+  end
+  # Leave run_server unimplemented since this proxies for a client only.
+  # If the driver tries to use this as a server, it will get an unimplemented
+  # status return value.
+  def run_client(reqs)
+    q = EnumeratorQueue.new(self)
+    Thread.new {
+      reqs.each do |req|
+        case req.argtype.to_s
+        when 'setup'
+          @bmc.setup(req.setup)
+          q.push(Grpc::Testing::ClientStatus.new(stats: @bmc.mark(false)))
+        when 'mark'
+          q.push(Grpc::Testing::ClientStatus.new(stats:
+                                                   @bmc.mark(req.mark.reset)))
+        end
+      end
+      @bmc.stop
+      q.push(self)
+    }
+    q.each_item
+  end
+  def core_count(_args, _call)
+    Grpc::Testing::CoreResponse.new(cores: cpu_cores)
+  end
+  def quit_worker(_args, _call)
+    Thread.new {
+      sleep 3
+      @server.stop
+    }
+    Grpc::Testing::Void.new
+  end
+  def initialize(s, bmc)
+    @server = s
+    @bmc = bmc
+  end
+end
+
+def proxymain
+  options = {
+    'driver_port' => 0
+  }
+  OptionParser.new do |opts|
+    opts.banner = 'Usage: [--driver_port <port>]'
+    opts.on('--driver_port PORT', '<port>') do |v|
+      options['driver_port'] = v
+    end
+  end.parse!
+
+  # Configure any errors with client or server child threads to surface
+  Thread.abort_on_exception = true
+
+  s = GRPC::RpcServer.new
+  port = s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s,
+                          :this_port_is_insecure)
+  bmc = ProxyBenchmarkClientServiceImpl.new(port)
+  s.handle(bmc)
+  s.handle(ProxyWorkerServiceImpl.new(s, bmc))
+  s.run
+end
+
+proxymain
diff --git a/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb
new file mode 100644
index 0000000..d238198
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/proxy-service_pb.rb
@@ -0,0 +1,17 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/proxy-service.proto
+
+require 'google/protobuf'
+
+require 'src/proto/grpc/testing/control_pb'
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.ProxyStat" do
+    optional :latency, :double, 1
+  end
+end
+
+module Grpc
+  module Testing
+    ProxyStat = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ProxyStat").msgclass
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb b/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb
new file mode 100644
index 0000000..37ddbf5
--- /dev/null
+++ b/src/ruby/qps/src/proto/grpc/testing/proxy-service_services_pb.rb
@@ -0,0 +1,55 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: src/proto/grpc/testing/proxy-service.proto for package 'grpc.testing'
+# Original file comments:
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+require 'grpc'
+require 'src/proto/grpc/testing/proxy-service_pb'
+
+module Grpc
+  module Testing
+    module ProxyClientService
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.ProxyClientService'
+
+        rpc :GetConfig, Void, ClientConfig
+        rpc :ReportTime, stream(ProxyStat), Void
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/test/core/iomgr/tcp_client_uv_test.c b/test/core/iomgr/tcp_client_uv_test.c
index f8938d0..064119f 100644
--- a/test/core/iomgr/tcp_client_uv_test.c
+++ b/test/core/iomgr/tcp_client_uv_test.c
@@ -58,7 +58,7 @@
 static grpc_endpoint *g_connecting = NULL;
 
 static gpr_timespec test_deadline(void) {
-  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
+  return grpc_timeout_seconds_to_deadline(10);
 }
 
 static void finish_connection() {
@@ -73,7 +73,8 @@
                          grpc_error *error) {
   GPR_ASSERT(g_connecting != NULL);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_endpoint_shutdown(exec_ctx, g_connecting);
+  grpc_endpoint_shutdown(exec_ctx, g_connecting,
+                         GRPC_ERROR_CREATE("must_succeed called"));
   grpc_endpoint_destroy(exec_ctx, g_connecting);
   g_connecting = NULL;
   finish_connection();
@@ -133,7 +134,7 @@
         "pollset_work",
         grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                           gpr_now(GPR_CLOCK_MONOTONIC),
-                          GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))));
+                          grpc_timeout_seconds_to_deadline(5))));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_flush(&exec_ctx);
     gpr_mu_lock(g_mu);
diff --git a/test/core/iomgr/tcp_server_uv_test.c b/test/core/iomgr/tcp_server_uv_test.c
index 7b458c9..0fc7459 100644
--- a/test/core/iomgr/tcp_server_uv_test.c
+++ b/test/core/iomgr/tcp_server_uv_test.c
@@ -115,7 +115,7 @@
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
-  grpc_endpoint_shutdown(exec_ctx, tcp);
+  grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected"));
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   on_connect_result temp_result;
@@ -203,7 +203,7 @@
 
 static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
                         socklen_t remote_len, on_connect_result *result) {
-  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
   uv_tcp_t *client_handle = gpr_malloc(sizeof(uv_tcp_t));
   uv_connect_t *req = gpr_malloc(sizeof(uv_connect_t));
   int nconnects_before;
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index d57a37b..396ec95 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -62,8 +62,7 @@
 static int g_number_of_bytes_read = 0;
 static int g_number_of_orphan_calls = 0;
 
-static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
-                    grpc_server *server) {
+static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) {
   char read_buffer[512];
   ssize_t byte_count;
 
@@ -79,7 +78,7 @@
   gpr_mu_unlock(g_mu);
 }
 
-static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) {
+static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) {
   gpr_mu_lock(g_mu);
   g_number_of_writes++;
 
@@ -88,7 +87,8 @@
   gpr_mu_unlock(g_mu);
 }
 
-static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) {
+static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
+                           void *user_data) {
   gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d",
           grpc_fd_wrapped_fd(emfd));
   g_number_of_orphan_calls++;
diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c
index 09f0e2d..107abbc 100644
--- a/test/core/memory_usage/client.c
+++ b/test/core/memory_usage/client.c
@@ -43,6 +43,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/test_config.h"
@@ -310,6 +311,29 @@
           server_calls_end.total_size_relative -
               after_server_create.total_size_relative);
 
+  const char *csv_file = "memory_usage.csv";
+  FILE *csv = fopen(csv_file, "w");
+  if (csv) {
+    char *env_build = gpr_getenv("BUILD_NUMBER");
+    char *env_job = gpr_getenv("JOB_NAME");
+    fprintf(csv, "%f,%zi,%zi,%f,%zi,%s,%s\n",
+            (double)(client_calls_inflight.total_size_relative -
+                     client_benchmark_calls_start.total_size_relative) /
+                benchmark_iterations,
+            client_channel_end.total_size_relative -
+                client_channel_start.total_size_relative,
+            after_server_create.total_size_relative -
+                before_server_create.total_size_relative,
+            (double)(server_calls_inflight.total_size_relative -
+                     server_benchmark_calls_start.total_size_relative) /
+                benchmark_iterations,
+            server_calls_end.total_size_relative -
+                after_server_create.total_size_relative,
+            env_build == NULL ? "" : env_build, env_job == NULL ? "" : env_job);
+    fclose(csv);
+    gpr_log(GPR_INFO, "Summary written to %s", csv_file);
+  }
+
   grpc_memory_counters_destroy();
   return 0;
 }
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index e750c39..1cb03c5 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -34,7 +34,7 @@
 grpc_fuzzer(
   name = "ssl_server_fuzzer",
   srcs = ["ssl_server_fuzzer.c"],
-  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util", "//test/core/end2end:ssl_test_data"],
   corpus = "corpus",
   copts = ["-std=c99"],
 )
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index f789278..7a3612c 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -38,6 +38,7 @@
 #include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
@@ -46,10 +47,6 @@
 // Turning this on will fail the leak check.
 bool leak_check = false;
 
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
-
 static void discard_write(grpc_slice slice) {}
 
 static void dont_log(gpr_log_func_args *args) {}
@@ -88,12 +85,9 @@
   // Load key pair and establish server SSL credentials.
   grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
   grpc_slice ca_slice, cert_slice, key_slice;
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_CA_PATH, 1, &ca_slice)));
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_CERT_PATH, 1, &cert_slice)));
-  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
-                               grpc_load_file(SSL_KEY_PATH, 1, &key_slice)));
+  ca_slice = grpc_slice_from_static_string(test_root_cert);
+  cert_slice = grpc_slice_from_static_string(test_server1_cert);
+  key_slice = grpc_slice_from_static_string(test_server1_key);
   const char *ca_cert = (const char *)GRPC_SLICE_START_PTR(ca_slice);
   pem_key_cert_pair.private_key = (const char *)GRPC_SLICE_START_PTR(key_slice);
   pem_key_cert_pair.cert_chain = (const char *)GRPC_SLICE_START_PTR(cert_slice);
diff --git a/test/core/util/memory_counters.c b/test/core/util/memory_counters.c
index 7c8b620..c27065f 100644
--- a/test/core/util/memory_counters.c
+++ b/test/core/util/memory_counters.c
@@ -46,17 +46,23 @@
 static void *guard_realloc(void *vptr, size_t size);
 static void guard_free(void *vptr);
 
+#ifdef GPR_LOW_LEVEL_COUNTERS
+/* hide these from the microbenchmark atomic stats */
+#define NO_BARRIER_FETCH_ADD(x, sz) \
+  __atomic_fetch_add((x), (sz), __ATOMIC_RELAXED)
+#define NO_BARRIER_LOAD(x) __atomic_load_n((x), __ATOMIC_RELAXED)
+#else
+#define NO_BARRIER_FETCH_ADD(x, sz) gpr_atm_no_barrier_fetch_add(x, sz)
+#define NO_BARRIER_LOAD(x) gpr_atm_no_barrier_load(x)
+#endif
+
 static void *guard_malloc(size_t size) {
   size_t *ptr;
   if (!size) return NULL;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
-                               (gpr_atm)1);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
-                               (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1);
   ptr = g_old_allocs.malloc_fn(size + sizeof(size));
   *ptr++ = size;
   return ptr;
@@ -72,14 +78,10 @@
     return NULL;
   }
   --ptr;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               -(gpr_atm)*ptr);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               (gpr_atm)size);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute,
-                               (gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
   ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size));
   *ptr++ = size;
   return ptr;
@@ -89,10 +91,8 @@
   size_t *ptr = vptr;
   if (!vptr) return;
   --ptr;
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative,
-                               -(gpr_atm)*ptr);
-  gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative,
-                               -(gpr_atm)1);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+  NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1);
   g_old_allocs.free_fn(ptr);
 }
 
@@ -112,12 +112,12 @@
 struct grpc_memory_counters grpc_memory_counters_snapshot() {
   struct grpc_memory_counters counters;
   counters.total_size_relative =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_size_relative);
+      NO_BARRIER_LOAD(&g_memory_counters.total_size_relative);
   counters.total_size_absolute =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_size_absolute);
+      NO_BARRIER_LOAD(&g_memory_counters.total_size_absolute);
   counters.total_allocs_relative =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_relative);
+      NO_BARRIER_LOAD(&g_memory_counters.total_allocs_relative);
   counters.total_allocs_absolute =
-      gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_absolute);
+      NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute);
   return counters;
 }
diff --git a/test/core/util/trickle_endpoint.c b/test/core/util/trickle_endpoint.c
index 7ab0488..0848147 100644
--- a/test/core/util/trickle_endpoint.c
+++ b/test/core/util/trickle_endpoint.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include "src/core/lib/iomgr/sockaddr.h"
+
 #include "test/core/util/passthru_endpoint.h"
 
 #include <inttypes.h>
@@ -40,9 +42,6 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
-
-#include "src/core/lib/iomgr/sockaddr.h"
-
 #include "src/core/lib/slice/slice_internal.h"
 
 typedef struct {
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
index 01c0782..38a437f 100644
--- a/test/cpp/interop/http2_client.cc
+++ b/test/cpp/interop/http2_client.cc
@@ -41,7 +41,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/http2_client.h"
 
diff --git a/test/cpp/interop/http2_client.h b/test/cpp/interop/http2_client.h
index 12df5d2..e57d695 100644
--- a/test/cpp/interop/http2_client.h
+++ b/test/cpp/interop/http2_client.h
@@ -38,7 +38,7 @@
 
 #include <grpc++/channel.h>
 #include <grpc/grpc.h>
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 
 namespace grpc {
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index b7f2723..55ba324 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -46,8 +46,8 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/client_helper.h"
 #include "test/cpp/interop/interop_client.h"
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index 74f4db6..efcb7d2 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -38,7 +38,7 @@
 
 #include <grpc++/channel.h>
 #include <grpc/grpc.h>
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 
 namespace grpc {
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 5a810b4..1cbca17 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -48,8 +48,8 @@
 
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/byte_stream.h"
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/server_helper.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 1c2f606..01d9850 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -40,8 +40,8 @@
 #include <grpc++/support/channel_arguments.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/util/create_test_channel.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc
index 634d0a9..8d1b884 100644
--- a/test/cpp/interop/reconnect_interop_server.cc
+++ b/test/cpp/interop/reconnect_interop_server.cc
@@ -47,8 +47,8 @@
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 
-#include "src/proto/grpc/testing/empty.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/empty.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/core/util/reconnect_server.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc
index ee3dec2..34874b5 100644
--- a/test/cpp/microbenchmarks/bm_metadata.cc
+++ b/test/cpp/microbenchmarks/bm_metadata.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2017, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc
new file mode 100644
index 0000000..0f3d3ce
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_pollset.cc
@@ -0,0 +1,254 @@
+/*
+ *
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Test out pollset latencies */
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+extern "C" {
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/port.h"
+#include "src/core/lib/iomgr/wakeup_fd_posix.h"
+}
+
+#include "test/cpp/microbenchmarks/helpers.h"
+#include "third_party/benchmark/include/benchmark/benchmark.h"
+
+#include <string.h>
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+#endif
+
+auto& force_library_initialization = Library::get();
+
+static void shutdown_ps(grpc_exec_ctx* exec_ctx, void* ps, grpc_error* error) {
+  grpc_pollset_destroy(static_cast<grpc_pollset*>(ps));
+}
+
+static void BM_CreateDestroyPollset(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_malloc(ps_sz));
+  gpr_mu* mu;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  while (state.KeepRunning()) {
+    memset(ps, 0, ps_sz);
+    grpc_pollset_init(ps, &mu);
+    gpr_mu_lock(mu);
+    grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+    gpr_mu_unlock(mu);
+    grpc_exec_ctx_flush(&exec_ctx);
+  }
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(ps);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_CreateDestroyPollset);
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+static void BM_PollEmptyPollset_SpeedOfLight(benchmark::State& state) {
+  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
+  // what the speed of light would be if we abstracted perfectly
+  TrackCounters track_counters;
+  int epfd = epoll_create1(0);
+  GPR_ASSERT(epfd != -1);
+  size_t nev = state.range(0);
+  size_t nfd = state.range(1);
+  epoll_event* ev = new epoll_event[nev];
+  std::vector<int> fds;
+  for (size_t i = 0; i < nfd; i++) {
+    fds.push_back(eventfd(0, 0));
+    epoll_event ev;
+    ev.events = EPOLLIN;
+    epoll_ctl(epfd, EPOLL_CTL_ADD, fds.back(), &ev);
+  }
+  while (state.KeepRunning()) {
+    epoll_wait(epfd, ev, nev, 0);
+  }
+  for (auto fd : fds) {
+    close(fd);
+  }
+  close(epfd);
+  delete[] ev;
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_PollEmptyPollset_SpeedOfLight)
+    ->Args({1, 0})
+    ->Args({1, 1})
+    ->Args({1, 10})
+    ->Args({1, 100})
+    ->Args({1, 1000})
+    ->Args({1, 10000})
+    ->Args({1, 100000})
+    ->Args({10, 1})
+    ->Args({100, 1})
+    ->Args({1000, 1});
+#endif
+
+static void BM_PollEmptyPollset(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
+  gpr_mu* mu;
+  grpc_pollset_init(ps, &mu);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
+  gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
+  gpr_mu_lock(mu);
+  while (state.KeepRunning()) {
+    grpc_pollset_worker* worker;
+    GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, &worker, now, deadline));
+  }
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+  gpr_mu_unlock(mu);
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(ps);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_PollEmptyPollset);
+
+class Closure : public grpc_closure {
+ public:
+  virtual ~Closure() {}
+};
+
+template <class F>
+Closure* MakeClosure(F f, grpc_closure_scheduler* scheduler) {
+  struct C : public Closure {
+    C(F f, grpc_closure_scheduler* scheduler) : f_(f) {
+      grpc_closure_init(this, C::cbfn, this, scheduler);
+    }
+    static void cbfn(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+      C* p = static_cast<C*>(arg);
+      p->f_();
+    }
+    F f_;
+  };
+  return new C(f, scheduler);
+}
+
+#ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
+static void BM_SingleThreadPollOneFd_SpeedOfLight(benchmark::State& state) {
+  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
+  // what the speed of light would be if we abstracted perfectly
+  TrackCounters track_counters;
+  int epfd = epoll_create1(0);
+  GPR_ASSERT(epfd != -1);
+  epoll_event ev[100];
+  int fd = eventfd(0, EFD_NONBLOCK);
+  ev[0].events = EPOLLIN;
+  epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev[0]);
+  while (state.KeepRunning()) {
+    int err;
+    do {
+      err = eventfd_write(fd, 1);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 0);
+    do {
+      err = epoll_wait(epfd, ev, GPR_ARRAY_SIZE(ev), 0);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 1);
+    eventfd_t value;
+    do {
+      err = eventfd_read(fd, &value);
+    } while (err < 0 && errno == EINTR);
+    GPR_ASSERT(err == 0);
+  }
+  close(fd);
+  close(epfd);
+  track_counters.Finish(state);
+}
+BENCHMARK(BM_SingleThreadPollOneFd_SpeedOfLight);
+#endif
+
+static void BM_SingleThreadPollOneFd(benchmark::State& state) {
+  TrackCounters track_counters;
+  size_t ps_sz = grpc_pollset_size();
+  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
+  gpr_mu* mu;
+  grpc_pollset_init(ps, &mu);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  grpc_wakeup_fd wakeup_fd;
+  GRPC_ERROR_UNREF(grpc_wakeup_fd_init(&wakeup_fd));
+  grpc_fd* wakeup = grpc_fd_create(wakeup_fd.read_fd, "wakeup_read");
+  grpc_pollset_add_fd(&exec_ctx, ps, wakeup);
+  bool done = false;
+  Closure* continue_closure = MakeClosure(
+      [&]() {
+        GRPC_ERROR_UNREF(grpc_wakeup_fd_consume_wakeup(&wakeup_fd));
+        if (!state.KeepRunning()) {
+          done = true;
+          return;
+        }
+        GRPC_ERROR_UNREF(grpc_wakeup_fd_wakeup(&wakeup_fd));
+        grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure);
+      },
+      grpc_schedule_on_exec_ctx);
+  GRPC_ERROR_UNREF(grpc_wakeup_fd_wakeup(&wakeup_fd));
+  grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure);
+  gpr_mu_lock(mu);
+  while (!done) {
+    grpc_pollset_worker* worker;
+    GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, &worker, now, deadline));
+  }
+  grpc_fd_orphan(&exec_ctx, wakeup, NULL, NULL, "done");
+  wakeup_fd.read_fd = 0;
+  grpc_closure shutdown_ps_closure;
+  grpc_closure_init(&shutdown_ps_closure, shutdown_ps, ps,
+                    grpc_schedule_on_exec_ctx);
+  grpc_pollset_shutdown(&exec_ctx, ps, &shutdown_ps_closure);
+  gpr_mu_unlock(mu);
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_wakeup_fd_destroy(&wakeup_fd);
+  gpr_free(ps);
+  track_counters.Finish(state);
+  delete continue_closure;
+}
+BENCHMARK(BM_SingleThreadPollOneFd);
+
+BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h
index 2829a46..f44b7cf 100644
--- a/test/cpp/microbenchmarks/helpers.h
+++ b/test/cpp/microbenchmarks/helpers.h
@@ -55,7 +55,9 @@
 
  private:
   Library() {
+#ifdef GPR_LOW_LEVEL_COUNTERS
     grpc_memory_counters_init();
+#endif
     init_lib_.init();
     rq_ = grpc_resource_quota_create("bm");
   }
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index baa9304..25a19a5 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -46,7 +46,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
-#include "src/proto/grpc/testing/payloads.grpc.pb.h"
+#include "src/proto/grpc/testing/payloads.pb.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 
 #include "test/cpp/qps/histogram.h"
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index e72d30a..dd32a16 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -36,7 +36,7 @@
 
 #include <memory>
 
-#include "src/proto/grpc/testing/control.grpc.pb.h"
+#include "src/proto/grpc/testing/control.pb.h"
 #include "test/cpp/qps/histogram.h"
 
 namespace grpc {
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index acb415f..470a394 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -35,7 +35,7 @@
 #define TEST_QPS_HISTOGRAM_H
 
 #include <grpc/support/histogram.h>
-#include "src/proto/grpc/testing/stats.grpc.pb.h"
+#include "src/proto/grpc/testing/stats.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index ddaaa7c..bd2c1f0 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -31,6 +31,7 @@
  *
  */
 
+#include <iostream>
 #include <memory>
 #include <set>
 
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 821d593..8fbf37a 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -38,8 +38,8 @@
 #include <grpc/support/cpu.h>
 #include <vector>
 
-#include "src/proto/grpc/testing/control.grpc.pb.h"
-#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/control.pb.h"
+#include "src/proto/grpc/testing/messages.pb.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/cpp/qps/usage_timer.h"
diff --git a/tools/fuzzer/options/api_fuzzer.options b/tools/fuzzer/options/api_fuzzer.options
new file mode 100644
index 0000000..8871ae2
--- /dev/null
+++ b/tools/fuzzer/options/api_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = api_fuzzer.dictionary
diff --git a/tools/fuzzer/options/client_fuzzer.options b/tools/fuzzer/options/client_fuzzer.options
new file mode 100644
index 0000000..fd2eebf
--- /dev/null
+++ b/tools/fuzzer/options/client_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/fuzzer.options b/tools/fuzzer/options/fuzzer.options
new file mode 100644
index 0000000..5d468bc
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 512
diff --git a/tools/fuzzer/options/fuzzer_response.options b/tools/fuzzer/options/fuzzer_response.options
new file mode 100644
index 0000000..5dcdfac
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer_response.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/fuzzer/options/fuzzer_serverlist.options b/tools/fuzzer/options/fuzzer_serverlist.options
new file mode 100644
index 0000000..5dcdfac
--- /dev/null
+++ b/tools/fuzzer/options/fuzzer_serverlist.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/fuzzer/options/hpack_parser_fuzzer_test.options b/tools/fuzzer/options/hpack_parser_fuzzer_test.options
new file mode 100644
index 0000000..584487f
--- /dev/null
+++ b/tools/fuzzer/options/hpack_parser_fuzzer_test.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 512
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/percent_decode_fuzzer.options b/tools/fuzzer/options/percent_decode_fuzzer.options
new file mode 100644
index 0000000..ea2785e
--- /dev/null
+++ b/tools/fuzzer/options/percent_decode_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 32
diff --git a/tools/fuzzer/options/percent_encode_fuzzer.options b/tools/fuzzer/options/percent_encode_fuzzer.options
new file mode 100644
index 0000000..ea2785e
--- /dev/null
+++ b/tools/fuzzer/options/percent_encode_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 32
diff --git a/tools/fuzzer/options/request_fuzzer.options b/tools/fuzzer/options/request_fuzzer.options
new file mode 100644
index 0000000..fd32ac1
--- /dev/null
+++ b/tools/fuzzer/options/request_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+
diff --git a/tools/fuzzer/options/response_fuzzer.options b/tools/fuzzer/options/response_fuzzer.options
new file mode 100644
index 0000000..fd32ac1
--- /dev/null
+++ b/tools/fuzzer/options/response_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+
diff --git a/tools/fuzzer/options/server_fuzzer.options b/tools/fuzzer/options/server_fuzzer.options
new file mode 100644
index 0000000..fd2eebf
--- /dev/null
+++ b/tools/fuzzer/options/server_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 2048
+dict = hpack.dictionary
diff --git a/tools/fuzzer/options/ssl_server_fuzzer.options b/tools/fuzzer/options/ssl_server_fuzzer.options
new file mode 100644
index 0000000..60bd9b0
--- /dev/null
+++ b/tools/fuzzer/options/ssl_server_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 2048
diff --git a/tools/fuzzer/options/uri_fuzzer_test.options b/tools/fuzzer/options/uri_fuzzer_test.options
new file mode 100644
index 0000000..5dcdfac
--- /dev/null
+++ b/tools/fuzzer/options/uri_fuzzer_test.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 128
diff --git a/tools/gcp/utils/gcr_upload.py b/tools/gcp/utils/gcr_upload.py
new file mode 100755
index 0000000..b22f873
--- /dev/null
+++ b/tools/gcp/utils/gcr_upload.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python2.7
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Upload docker images to Google Container Registry."""
+
+from __future__ import print_function
+
+import argparse
+import atexit
+import os
+import shutil
+import subprocess
+import tempfile
+
+argp = argparse.ArgumentParser(description='Run interop tests.')
+argp.add_argument('--gcr_path',
+                  default='gcr.io/grpc-testing',
+                  help='Path of docker images in Google Container Registry')
+
+argp.add_argument('--gcr_tag',
+                  default='latest',
+                  help='the tag string for the images to upload')
+
+argp.add_argument('--with_files',
+                  default=[],
+                  nargs='+',
+                  help='additional files to include in the docker image')
+
+argp.add_argument('--with_file_dest',
+                  default='/var/local/image_info',
+                  help='Destination directory for with_files inside docker image')
+
+argp.add_argument('--images',
+                  default=[],
+                  nargs='+',
+                  help='local docker images in the form of repo:tag ' +
+                  '(i.e. grpc_interop_java:26328ad8) to upload')
+
+argp.add_argument('--keep',
+                  action='store_true',
+                  help='keep the created local images after uploading to GCR')
+
+
+args = argp.parse_args()
+
+def upload_to_gcr(image):
+  """Tags and Pushes a docker image in Google Containger Registry.
+
+  image: docker image name, i.e. grpc_interop_java:26328ad8
+
+  A docker image image_foo:tag_old will be uploaded as
+     <gcr_path>/image_foo:<gcr_tag>
+  after inserting extra with_files under with_file_dest in the image.  The
+  original image name will be stored as label original_name:"image_foo:tag_old".
+  """
+  tag_idx = image.find(':')
+  if tag_idx == -1:
+    print('Failed to parse docker image name %s' % image)
+    return False
+  new_tag = '%s/%s:%s' % (args.gcr_path, image[:tag_idx], args.gcr_tag)
+
+  lines = ['FROM ' + image]
+  lines.append('LABEL original_name="%s"' % image)
+
+  temp_dir = tempfile.mkdtemp()
+  atexit.register(lambda: subprocess.call(['rm', '-rf', temp_dir]))
+
+  # Copy with_files inside the tmp directory, which will be the docker build
+  # context.
+  for f in args.with_files:
+    shutil.copy(f, temp_dir)
+    lines.append('COPY %s %s/' % (os.path.basename(f), args.with_file_dest))
+
+  # Create a Dockerfile.
+  with open(os.path.join(temp_dir, 'Dockerfile'), 'w') as f:
+     f.write('\n'.join(lines))
+
+  build_cmd = ['docker', 'build', '--rm', '--tag', new_tag, temp_dir]
+  subprocess.check_output(build_cmd)
+
+  if not args.keep:
+    atexit.register(lambda: subprocess.call(['docker', 'rmi', new_tag]))
+
+  # Upload to GCR.
+  if args.gcr_path:
+    subprocess.call(['gcloud', 'docker', '--', 'push', new_tag])
+
+  return True
+
+
+for image in args.images:
+  upload_to_gcr(image)
diff --git a/tools/internal_ci/linux/grpc_master_sanitizers.sh b/tools/internal_ci/linux/grpc_master_sanitizers.sh
index 2cd0efe..d22387f 100755
--- a/tools/internal_ci/linux/grpc_master_sanitizers.sh
+++ b/tools/internal_ci/linux/grpc_master_sanitizers.sh
@@ -37,4 +37,4 @@
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-tools/run_tests/run_tests_matrix.sh -f sanitizers linux
+tools/run_tests/run_tests_matrix.py -f sanitizers linux
diff --git a/tools/internal_ci/linux/grpc_portability.sh b/tools/internal_ci/linux/grpc_portability.sh
index c7ac3bb..58d3c58 100755
--- a/tools/internal_ci/linux/grpc_portability.sh
+++ b/tools/internal_ci/linux/grpc_portability.sh
@@ -37,4 +37,4 @@
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-tools/run_tests/run_tests_matrix.sh -f portability linux
+tools/run_tests/run_tests_matrix.py -f portability linux
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.sh b/tools/internal_ci/linux/grpc_portability_build_only.sh
index edd6f91..80b5c4c 100755
--- a/tools/internal_ci/linux/grpc_portability_build_only.sh
+++ b/tools/internal_ci/linux/grpc_portability_build_only.sh
@@ -37,4 +37,4 @@
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-tools/run_tests/run_tests_matrix.sh -f portability linux --build_only
+tools/run_tests/run_tests_matrix.py -f portability linux --build_only
diff --git a/tools/profiling/latency_profile/run_latency_profile.sh b/tools/profiling/latency_profile/run_latency_profile.sh
index e9baee0..41423fc 100755
--- a/tools/profiling/latency_profile/run_latency_profile.sh
+++ b/tools/profiling/latency_profile/run_latency_profile.sh
@@ -44,4 +44,9 @@
   PYTHON=python2.7
 fi
 
+make CONFIG=opt memory_profile_test memory_profile_client memory_profile_server
+bins/opt/memory_profile_test
+bq load microbenchmarks.memory memory_usage.csv
+
 $PYTHON tools/run_tests/run_microbenchmark.py --collect summary perf latency --bigquery_upload
+
diff --git a/tools/profiling/microbenchmarks/bm_json.py b/tools/profiling/microbenchmarks/bm_json.py
index c48a63b..4695f82 100644
--- a/tools/profiling/microbenchmarks/bm_json.py
+++ b/tools/profiling/microbenchmarks/bm_json.py
@@ -98,6 +98,10 @@
     'tpl': [],
     'dyn': ['request_size'],
   },
+  'BM_PollEmptyPollset_SpeedOfLight': {
+    'tpl': [],
+    'dyn': ['request_size', 'request_count'],
+  }
 }
 
 def numericalize(s):
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index e0658f4..04702ba 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py
index a7535b3..90bbde8 100644
--- a/tools/run_tests/artifacts/distribtest_targets.py
+++ b/tools/run_tests/artifacts/distribtest_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/artifacts/package_targets.py b/tools/run_tests/artifacts/package_targets.py
index d490f57..2547f20 100644
--- a/tools/run_tests/artifacts/package_targets.py
+++ b/tools/run_tests/artifacts/package_targets.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 1dc8606..866d8a5 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -2677,6 +2677,27 @@
   }, 
   {
     "deps": [
+      "benchmark", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_benchmark", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "bm_pollset", 
+    "src": [
+      "test/cpp/microbenchmarks/bm_pollset.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
       "gpr", 
       "grpc", 
       "grpc++"
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 1eebc9a..b81b98b 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1834,7 +1834,9 @@
     ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
-    "exclude_iomgrs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
@@ -2890,6 +2892,28 @@
     ]
   }, 
   {
+    "args": [
+      "--benchmark_min_time=0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "bm_pollset", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
     "args": [], 
     "ci_platforms": [
       "linux", 
@@ -39683,31 +39707,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1024, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -39758,31 +39757,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -39833,31 +39807,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1024, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -39908,31 +39857,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40112,31 +40036,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1024, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40187,31 +40086,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40262,31 +40136,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1024, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40337,31 +40186,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "tsan", 
-      "asan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40618,42 +40442,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 64, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40726,42 +40514,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40834,42 +40586,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 64, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -40942,42 +40658,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -41234,42 +40914,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 64, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -41342,42 +40986,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -41450,42 +41058,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 64, 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
@@ -41557,42 +41129,6 @@
   }, 
   {
     "args": [
-      "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": "capacity", 
-    "defaults": "boringssl", 
-    "exclude_configs": [
-      "asan-noleaks", 
-      "asan-trace-cmp", 
-      "basicprof", 
-      "counters", 
-      "dbg", 
-      "gcov", 
-      "helgrind", 
-      "memcheck", 
-      "msan", 
-      "mutrace", 
-      "opt", 
-      "stapprof", 
-      "ubsan"
-    ], 
-    "excluded_poll_engines": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota_low_thread_count", 
-    "timeout_seconds": 360
-  }, 
-  {
-    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/00.bin"
     ], 
     "ci_platforms": [
diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py
index 89d2a9b..3bac119 100755
--- a/tools/run_tests/performance/bq_upload_result.py
+++ b/tools/run_tests/performance/bq_upload_result.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 # Uploads performance benchmark result file to bigquery.
 
+from __future__ import print_function
+
 import argparse
 import calendar
 import json
@@ -70,7 +72,7 @@
   _create_results_table(bq, dataset_id, table_id)
 
   if not _insert_result(bq, dataset_id, table_id, scenario_result, flatten=False):
-    print 'Error uploading result to bigquery.'
+    print('Error uploading result to bigquery.')
     sys.exit(1)
 
 
@@ -82,7 +84,7 @@
   _create_results_table(bq, dataset_id, table_id)
 
   if not _insert_result(bq, dataset_id, table_id, scenario_result):
-    print 'Error uploading result to bigquery.'
+    print('Error uploading result to bigquery.')
     sys.exit(1)
 
 
@@ -179,4 +181,4 @@
   _upload_netperf_latency_csv_to_bigquery(dataset_id, table_id, args.file_to_upload)
 else:
   _upload_scenario_result_to_bigquery(dataset_id, table_id, args.file_to_upload)
-print 'Successfully uploaded %s to BigQuery.\n' % args.file_to_upload
+print('Successfully uploaded %s to BigQuery.\n' % args.file_to_upload)
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 830b8c0..1d91b61 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -275,15 +275,18 @@
               secure=secure,
               categories=smoketest_categories+[SCALABLE])
 
-          yield _ping_pong_scenario(
-              'cpp_protobuf_%s_%s_qps_unconstrained_%s_500kib_resource_quota' % (synchronicity, rpc_type, secstr),
-              rpc_type=rpc_type.upper(),
-              client_type='%s_CLIENT' % synchronicity.upper(),
-              server_type='%s_SERVER' % synchronicity.upper(),
-              unconstrained_client=synchronicity,
-              secure=secure,
-              categories=smoketest_categories+[SCALABLE],
-              resource_quota_size=500*1024)
+          # TODO(vjpai): Re-enable this test. It has a lot of timeouts
+          # and hasn't yet been conclusively identified as a test failure
+          # or race in the library
+          # yield _ping_pong_scenario(
+          #     'cpp_protobuf_%s_%s_qps_unconstrained_%s_500kib_resource_quota' % (synchronicity, rpc_type, secstr),
+          #     rpc_type=rpc_type.upper(),
+          #     client_type='%s_CLIENT' % synchronicity.upper(),
+          #     server_type='%s_SERVER' % synchronicity.upper(),
+          #     unconstrained_client=synchronicity,
+          #     secure=secure,
+          #     categories=smoketest_categories+[SCALABLE],
+          #     resource_quota_size=500*1024)
 
           for channels in geometric_progression(1, 20000, math.sqrt(10)):
             for outstanding in geometric_progression(1, 200000, math.sqrt(10)):
diff --git a/tools/run_tests/python_utils/antagonist.py b/tools/run_tests/python_utils/antagonist.py
index 857addf..111839c 100755
--- a/tools/run_tests/python_utils/antagonist.py
+++ b/tools/run_tests/python_utils/antagonist.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/python_utils/filter_pull_request_tests.py b/tools/run_tests/python_utils/filter_pull_request_tests.py
index 3734f02..e013376 100644
--- a/tools/run_tests/python_utils/filter_pull_request_tests.py
+++ b/tools/run_tests/python_utils/filter_pull_request_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -30,7 +30,10 @@
 
 """Filter out tests based on file differences compared to merge target branch"""
 
+from __future__ import print_function
+
 import re
+import six
 from subprocess import check_output
 
 
@@ -125,7 +128,7 @@
 }
 
 # Add all triggers to their respective test suites
-for trigger, test_suites in _WHITELIST_DICT.iteritems():
+for trigger, test_suites in six.iteritems(_WHITELIST_DICT):
   for test_suite in test_suites:
     test_suite.add_trigger(trigger)
 
diff --git a/tools/run_tests/python_utils/port_server.py b/tools/run_tests/python_utils/port_server.py
index e9b3f7f..dbd32ef 100755
--- a/tools/run_tests/python_utils/port_server.py
+++ b/tools/run_tests/python_utils/port_server.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/python_utils/report_utils.py b/tools/run_tests/python_utils/report_utils.py
index 9dad604..131772f 100644
--- a/tools/run_tests/python_utils/report_utils.py
+++ b/tools/run_tests/python_utils/report_utils.py
@@ -40,6 +40,7 @@
 import os
 import string
 import xml.etree.cElementTree as ET
+import six
 
 
 def _filter_msg(msg, output_format):
@@ -63,7 +64,7 @@
   root = ET.Element('testsuites')
   testsuite = ET.SubElement(root, 'testsuite', id='1', package=suite_package,
                             name=suite_name)
-  for shortname, results in resultset.iteritems():
+  for shortname, results in six.iteritems(resultset):
     for result in results:
       xml_test = ET.SubElement(testsuite, 'testcase', name=shortname)
       if result.elapsed_time:
diff --git a/tools/run_tests/run_build_statistics.py b/tools/run_tests/run_build_statistics.py
index 654cf95..dd11a45 100755
--- a/tools/run_tests/run_build_statistics.py
+++ b/tools/run_tests/run_build_statistics.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 """Tool to get build statistics from Jenkins and upload to BigQuery."""
 
+from __future__ import print_function
+
 import argparse
 import jenkinsapi
 from jenkinsapi.custom_exceptions import JenkinsAPIException
@@ -243,6 +245,6 @@
     rows = [big_query_utils.make_row(build_number, build_result)]
     if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, build_name, 
                                        rows):
-      print '====> Error uploading result to bigquery.'
+      print('====> Error uploading result to bigquery.')
       sys.exit(1)
 
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 161fa81..29d5a9a 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -44,6 +44,7 @@
 import tempfile
 import time
 import uuid
+import six
 
 import python_utils.dockerjob as dockerjob
 import python_utils.jobset as jobset
@@ -885,7 +886,7 @@
 
 languages = set(_LANGUAGES[l]
                 for l in itertools.chain.from_iterable(
-                    _LANGUAGES.iterkeys() if x == 'all' else [x]
+                    six.iterkeys(_LANGUAGES) if x == 'all' else [x]
                     for x in args.language))
 
 languages_http2_badserver_interop = set()
@@ -925,7 +926,7 @@
     else:
       jobset.message('FAILED', 'Failed to build interop docker images.',
                      do_newline=True)
-      for image in docker_images.itervalues():
+      for image in six.itervalues(docker_images):
         dockerjob.remove_image(image, skip_nonexistent=True)
       sys.exit(1)
 
@@ -1053,7 +1054,7 @@
 
   if not jobs:
     print('No jobs to run.')
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
@@ -1093,9 +1094,9 @@
     if not job.is_running():
       print('Server "%s" has exited prematurely.' % server)
 
-  dockerjob.finish_jobs([j for j in server_jobs.itervalues()])
+  dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)])
 
-  for image in docker_images.itervalues():
+  for image in six.itervalues(docker_images):
     if not args.manual_run:
       print('Removing docker image %s' % image)
       dockerjob.remove_image(image)
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 9471110..57b2636 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2017, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index ee4102c..35d20be 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
@@ -46,6 +46,7 @@
 import time
 import traceback
 import uuid
+import six
 
 import performance.scenario_config as scenario_config
 import python_utils.jobset as jobset
@@ -502,8 +503,8 @@
 
 languages = set(scenario_config.LANGUAGES[l]
                 for l in itertools.chain.from_iterable(
-                      scenario_config.LANGUAGES.iterkeys() if x == 'all' else [x]
-                      for x in args.language))
+                      six.iterkeys(scenario_config.LANGUAGES) if x == 'all'
+                      else [x] for x in args.language))
 
 
 # Put together set of remote hosts where to run and build
@@ -572,8 +573,8 @@
         jobs.append(create_quit_jobspec(scenario.workers, remote_host=args.remote_driver_host))
       scenario_failures, resultset = jobset.run(jobs, newline_on_success=True, maxjobs=1)
       total_scenario_failures += scenario_failures
-      merged_resultset = dict(itertools.chain(merged_resultset.iteritems(),
-                                              resultset.iteritems()))
+      merged_resultset = dict(itertools.chain(six.iteritems(merged_resultset),
+                                              six.iteritems(resultset)))
     finally:
       # Consider qps workers that need to be killed as failures
       qps_workers_killed += finish_qps_workers(scenario.workers)
diff --git a/tools/run_tests/run_stress_tests.py b/tools/run_tests/run_stress_tests.py
index a94a615..4eea021 100755
--- a/tools/run_tests/run_stress_tests.py
+++ b/tools/run_tests/run_stress_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -43,6 +43,7 @@
 import tempfile
 import time
 import uuid
+import six
 
 import python_utils.dockerjob as dockerjob
 import python_utils.jobset as jobset
@@ -239,9 +240,8 @@
     for s in itertools.chain.from_iterable(_SERVERS if x == 'all' else [x]
                                            for x in args.server))
 
-languages = set(_LANGUAGES[l]
-                for l in itertools.chain.from_iterable(_LANGUAGES.iterkeys(
-                ) if x == 'all' else [x] for x in args.language))
+languages = set(_LANGUAGES[l] for l in itertools.chain.from_iterable(
+  six.iterkeys(_LANGUAGES) if x == 'all' else [x] for x in args.language))
 
 docker_images = {}
 # languages for which to build docker images
@@ -267,7 +267,7 @@
     jobset.message('FAILED',
                    'Failed to build interop docker images.',
                    do_newline=True)
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
@@ -306,7 +306,7 @@
 
   if not jobs:
     print('No jobs to run.')
-    for image in docker_images.itervalues():
+    for image in six.itervalues(docker_images):
       dockerjob.remove_image(image, skip_nonexistent=True)
     sys.exit(1)
 
@@ -324,8 +324,8 @@
     if not job.is_running():
       print('Server "%s" has exited prematurely.' % server)
 
-  dockerjob.finish_jobs([j for j in server_jobs.itervalues()])
+  dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)])
 
-  for image in docker_images.itervalues():
+  for image in six.itervalues(docker_images):
     print('Removing docker image %s' % image)
     dockerjob.remove_image(image)
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 43b8f81..cba91a9 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -54,6 +54,7 @@
 import time
 from six.moves import urllib
 import uuid
+import six
 
 import python_utils.jobset as jobset
 import python_utils.report_utils as report_utils
@@ -771,7 +772,7 @@
         runtime_cmd = ['mono']
 
     specs = []
-    for assembly in tests_by_assembly.iterkeys():
+    for assembly in six.iterkeys(tests_by_assembly):
       assembly_file = 'src/csharp/%s/%s/%s%s' % (assembly,
                                                  assembly_subdir,
                                                  assembly,
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 4742245..b9bf6e5 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -30,6 +30,8 @@
 
 """Run test matrix."""
 
+from __future__ import print_function
+
 import argparse
 import multiprocessing
 import os
@@ -95,19 +97,19 @@
       for config in configs:
         name = '%s_%s_%s_%s' % (language, platform, config, iomgr_platform)
         runtests_args = ['-l', language,
-                         '-c', config]
+                         '-c', config,
+                         '--iomgr_platform', iomgr_platform]
         if arch or compiler:
           name += '_%s_%s' % (arch, compiler)
           runtests_args += ['--arch', arch,
                             '--compiler', compiler]
-
         runtests_args += extra_args
         if platform == 'linux':
           job = _docker_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
         else:
           job = _workspace_jobspec(name=name, runtests_args=runtests_args, inner_jobs=inner_jobs)
 
-        job.labels = [platform, config, language] + labels
+        job.labels = [platform, config, language, iomgr_platform] + labels
         result.append(job)
   return result
 
@@ -415,8 +417,8 @@
                                        maxjobs=args.jobs)
   # Merge skipped tests into results to show skipped tests on report.xml
   if skipped_jobs:
-    skipped_results = jobset.run(skipped_jobs,
-                                 skip_jobs=True)
+    ignored_num_skipped_failures, skipped_results = jobset.run(
+        skipped_jobs, skip_jobs=True)
     resultset.update(skipped_results)
   report_utils.render_junit_xml_report(resultset, 'report_%s' % _REPORT_SUFFIX,
                                        suite_name='aggregate_tests')
diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
index a86db02..f2e0bfe 100755
--- a/tools/run_tests/sanity/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -28,6 +28,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+from __future__ import print_function
+
 import json
 import os
 import re
diff --git a/tools/run_tests/sanity/check_test_filtering.py b/tools/run_tests/sanity/check_test_filtering.py
index 290a6e2..ba03f11 100755
--- a/tools/run_tests/sanity/check_test_filtering.py
+++ b/tools/run_tests/sanity/check_test_filtering.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -62,7 +62,7 @@
     def _get_changed_files(foo):
       return changed_files
     filter_pull_request_tests._get_changed_files = _get_changed_files
-    print
+    print()
     filtered_jobs = filter_pull_request_tests.filter_tests(all_jobs, "test")
 
     # Make sure sanity tests aren't being filtered out
diff --git a/tools/run_tests/sanity/check_version.py b/tools/run_tests/sanity/check_version.py
index e62f390..d247260 100755
--- a/tools/run_tests/sanity/check_version.py
+++ b/tools/run_tests/sanity/check_version.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -29,6 +29,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+from __future__ import print_function
+
 import sys
 import yaml
 import os
@@ -48,13 +50,13 @@
     'git rev-parse --abbrev-ref HEAD',
     shell=True)
 except:
-  print 'WARNING: not a git repository'
+  print('WARNING: not a git repository')
   branch_name = None
 
 if branch_name is not None:
   m = re.match(r'^release-([0-9]+)_([0-9]+)$', branch_name)
   if m:
-    print 'RELEASE branch'
+    print('RELEASE branch')
     # version number should align with the branched version
     check_version = lambda version: (
       version.major == int(m.group(1)) and
@@ -78,7 +80,7 @@
 top_version = Version(settings['version'])
 if not check_version(top_version):
   errors += 1
-  print warning % ('version', top_version)
+  print(warning % ('version', top_version))
 
 for tag, value in settings.iteritems():
   if re.match(r'^[a-z]+_version$', tag):
@@ -86,12 +88,14 @@
     if tag != 'core_version':
       if value.major != top_version.major:
         errors += 1
-        print 'major version mismatch on %s: %d vs %d' % (tag, value.major, top_version.major)
+        print('major version mismatch on %s: %d vs %d' % (tag, value.major,
+                                                          top_version.major))
       if value.minor != top_version.minor:
         errors += 1
-        print 'minor version mismatch on %s: %d vs %d' % (tag, value.minor, top_version.minor)
+        print('minor version mismatch on %s: %d vs %d' % (tag, value.minor,
+                                                          top_version.minor))
     if not check_version(value):
       errors += 1
-      print warning % (tag, value)
+      print(warning % (tag, value))
 
 sys.exit(errors)
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index 6d9be2e..c3c3cbe 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -29,6 +29,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+from __future__ import print_function
+
 import os
 import sys
 
@@ -60,7 +62,7 @@
     for banned, exceptions in BANNED_EXCEPT.items():
       if path in exceptions: continue
       if banned in text:
-        print 'Illegal use of "%s" in %s' % (banned, path)
+        print('Illegal use of "%s" in %s' % (banned, path))
         errors += 1
 
 assert errors == 0
diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py
index e33ac12..bfd7222 100755
--- a/tools/run_tests/start_port_server.py
+++ b/tools/run_tests/start_port_server.py
@@ -39,8 +39,10 @@
 an error message to users.
 """
 
+from __future__ import print_function
+
 import python_utils.start_port_server as start_port_server
 
 start_port_server.start_port_server()
 
-print "Port server started successfully"
+print("Port server started successfully")
diff --git a/tools/run_tests/stress_test/print_summary.py b/tools/run_tests/stress_test/print_summary.py
index cb1a339..6f4ada2 100755
--- a/tools/run_tests/stress_test/print_summary.py
+++ b/tools/run_tests/stress_test/print_summary.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
diff --git a/tools/run_tests/stress_test/run_on_gke.py b/tools/run_tests/stress_test/run_on_gke.py
index e2be76e..b190ebd 100755
--- a/tools/run_tests/stress_test/run_on_gke.py
+++ b/tools/run_tests/stress_test/run_on_gke.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
@@ -27,6 +27,9 @@
 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from __future__ import print_function
+
 import argparse
 import datetime
 import json
@@ -124,23 +127,24 @@
     return 'gcr.io/%s/%s' % (project_id, image_name)
 
   def build_image(self):
-    print 'Building docker image: %s (tag: %s)' % (self.image_name,
-                                                   self.tag_name)
+    print('Building docker image: %s (tag: %s)' % (self.image_name,
+                                                   self.tag_name))
     os.environ['INTEROP_IMAGE'] = self.image_name
     os.environ['INTEROP_IMAGE_REPOSITORY_TAG'] = self.tag_name
     os.environ['BASE_NAME'] = self.dockerfile_dir
     os.environ['BUILD_TYPE'] = self.build_type
-    print 'DEBUG: path: ', self.build_script_path
+    print('DEBUG: path: ', self.build_script_path)
     if subprocess.call(args=[self.build_script_path]) != 0:
-      print 'Error in building the Docker image'
+      print('Error in building the Docker image')
       return False
     return True
 
   def push_to_gke_registry(self):
     cmd = ['gcloud', 'docker', 'push', self.tag_name]
-    print 'Pushing %s to the GKE registry..' % self.tag_name
+    print('Pushing %s to the GKE registry..' % self.tag_name)
     if subprocess.call(args=cmd) != 0:
-      print 'Error in pushing the image %s to the GKE registry' % self.tag_name
+      print('Error in pushing the image %s to the GKE registry' %
+            self.tag_name)
       return False
     return True
 
@@ -199,11 +203,11 @@
       cmd = ['kubectl', 'proxy', '--port=%d' % port]
       self.p = subprocess.Popen(args=cmd)
       time.sleep(2)
-      print '\nStarted kubernetes proxy on port: %d' % port
+      print('\nStarted kubernetes proxy on port: %d' % port)
 
     def __del__(self):
       if self.p is not None:
-        print 'Shutting down Kubernetes proxy..'
+        print('Shutting down Kubernetes proxy..')
         self.p.kill()
 
   def __init__(self, project_id, run_id, dataset_id, summary_table_id,
@@ -253,7 +257,7 @@
 
     for pod_name in server_pod_spec.pod_names():
       server_env['POD_NAME'] = pod_name
-      print 'Creating server: %s' % pod_name
+      print('Creating server: %s' % pod_name)
       is_success = kubernetes_api.create_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -267,11 +271,11 @@
           True  # Headless = True for server to that GKE creates a DNS record for pod_name
       )
       if not is_success:
-        print 'Error in launching server: %s' % pod_name
+        print('Error in launching server: %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully created server(s)'
+      print('Successfully created server(s)')
 
     return is_success
 
@@ -301,7 +305,7 @@
 
     for pod_name in client_pod_spec.pod_names():
       client_env['POD_NAME'] = pod_name
-      print 'Creating client: %s' % pod_name
+      print('Creating client: %s' % pod_name)
       is_success = kubernetes_api.create_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -316,18 +320,18 @@
       )
 
       if not is_success:
-        print 'Error in launching client %s' % pod_name
+        print('Error in launching client %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully created all client(s)'
+      print('Successfully created all client(s)')
 
     return is_success
 
   def _delete_pods(self, pod_name_list):
     is_success = True
     for pod_name in pod_name_list:
-      print 'Deleting %s' % pod_name
+      print('Deleting %s' % pod_name)
       is_success = kubernetes_api.delete_pod_and_service(
           'localhost',
           self.kubernetes_port,
@@ -335,11 +339,11 @@
           pod_name)
 
       if not is_success:
-        print 'Error in deleting pod %s' % pod_name
+        print('Error in deleting pod %s' % pod_name)
         break
 
     if is_success:
-      print 'Successfully deleted all pods'
+      print('Successfully deleted all pods')
 
     return is_success
 
@@ -353,7 +357,7 @@
 class Config:
 
   def __init__(self, config_filename, gcp_project_id):
-    print 'Loading configuration...'
+    print('Loading configuration...')
     config_dict = self._load_config(config_filename)
 
     self.global_settings = self._parse_global_settings(config_dict,
@@ -367,7 +371,7 @@
     self.client_pod_specs_dict = self._parse_client_pod_specs(
         config_dict, self.docker_images_dict, self.client_templates_dict,
         self.server_pod_specs_dict)
-    print 'Loaded Configuaration.'
+    print('Loaded Configuaration.')
 
   def _parse_global_settings(self, config_dict, gcp_project_id):
     global_settings_dict = config_dict['globalSettings']
@@ -540,8 +544,8 @@
   # run id. This is useful in debugging when looking at records in Biq query)
   run_id = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
   dataset_id = '%s_%s' % (config.global_settings.dataset_id_prefix, run_id)
-  print 'Run id:', run_id
-  print 'Dataset id:', dataset_id
+  print('Run id:', run_id)
+  print('Dataset id:', dataset_id)
 
   bq_helper = BigQueryHelper(run_id, '', '',
                              config.global_settings.gcp_project_id, dataset_id,
@@ -557,7 +561,7 @@
   is_success = True
 
   try:
-    print 'Launching servers..'
+    print('Launching servers..')
     for name, server_pod_spec in config.server_pod_specs_dict.iteritems():
       if not gke.launch_servers(server_pod_spec):
         is_success = False  # is_success is checked in the 'finally' block
@@ -579,11 +583,12 @@
     start_time = datetime.datetime.now()
     end_time = start_time + datetime.timedelta(
         seconds=config.global_settings.test_duration_secs)
-    print 'Running the test until %s' % end_time.isoformat()
+    print('Running the test until %s' % end_time.isoformat())
 
     while True:
       if datetime.datetime.now() > end_time:
-        print 'Test was run for %d seconds' % config.global_settings.test_duration_secs
+        print('Test was run for %d seconds' %
+              config.global_settings.test_duration_secs)
         break
 
       # Check if either stress server or clients have failed (btw, the bq_helper
@@ -591,11 +596,12 @@
       # have a failure status)
       if bq_helper.check_if_any_tests_failed():
         is_success = False
-        print 'Some tests failed.'
+        print('Some tests failed.')
         break  # Don't 'return' here. We still want to call bq_helper to print qps/summary tables
 
       # Tests running fine. Wait until next poll time to check the status
-      print 'Sleeping for %d seconds..' % config.global_settings.test_poll_interval_secs
+      print('Sleeping for %d seconds..' %
+            config.global_settings.test_poll_interval_secs)
       time.sleep(config.global_settings.test_poll_interval_secs)
 
     # Print BiqQuery tables
diff --git a/tools/run_tests/task_runner.py b/tools/run_tests/task_runner.py
index fdc4668..0ec7efb 100755
--- a/tools/run_tests/task_runner.py
+++ b/tools/run_tests/task_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #