diff --git a/.pylintrc b/.pylintrc
index 04c0088c88e50f1e5299255bc338fdeec4d742f7..41027479061b42b3bbf67015f0e64449baa4e67b 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -3,6 +3,12 @@
 # not include "unused_" and "ignored_" by default?
 dummy-variables-rgx=^ignored_|^unused_
 
+[DESIGN]
+# NOTE(nathaniel): Not particularly attached to this value; it just seems to
+# be what works for us at the moment (excepting the dead-code-walking Beta
+# API).
+max-args=6
+
 [MISCELLANEOUS]
 # NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
 # "NOTE(<username or issue link>): ". We do not allow "TODO:",
@@ -13,28 +19,22 @@ notes=FIXME,XXX
 
 #TODO: Enable missing-docstring
 #TODO: Enable too-few-public-methods
-#TODO: Enable too-many-arguments
 #TODO: Enable no-init
 #TODO: Enable duplicate-code
 #TODO: Enable invalid-name
-#TODO: Enable suppressed-message
 #TODO: Enable locally-disabled
 #TODO: Enable protected-access
 #TODO: Enable no-name-in-module
-#TODO: Enable unused-argument
 #TODO: Enable wrong-import-order
 # TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
 # enable cyclic-import after a 1.7-or-later pylint release that recognizes our
 # disable=cyclic-import suppressions.
 #TODO: Enable too-many-instance-attributes
-#TODO: Enable too-many-locals
 #TODO: Enable too-many-lines
 #TODO: Enable redefined-variable-type
 #TODO: Enable next-method-called
 #TODO: Enable import-error
 #TODO: Enable useless-else-on-loop
-#TODO: Enable too-many-return-statements
 #TODO: Enable too-many-nested-blocks
-#TODO: Enable super-init-not-called
 
-disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called
+disable=missing-docstring,too-few-public-methods,no-init,duplicate-code,invalid-name,locally-disabled,protected-access,no-name-in-module,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-nested-blocks
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24b84fd15a8040898e55d763cc3895e60fbd3acf..d3a76a29d76fc1c7969b4fbe8a5f9834cada50d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7967,7 +7967,9 @@ target_link_libraries(bm_metadata
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc_benchmark
   benchmark
+  grpc++_test_util
   grpc_test_util
+  grpc++
   grpc
   gpr_test_util
   gpr
diff --git a/Makefile b/Makefile
index a49fa928aacaf4e8c63127b2278447b64a15b0eb..3cffa73224bc71abd94d99187f0d7a0ec826198f 100644
--- a/Makefile
+++ b/Makefile
@@ -13002,16 +13002,16 @@ $(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_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_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.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_metadata
+	$(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_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_metadata
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o:  $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.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_metadata: $(BM_METADATA_OBJS:.o=.dep)
 
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
index b9d7eb5902b8c1dbb895c1dc4cf5a1402fd325fc..ab1add476e1cbcb50237eaf5b669d69b90b5e958 100644
--- a/bazel/cc_grpc_library.bzl
+++ b/bazel/cc_grpc_library.bzl
@@ -2,7 +2,7 @@
 
 load("//:bazel/generate_cc.bzl", "generate_cc")
 
-def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs):
+def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_external = False, **kwargs):
   """Generates C++ grpc classes from a .proto file.
 
   Assumes the generated classes will be used in cc_api_version = 2.
@@ -12,6 +12,9 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
       srcs: a single proto_library, which wraps the .proto files with services.
       deps: a list of C++ proto_library (or cc_proto_library) which provides
         the compiled code of any message that the services depend on.
+      well_known_protos: The target from protobuf library that exports well
+        known protos. Currently it will only work if the value is
+        "@submodule_protobuf//:well_known_protos"
       use_external: When True the grpc deps are prefixed with //external. This
         allows grpc to be used as a dependency in other bazel projects.
       **kwargs: rest of arguments, e.g., compatible_with and visibility.
@@ -35,6 +38,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
   generate_cc(
       name = codegen_target,
       srcs = [proto_target],
+      well_known_protos = well_known_protos,
       **kwargs
   )
 
@@ -49,6 +53,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs
         name = codegen_grpc_target,
         srcs = [proto_target],
         plugin = plugin,
+        well_known_protos = well_known_protos,
         **kwargs
     )
 
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index d49cbe8d7289e8f4355f59f8f794d5dcaa2b303b..f3961f0a4197f5e2bb3e0d7ce1857bd120fe3eaf 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -31,8 +31,20 @@ def generate_cc_impl(ctx):
   arguments += ["-I{0}={0}".format(include.path) for include in includes]
   arguments += [proto.path for proto in protos]
 
+  # create a list of well known proto files if the argument is non-None
+  well_known_proto_files = []
+  if ctx.attr.well_known_protos:
+    f = ctx.attr.well_known_protos.files.to_list()[0].dirname
+    if f != "external/submodule_protobuf/src/google/protobuf":
+      print("Error: Only @submodule_protobuf//:well_known_protos is supported")
+    else:
+      # f points to "external/submodule_protobuf/src/google/protobuf"
+      # add -I argument to protoc so it knows where to look for the proto files.
+      arguments += ["-I{0}".format(f + "/../..")]
+      well_known_proto_files = [f for f in ctx.attr.well_known_protos.files]
+
   ctx.action(
-      inputs = protos + includes + additional_input,
+      inputs = protos + includes + additional_input + well_known_proto_files,
       outputs = out_files,
       executable = ctx.executable._protoc,
       arguments = arguments,
@@ -56,6 +68,9 @@ generate_cc = rule(
             mandatory = False,
             allow_empty = True,
         ),
+        "well_known_protos" : attr.label(
+            mandatory = False,
+        ),
         "_protoc": attr.label(
             default = Label("//external:protocol_compiler"),
             executable = True,
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 855d2d7b72335c7769561d4cd974de8f6623d0e5..8b524bd0e52023468a4f1379bc881587ea0e4a17 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -58,11 +58,13 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
 
 load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
 
-def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True, use_external = False):
+def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
+                       has_services = True, use_external = False):
   cc_grpc_library(
     name = name,
     srcs = srcs,
     deps = deps,
+    well_known_protos = well_known_protos,
     proto_only = not has_services,
     use_external = use_external,
   )
diff --git a/build.yaml b/build.yaml
index 106e876a5168a5395f367d6c96cd89bd0436b7c6..dc69998cccbc5aa8f62512c4443ff217f0d2edfd 100644
--- a/build.yaml
+++ b/build.yaml
@@ -3243,7 +3243,9 @@ targets:
   deps:
   - grpc_benchmark
   - benchmark
+  - grpc++_test_util
   - grpc_test_util
+  - grpc++
   - grpc
   - gpr_test_util
   - gpr
diff --git a/requirements.txt b/requirements.txt
index bf87de07f894084ce57e7bd5d785a794bb4ff130..12969958aeeac640956c836c018252ac582dce04 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ coverage>=4.0
 cython>=0.23
 enum34>=1.0.4
 futures>=2.2.0
-protobuf>=3.0.0
+protobuf>=3.2.0
 six>=1.10
 wheel>=0.29
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 2a1c8d39fae1cd08fa58f6e38e1abda33a0c4630..d1bcd89af1f0b07d9ffb25de8fc459423992774f 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -485,7 +485,11 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
                       grpc_schedule_on_exec_ctx);
     grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
 
-    s->active_ports++;
+    /* Registered for both read and write callbacks: increment active_ports
+     * twice to account for this, and delay free-ing of memory until both
+     * on_read and on_write have fired. */
+    s->active_ports += 2;
+
     sp = sp->next;
   }
 
diff --git a/src/csharp/Grpc.Core.Tests/TestResult.xml b/src/csharp/Grpc.Core.Tests/TestResult.xml
deleted file mode 100644
index 13da80739ceead3bd6e8477089ed94a9165d0a9b..0000000000000000000000000000000000000000
--- a/src/csharp/Grpc.Core.Tests/TestResult.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!--This file represents the results of running a test suite-->
-<test-results name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" total="3" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2015-01-29" time="19:40:47">
-  <environment nunit-version="2.6.0.0" clr-version="4.0.30319.17020" os-version="Unix 3.13.0.43" platform="Unix" cwd="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests" machine-name="jtattermusch.mtv.corp.google.com" user="jtattermusch" user-domain="jtattermusch.mtv.corp.google.com" />
-  <culture-info current-culture="en-US" current-uiculture="en-US" />
-  <test-suite type="Assembly" name="/usr/local/google/home/jtattermusch/github/grpc/src/csharp/GrpcCoreTests/bin/Debug/GrpcCoreTests.dll" executed="True" result="Success" success="True" time="0.172" asserts="0">
-    <results>
-      <test-suite type="Namespace" name="Google" executed="True" result="Success" success="True" time="0.166" asserts="0">
-        <results>
-          <test-suite type="Namespace" name="GRPC" executed="True" result="Success" success="True" time="0.166" asserts="0">
-            <results>
-              <test-suite type="Namespace" name="Core" executed="True" result="Success" success="True" time="0.166" asserts="0">
-                <results>
-                  <test-suite type="Namespace" name="Tests" executed="True" result="Success" success="True" time="0.166" asserts="0">
-                    <results>
-                      <test-suite type="TestFixture" name="CallsTest" executed="True" result="Success" success="True" time="0.009" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.CallsTest.Test1" executed="True" result="Success" success="True" time="0.004" asserts="0" />
-                        </results>
-                      </test-suite>
-                      <test-suite type="TestFixture" name="ClientServerTest" executed="True" result="Success" success="True" time="0.149" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.ClientServerTest.EmptyCall" executed="True" result="Success" success="True" time="0.111" asserts="0" />
-                        </results>
-                      </test-suite>
-                      <test-suite type="TestFixture" name="ServerTest" executed="True" result="Success" success="True" time="0.001" asserts="0">
-                        <results>
-                          <test-case name="Grpc.Core.Tests.ServerTest.StartAndShutdownServer" executed="True" result="Success" success="True" time="0.001" asserts="0" />
-                        </results>
-                      </test-suite>
-                    </results>
-                  </test-suite>
-                </results>
-              </test-suite>
-            </results>
-          </test-suite>
-        </results>
-      </test-suite>
-    </results>
-  </test-suite>
-</test-results>
\ No newline at end of file
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index c86cb25682ba6b837adcd805117569e8f1164ff9..4316449ac65d4d701a070183bd061eaba4274ec4 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -237,7 +237,7 @@ def _consume_request_iterator(request_iterator, state, call,
                     cygrpc.Operations(operations), event_handler)
                 state.due.add(cygrpc.OperationType.send_close_from_client)
 
-    def stop_consumption_thread(timeout):
+    def stop_consumption_thread(timeout):  # pylint: disable=unused-argument
         with state.condition:
             if state.code is None:
                 call.cancel()
@@ -736,7 +736,7 @@ def _run_channel_spin_thread(state):
                         state.managed_calls = None
                         return
 
-    def stop_channel_spin(timeout):
+    def stop_channel_spin(timeout):  # pylint: disable=unused-argument
         with state.lock:
             if state.managed_calls is not None:
                 for call in state.managed_calls:
@@ -877,12 +877,8 @@ def _moot(state):
 def _subscribe(state, callback, try_to_connect):
     with state.lock:
         if not state.callbacks_and_connectivities and not state.polling:
-
-            def cancel_all_subscriptions(timeout):
-                _moot(state)
-
             polling_thread = _common.CleanupThread(
-                cancel_all_subscriptions,
+                lambda timeout: _moot(state),
                 target=_poll_connectivity,
                 args=(state, state.channel, bool(try_to_connect)))
             polling_thread.start()
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
index 901cb856124c34d06a71ba046a2bd04730f026bc..3c69acc019527857c64aba97c8c6f64290eac59c 100644
--- a/src/python/grpcio/grpc/beta/_client_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -35,6 +35,8 @@ from grpc.framework.common import cardinality
 from grpc.framework.foundation import future
 from grpc.framework.interfaces.face import face
 
+# pylint: disable=too-many-arguments,too-many-locals,unused-argument
+
 _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
     grpc.StatusCode.CANCELLED: (face.Abortion.Kind.CANCELLED,
                                 face.CancellationError),
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index 81348d5d87ff5cb00b57c51597e2c4d231d3b077..cf10c26d2fe0aa906e02f50ce0d360606c388d4b 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -41,6 +41,8 @@ from grpc.framework.foundation import logging_pool
 from grpc.framework.foundation import stream
 from grpc.framework.interfaces.face import face
 
+# pylint: disable=too-many-return-statements
+
 _DEFAULT_POOL_SIZE = 8
 
 
@@ -179,7 +181,7 @@ def _run_request_pipe_thread(request_iterator, request_consumer,
                 return
         request_consumer.terminate()
 
-    def stop_request_pipe(timeout):
+    def stop_request_pipe(timeout):  # pylint: disable=unused-argument
         thread_joined.set()
 
     request_pipe_thread = _common.CleanupThread(
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index 0b7957768900b0bc8196156322b084ce3ee8a734..113fd38f8a6e4fae9bf138ae2bcf48e1fd82a488 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -41,6 +41,8 @@ from grpc.beta import interfaces  # pylint: disable=unused-import
 from grpc.framework.common import cardinality  # pylint: disable=unused-import
 from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 ChannelCredentials = grpc.ChannelCredentials
 ssl_channel_credentials = grpc.ssl_channel_credentials
 CallCredentials = grpc.CallCredentials
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py
index cb3328296c5b57ce002b2d347e0d39b20de358af..aa80e65f57ade5b1c66367508a0b99beb655e591 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/base.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py
@@ -46,26 +46,29 @@ import six
 # abandonment is referenced from specification in this module.
 from grpc.framework.foundation import abandonment  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 
 class NoSuchMethodError(Exception):
     """Indicates that an unrecognized operation has been called.
 
-  Attributes:
-    code: A code value to communicate to the other side of the operation along
-      with indication of operation termination. May be None.
-    details: A details value to communicate to the other side of the operation
-      along with indication of operation termination. May be None.
-  """
-
-    def __init__(self, code, details):
-        """Constructor.
-
-    Args:
+    Attributes:
       code: A code value to communicate to the other side of the operation
         along with indication of operation termination. May be None.
       details: A details value to communicate to the other side of the
         operation along with indication of operation termination. May be None.
     """
+
+    def __init__(self, code, details):
+        """Constructor.
+
+        Args:
+          code: A code value to communicate to the other side of the operation
+            along with indication of operation termination. May be None.
+          details: A details value to communicate to the other side of the
+            operation along with indication of operation termination. May be None.
+        """
+        super(NoSuchMethodError, self).__init__()
         self.code = code
         self.details = details
 
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
index 6c7e2a3af6a1e6c2ed33e539e9e1b950f2ee14bb..c6c44fe4e4ccb83981015cf63acc96e38e0a1975 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/face.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -42,6 +42,8 @@ from grpc.framework.foundation import abandonment  # pylint: disable=unused-impo
 from grpc.framework.foundation import future  # pylint: disable=unused-import
 from grpc.framework.foundation import stream  # pylint: disable=unused-import
 
+# pylint: disable=too-many-arguments
+
 
 class NoSuchMethodError(Exception):
     """Raised by customer code to indicate an unrecognized method.
diff --git a/templates/tools/dockerfile/apt_get_pyenv.include b/templates/tools/dockerfile/apt_get_pyenv.include
index 816b27904f603f63b30eef53d96e74779f9a3722..ef0964e597535baeff50dfe55d29a287e20a9b05 100644
--- a/templates/tools/dockerfile/apt_get_pyenv.include
+++ b/templates/tools/dockerfile/apt_get_pyenv.include
@@ -12,6 +12,9 @@ RUN apt-get update && apt-get install -y ${'\\'}
 
 # Install Pyenv and dev Python versions 3.5 and 3.6
 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
+ENV PATH /root/.pyenv/bin:$PATH
+RUN eval "$(pyenv init -)"
+RUN eval "$(pyenv virtualenv-init -)"
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
diff --git a/tools/dockerfile/push_testing_images.sh b/tools/dockerfile/push_testing_images.sh
index 9dceb29a8774ee34a64e261d0303cecb886cd289..973e045ffe422e29f6a3f3702c94b1c9220cb043 100755
--- a/tools/dockerfile/push_testing_images.sh
+++ b/tools/dockerfile/push_testing_images.sh
@@ -44,7 +44,7 @@ cd -
 
 DOCKERHUB_ORGANIZATION=grpctesting
 
-for DOCKERFILE_DIR in tools/dockerfile/test/fuzzer tools/dockerfile/test/sanity
+for DOCKERFILE_DIR in tools/dockerfile/test/*
 do
   # Generate image name based on Dockerfile checksum. That works well as long
   # as can count on dockerfiles being written in a way that changing the logical 
diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
index 105f06e548bdbe5f6b3104623529815c419b7ec3..435a9fdc978feb2accde7745c25057c78de94709 100644
--- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile
+++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
@@ -92,6 +92,9 @@ RUN apt-get update && apt-get install -y \
 
 # Install Pyenv and dev Python versions 3.5 and 3.6
 RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
+ENV PATH /root/.pyenv/bin:$PATH
+RUN eval "$(pyenv init -)"
+RUN eval "$(pyenv virtualenv-init -)"
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 8a31a6e0552a6097156e8bcfa08a98dec4afb9f7..22cf618c229c0a30e3ca4a9d0593c1c23d1469ce 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -2607,6 +2607,8 @@
       "gpr", 
       "gpr_test_util", 
       "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
       "grpc_benchmark", 
       "grpc_test_util"
     ], 
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 61de2c93a9c7cb23e5c129d4569d748c6f22a951..43b8f8184e23931c4758faaf3fc44ab4a3c4faa2 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -1298,7 +1298,9 @@ if args.use_docker:
   if not args.travis:
     env['TTY_FLAG'] = '-t'  # enables Ctrl-C when not on Jenkins.
 
-  run_shell_command('tools/run_tests/dockerize/build_docker_and_run_tests.sh', env=env)
+  subprocess.check_call('tools/run_tests/dockerize/build_docker_and_run_tests.sh',
+                        shell=True,
+                        env=env)
   sys.exit(0)
 
 _check_arch_option(args.arch)