From 31d11dbfb8db0fc39da64be9c094e2900e9aedfb Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 09:29:46 +0200
Subject: [PATCH 001/344] Starting this from scratch

-) Basic workspace
-) Basic BUILD file with macros
---
 .gitignore               |    7 +
 BUILD                    | 1958 +++-----------------------------------
 WORKSPACE                |   42 +
 grpc-build-system.bzl    |   31 +
 templates/BUILD.template |  256 -----
 third_party/boringssl    |    2 +-
 third_party/zlib.BUILD   |   37 +
 7 files changed, 250 insertions(+), 2083 deletions(-)
 create mode 100644 WORKSPACE
 create mode 100644 grpc-build-system.bzl
 delete mode 100644 templates/BUILD.template
 create mode 100644 third_party/zlib.BUILD

diff --git a/.gitignore b/.gitignore
index ed015b3c92..febcaf7942 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,3 +103,10 @@ artifacts/
 
 # IDE specific folder for JetBrains IDEs
 .idea/
+
+# Blaze files
+bazel-bin
+bazel-genfiles
+bazel-grpc
+bazel-out
+bazel-testlogs
diff --git a/BUILD b/BUILD
index 5c4333463c..a0320bc5bf 100644
--- a/BUILD
+++ b/BUILD
@@ -1,11 +1,6 @@
 # GRPC Bazel BUILD file.
-# This currently builds C, C++ and Objective-C code.
-# This file has been automatically generated from a template file.
-# Please look at the templates directory instead.
-# This file can be regenerated from the template by running
-# tools/buildgen/generate_projects.sh
-
-# Copyright 2015, Google Inc.
+#
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -40,11 +35,12 @@ exports_files(["LICENSE"])
 
 package(default_visibility = ["//visibility:public"])
 
+load(":grpc-build-system.bzl", "grpc_cc_library")
 
+g_stands_for = "good"
+version = "1.1.0-dev"
 
-
-
-cc_library(
+grpc_cc_library(
   name = "gpr",
   srcs = [
     "src/core/lib/profiling/timers.h",
@@ -149,17 +145,11 @@ cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
   ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-  ],
 )
 
 
 
-cc_library(
+grpc_cc_library(
   name = "grpc",
   srcs = [
     "src/core/lib/channel/channel_args.h",
@@ -547,351 +537,141 @@ cc_library(
     "include/grpc/grpc_security.h",
     "include/grpc/census.h",
   ],
-  includes = [
-    "include",
-    ".",
-  ],
   deps = [
     "//external:libssl",
     "//external:zlib",
     ":gpr",
     "//external:nanopb",
   ],
-  copts = [
-    "-std=gnu99",
-  ],
+  language = "C",
 )
 
 
-
-cc_library(
-  name = "grpc_cronet",
+grpc_cc_library(
+  name = "grpc++",
   srcs = [
-    "src/core/lib/channel/channel_args.h",
-    "src/core/lib/channel/channel_stack.h",
-    "src/core/lib/channel/channel_stack_builder.h",
-    "src/core/lib/channel/compress_filter.h",
-    "src/core/lib/channel/connected_channel.h",
-    "src/core/lib/channel/context.h",
-    "src/core/lib/channel/deadline_filter.h",
-    "src/core/lib/channel/handshaker.h",
-    "src/core/lib/channel/http_client_filter.h",
-    "src/core/lib/channel/http_server_filter.h",
-    "src/core/lib/channel/message_size_filter.h",
-    "src/core/lib/compression/algorithm_metadata.h",
-    "src/core/lib/compression/message_compress.h",
-    "src/core/lib/debug/trace.h",
-    "src/core/lib/http/format_request.h",
-    "src/core/lib/http/httpcli.h",
-    "src/core/lib/http/parser.h",
-    "src/core/lib/iomgr/closure.h",
-    "src/core/lib/iomgr/combiner.h",
-    "src/core/lib/iomgr/endpoint.h",
-    "src/core/lib/iomgr/endpoint_pair.h",
-    "src/core/lib/iomgr/error.h",
-    "src/core/lib/iomgr/ev_epoll_linux.h",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
-    "src/core/lib/iomgr/ev_poll_posix.h",
-    "src/core/lib/iomgr/ev_posix.h",
-    "src/core/lib/iomgr/exec_ctx.h",
-    "src/core/lib/iomgr/executor.h",
-    "src/core/lib/iomgr/iocp_windows.h",
-    "src/core/lib/iomgr/iomgr.h",
-    "src/core/lib/iomgr/iomgr_internal.h",
-    "src/core/lib/iomgr/iomgr_posix.h",
-    "src/core/lib/iomgr/load_file.h",
-    "src/core/lib/iomgr/network_status_tracker.h",
-    "src/core/lib/iomgr/polling_entity.h",
-    "src/core/lib/iomgr/pollset.h",
-    "src/core/lib/iomgr/pollset_set.h",
-    "src/core/lib/iomgr/pollset_set_windows.h",
-    "src/core/lib/iomgr/pollset_windows.h",
-    "src/core/lib/iomgr/resolve_address.h",
-    "src/core/lib/iomgr/sockaddr.h",
-    "src/core/lib/iomgr/sockaddr_posix.h",
-    "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_windows.h",
-    "src/core/lib/iomgr/socket_utils_posix.h",
-    "src/core/lib/iomgr/socket_windows.h",
-    "src/core/lib/iomgr/tcp_client.h",
-    "src/core/lib/iomgr/tcp_posix.h",
-    "src/core/lib/iomgr/tcp_server.h",
-    "src/core/lib/iomgr/tcp_windows.h",
-    "src/core/lib/iomgr/time_averaged_stats.h",
-    "src/core/lib/iomgr/timer.h",
-    "src/core/lib/iomgr/timer_heap.h",
-    "src/core/lib/iomgr/udp_server.h",
-    "src/core/lib/iomgr/unix_sockets_posix.h",
-    "src/core/lib/iomgr/wakeup_fd_cv.h",
-    "src/core/lib/iomgr/wakeup_fd_pipe.h",
-    "src/core/lib/iomgr/wakeup_fd_posix.h",
-    "src/core/lib/iomgr/workqueue.h",
-    "src/core/lib/iomgr/workqueue_windows.h",
-    "src/core/lib/json/json.h",
-    "src/core/lib/json/json_common.h",
-    "src/core/lib/json/json_reader.h",
-    "src/core/lib/json/json_writer.h",
-    "src/core/lib/surface/api_trace.h",
-    "src/core/lib/surface/call.h",
-    "src/core/lib/surface/call_test_only.h",
-    "src/core/lib/surface/channel.h",
-    "src/core/lib/surface/channel_init.h",
-    "src/core/lib/surface/channel_stack_type.h",
-    "src/core/lib/surface/completion_queue.h",
-    "src/core/lib/surface/event_string.h",
-    "src/core/lib/surface/init.h",
-    "src/core/lib/surface/lame_client.h",
-    "src/core/lib/surface/server.h",
-    "src/core/lib/transport/byte_stream.h",
-    "src/core/lib/transport/connectivity_state.h",
-    "src/core/lib/transport/mdstr_hash_table.h",
-    "src/core/lib/transport/metadata.h",
-    "src/core/lib/transport/metadata_batch.h",
-    "src/core/lib/transport/static_metadata.h",
-    "src/core/lib/transport/timeout_encoding.h",
-    "src/core/lib/transport/transport.h",
-    "src/core/lib/transport/transport_impl.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
-    "src/core/ext/transport/chttp2/transport/frame.h",
-    "src/core/ext/transport/chttp2/transport/frame_data.h",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
-    "src/core/ext/transport/chttp2/transport/frame_ping.h",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
-    "src/core/ext/transport/chttp2/transport/frame_settings.h",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
-    "src/core/ext/transport/chttp2/transport/hpack_table.h",
-    "src/core/ext/transport/chttp2/transport/http2_errors.h",
-    "src/core/ext/transport/chttp2/transport/huffsyms.h",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
-    "src/core/ext/transport/chttp2/transport/internal.h",
-    "src/core/ext/transport/chttp2/transport/status_conversion.h",
-    "src/core/ext/transport/chttp2/transport/stream_map.h",
-    "src/core/ext/transport/chttp2/transport/varint.h",
-    "src/core/ext/transport/chttp2/alpn/alpn.h",
-    "src/core/ext/client_config/client_channel.h",
-    "src/core/ext/client_config/client_channel_factory.h",
-    "src/core/ext/client_config/connector.h",
-    "src/core/ext/client_config/http_connect_handshaker.h",
-    "src/core/ext/client_config/initial_connect_string.h",
-    "src/core/ext/client_config/lb_policy.h",
-    "src/core/ext/client_config/lb_policy_factory.h",
-    "src/core/ext/client_config/lb_policy_registry.h",
-    "src/core/ext/client_config/method_config.h",
-    "src/core/ext/client_config/parse_address.h",
-    "src/core/ext/client_config/resolver.h",
-    "src/core/ext/client_config/resolver_factory.h",
-    "src/core/ext/client_config/resolver_registry.h",
-    "src/core/ext/client_config/resolver_result.h",
-    "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_index.h",
-    "src/core/ext/client_config/uri_parser.h",
-    "src/core/lib/security/context/security_context.h",
-    "src/core/lib/security/credentials/composite/composite_credentials.h",
-    "src/core/lib/security/credentials/credentials.h",
-    "src/core/lib/security/credentials/fake/fake_credentials.h",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
-    "src/core/lib/security/credentials/iam/iam_credentials.h",
-    "src/core/lib/security/credentials/jwt/json_token.h",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
-    "src/core/lib/security/transport/auth_filters.h",
-    "src/core/lib/security/transport/handshake.h",
-    "src/core/lib/security/transport/secure_endpoint.h",
-    "src/core/lib/security/transport/security_connector.h",
-    "src/core/lib/security/transport/tsi_error.h",
-    "src/core/lib/security/util/b64.h",
-    "src/core/lib/security/util/json_util.h",
-    "src/core/lib/tsi/fake_transport_security.h",
-    "src/core/lib/tsi/ssl_transport_security.h",
-    "src/core/lib/tsi/ssl_types.h",
-    "src/core/lib/tsi/transport_security.h",
-    "src/core/lib/tsi/transport_security_interface.h",
-    "src/core/lib/surface/init.c",
-    "src/core/lib/channel/channel_args.c",
-    "src/core/lib/channel/channel_stack.c",
-    "src/core/lib/channel/channel_stack_builder.c",
-    "src/core/lib/channel/compress_filter.c",
-    "src/core/lib/channel/connected_channel.c",
-    "src/core/lib/channel/deadline_filter.c",
-    "src/core/lib/channel/handshaker.c",
-    "src/core/lib/channel/http_client_filter.c",
-    "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/channel/message_size_filter.c",
-    "src/core/lib/compression/compression.c",
-    "src/core/lib/compression/message_compress.c",
-    "src/core/lib/debug/trace.c",
-    "src/core/lib/http/format_request.c",
-    "src/core/lib/http/httpcli.c",
-    "src/core/lib/http/parser.c",
-    "src/core/lib/iomgr/closure.c",
-    "src/core/lib/iomgr/combiner.c",
-    "src/core/lib/iomgr/endpoint.c",
-    "src/core/lib/iomgr/endpoint_pair_posix.c",
-    "src/core/lib/iomgr/endpoint_pair_windows.c",
-    "src/core/lib/iomgr/error.c",
-    "src/core/lib/iomgr/ev_epoll_linux.c",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
-    "src/core/lib/iomgr/ev_poll_posix.c",
-    "src/core/lib/iomgr/ev_posix.c",
-    "src/core/lib/iomgr/exec_ctx.c",
-    "src/core/lib/iomgr/executor.c",
-    "src/core/lib/iomgr/iocp_windows.c",
-    "src/core/lib/iomgr/iomgr.c",
-    "src/core/lib/iomgr/iomgr_posix.c",
-    "src/core/lib/iomgr/iomgr_windows.c",
-    "src/core/lib/iomgr/load_file.c",
-    "src/core/lib/iomgr/network_status_tracker.c",
-    "src/core/lib/iomgr/polling_entity.c",
-    "src/core/lib/iomgr/pollset_set_windows.c",
-    "src/core/lib/iomgr/pollset_windows.c",
-    "src/core/lib/iomgr/resolve_address_posix.c",
-    "src/core/lib/iomgr/resolve_address_windows.c",
-    "src/core/lib/iomgr/sockaddr_utils.c",
-    "src/core/lib/iomgr/socket_utils_common_posix.c",
-    "src/core/lib/iomgr/socket_utils_linux.c",
-    "src/core/lib/iomgr/socket_utils_posix.c",
-    "src/core/lib/iomgr/socket_windows.c",
-    "src/core/lib/iomgr/tcp_client_posix.c",
-    "src/core/lib/iomgr/tcp_client_windows.c",
-    "src/core/lib/iomgr/tcp_posix.c",
-    "src/core/lib/iomgr/tcp_server_posix.c",
-    "src/core/lib/iomgr/tcp_server_windows.c",
-    "src/core/lib/iomgr/tcp_windows.c",
-    "src/core/lib/iomgr/time_averaged_stats.c",
-    "src/core/lib/iomgr/timer.c",
-    "src/core/lib/iomgr/timer_heap.c",
-    "src/core/lib/iomgr/udp_server.c",
-    "src/core/lib/iomgr/unix_sockets_posix.c",
-    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
-    "src/core/lib/iomgr/wakeup_fd_cv.c",
-    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
-    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
-    "src/core/lib/iomgr/wakeup_fd_pipe.c",
-    "src/core/lib/iomgr/wakeup_fd_posix.c",
-    "src/core/lib/iomgr/workqueue_windows.c",
-    "src/core/lib/json/json.c",
-    "src/core/lib/json/json_reader.c",
-    "src/core/lib/json/json_string.c",
-    "src/core/lib/json/json_writer.c",
-    "src/core/lib/surface/alarm.c",
-    "src/core/lib/surface/api_trace.c",
-    "src/core/lib/surface/byte_buffer.c",
-    "src/core/lib/surface/byte_buffer_reader.c",
-    "src/core/lib/surface/call.c",
-    "src/core/lib/surface/call_details.c",
-    "src/core/lib/surface/call_log_batch.c",
-    "src/core/lib/surface/channel.c",
-    "src/core/lib/surface/channel_init.c",
-    "src/core/lib/surface/channel_ping.c",
-    "src/core/lib/surface/channel_stack_type.c",
-    "src/core/lib/surface/completion_queue.c",
-    "src/core/lib/surface/event_string.c",
-    "src/core/lib/surface/lame_client.c",
-    "src/core/lib/surface/metadata_array.c",
-    "src/core/lib/surface/server.c",
-    "src/core/lib/surface/validate_metadata.c",
-    "src/core/lib/surface/version.c",
-    "src/core/lib/transport/byte_stream.c",
-    "src/core/lib/transport/connectivity_state.c",
-    "src/core/lib/transport/mdstr_hash_table.c",
-    "src/core/lib/transport/metadata.c",
-    "src/core/lib/transport/metadata_batch.c",
-    "src/core/lib/transport/static_metadata.c",
-    "src/core/lib/transport/timeout_encoding.c",
-    "src/core/lib/transport/transport.c",
-    "src/core/lib/transport/transport_op_string.c",
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
-    "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.c",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
-    "src/core/ext/transport/chttp2/transport/frame_data.c",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
-    "src/core/ext/transport/chttp2/transport/frame_ping.c",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
-    "src/core/ext/transport/chttp2/transport/frame_settings.c",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
-    "src/core/ext/transport/chttp2/transport/hpack_table.c",
-    "src/core/ext/transport/chttp2/transport/huffsyms.c",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
-    "src/core/ext/transport/chttp2/transport/parsing.c",
-    "src/core/ext/transport/chttp2/transport/status_conversion.c",
-    "src/core/ext/transport/chttp2/transport/stream_lists.c",
-    "src/core/ext/transport/chttp2/transport/stream_map.c",
-    "src/core/ext/transport/chttp2/transport/varint.c",
-    "src/core/ext/transport/chttp2/transport/writing.c",
-    "src/core/ext/transport/chttp2/alpn/alpn.c",
-    "src/core/ext/client_config/channel_connectivity.c",
-    "src/core/ext/client_config/client_channel.c",
-    "src/core/ext/client_config/client_channel_factory.c",
-    "src/core/ext/client_config/client_config_plugin.c",
-    "src/core/ext/client_config/connector.c",
-    "src/core/ext/client_config/default_initial_connect_string.c",
-    "src/core/ext/client_config/http_connect_handshaker.c",
-    "src/core/ext/client_config/initial_connect_string.c",
-    "src/core/ext/client_config/lb_policy.c",
-    "src/core/ext/client_config/lb_policy_factory.c",
-    "src/core/ext/client_config/lb_policy_registry.c",
-    "src/core/ext/client_config/method_config.c",
-    "src/core/ext/client_config/parse_address.c",
-    "src/core/ext/client_config/resolver.c",
-    "src/core/ext/client_config/resolver_factory.c",
-    "src/core/ext/client_config/resolver_registry.c",
-    "src/core/ext/client_config/resolver_result.c",
-    "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_index.c",
-    "src/core/ext/client_config/uri_parser.c",
-    "src/core/lib/http/httpcli_security_connector.c",
-    "src/core/lib/security/context/security_context.c",
-    "src/core/lib/security/credentials/composite/composite_credentials.c",
-    "src/core/lib/security/credentials/credentials.c",
-    "src/core/lib/security/credentials/credentials_metadata.c",
-    "src/core/lib/security/credentials/fake/fake_credentials.c",
-    "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_windows.c",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
-    "src/core/lib/security/credentials/iam/iam_credentials.c",
-    "src/core/lib/security/credentials/jwt/json_token.c",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
-    "src/core/lib/security/transport/client_auth_filter.c",
-    "src/core/lib/security/transport/handshake.c",
-    "src/core/lib/security/transport/secure_endpoint.c",
-    "src/core/lib/security/transport/security_connector.c",
-    "src/core/lib/security/transport/server_auth_filter.c",
-    "src/core/lib/security/transport/tsi_error.c",
-    "src/core/lib/security/util/b64.c",
-    "src/core/lib/security/util/json_util.c",
-    "src/core/lib/surface/init_secure.c",
-    "src/core/lib/tsi/fake_transport_security.c",
-    "src/core/lib/tsi/ssl_transport_security.c",
-    "src/core/lib/tsi/transport_security.c",
-    "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
+    "include/grpc++/impl/codegen/core_codegen.h",
+    "src/cpp/client/secure_credentials.h",
+    "src/cpp/common/secure_auth_context.h",
+    "src/cpp/server/secure_server_credentials.h",
+    "src/cpp/client/create_channel_internal.h",
+    "src/cpp/common/channel_filter.h",
+    "src/cpp/server/dynamic_thread_pool.h",
+    "src/cpp/server/thread_pool_interface.h",
+    "src/cpp/client/insecure_credentials.cc",
+    "src/cpp/client/secure_credentials.cc",
+    "src/cpp/common/auth_property_iterator.cc",
+    "src/cpp/common/secure_auth_context.cc",
+    "src/cpp/common/secure_channel_arguments.cc",
+    "src/cpp/common/secure_create_auth_context.cc",
+    "src/cpp/server/insecure_server_credentials.cc",
+    "src/cpp/server/secure_server_credentials.cc",
+    "src/cpp/client/channel_cc.cc",
+    "src/cpp/client/client_context.cc",
+    "src/cpp/client/create_channel.cc",
+    "src/cpp/client/create_channel_internal.cc",
+    "src/cpp/client/create_channel_posix.cc",
+    "src/cpp/client/credentials_cc.cc",
+    "src/cpp/client/generic_stub.cc",
+    "src/cpp/common/channel_arguments.cc",
+    "src/cpp/common/channel_filter.cc",
+    "src/cpp/common/completion_queue_cc.cc",
+    "src/cpp/common/core_codegen.cc",
+    "src/cpp/common/rpc_method.cc",
+    "src/cpp/server/async_generic_service.cc",
+    "src/cpp/server/create_default_thread_pool.cc",
+    "src/cpp/server/dynamic_thread_pool.cc",
+    "src/cpp/server/server_builder.cc",
+    "src/cpp/server/server_cc.cc",
+    "src/cpp/server/server_context.cc",
+    "src/cpp/server/server_credentials.cc",
+    "src/cpp/server/server_posix.cc",
+    "src/cpp/util/byte_buffer_cc.cc",
+    "src/cpp/util/slice_cc.cc",
+    "src/cpp/util/status.cc",
+    "src/cpp/util/string_ref.cc",
+    "src/cpp/util/time_cc.cc",
+    "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/grpc_posix.h",
-    "include/grpc/grpc_security_constants.h",
-    "include/grpc/status.h",
+    "include/grpc++/alarm.h",
+    "include/grpc++/channel.h",
+    "include/grpc++/client_context.h",
+    "include/grpc++/completion_queue.h",
+    "include/grpc++/create_channel.h",
+    "include/grpc++/create_channel_posix.h",
+    "include/grpc++/generic/async_generic_service.h",
+    "include/grpc++/generic/generic_stub.h",
+    "include/grpc++/grpc++.h",
+    "include/grpc++/impl/call.h",
+    "include/grpc++/impl/client_unary_call.h",
+    "include/grpc++/impl/codegen/core_codegen.h",
+    "include/grpc++/impl/grpc_library.h",
+    "include/grpc++/impl/method_handler_impl.h",
+    "include/grpc++/impl/rpc_method.h",
+    "include/grpc++/impl/rpc_service_method.h",
+    "include/grpc++/impl/serialization_traits.h",
+    "include/grpc++/impl/server_builder_option.h",
+    "include/grpc++/impl/server_builder_plugin.h",
+    "include/grpc++/impl/server_initializer.h",
+    "include/grpc++/impl/service_type.h",
+    "include/grpc++/impl/sync.h",
+    "include/grpc++/impl/sync_cxx11.h",
+    "include/grpc++/impl/sync_no_cxx11.h",
+    "include/grpc++/impl/thd.h",
+    "include/grpc++/impl/thd_cxx11.h",
+    "include/grpc++/impl/thd_no_cxx11.h",
+    "include/grpc++/security/auth_context.h",
+    "include/grpc++/security/auth_metadata_processor.h",
+    "include/grpc++/security/credentials.h",
+    "include/grpc++/security/server_credentials.h",
+    "include/grpc++/server.h",
+    "include/grpc++/server_builder.h",
+    "include/grpc++/server_context.h",
+    "include/grpc++/server_posix.h",
+    "include/grpc++/support/async_stream.h",
+    "include/grpc++/support/async_unary_call.h",
+    "include/grpc++/support/byte_buffer.h",
+    "include/grpc++/support/channel_arguments.h",
+    "include/grpc++/support/config.h",
+    "include/grpc++/support/slice.h",
+    "include/grpc++/support/status.h",
+    "include/grpc++/support/status_code_enum.h",
+    "include/grpc++/support/string_ref.h",
+    "include/grpc++/support/stub_options.h",
+    "include/grpc++/support/sync_stream.h",
+    "include/grpc++/support/time.h",
+    "include/grpc++/impl/codegen/async_stream.h",
+    "include/grpc++/impl/codegen/async_unary_call.h",
+    "include/grpc++/impl/codegen/call.h",
+    "include/grpc++/impl/codegen/call_hook.h",
+    "include/grpc++/impl/codegen/channel_interface.h",
+    "include/grpc++/impl/codegen/client_context.h",
+    "include/grpc++/impl/codegen/client_unary_call.h",
+    "include/grpc++/impl/codegen/completion_queue.h",
+    "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
+    "include/grpc++/impl/codegen/core_codegen_interface.h",
+    "include/grpc++/impl/codegen/create_auth_context.h",
+    "include/grpc++/impl/codegen/grpc_library.h",
+    "include/grpc++/impl/codegen/method_handler_impl.h",
+    "include/grpc++/impl/codegen/rpc_method.h",
+    "include/grpc++/impl/codegen/rpc_service_method.h",
+    "include/grpc++/impl/codegen/security/auth_context.h",
+    "include/grpc++/impl/codegen/serialization_traits.h",
+    "include/grpc++/impl/codegen/server_context.h",
+    "include/grpc++/impl/codegen/server_interface.h",
+    "include/grpc++/impl/codegen/service_type.h",
+    "include/grpc++/impl/codegen/status.h",
+    "include/grpc++/impl/codegen/status_code_enum.h",
+    "include/grpc++/impl/codegen/status_helper.h",
+    "include/grpc++/impl/codegen/string_ref.h",
+    "include/grpc++/impl/codegen/stub_options.h",
+    "include/grpc++/impl/codegen/sync.h",
+    "include/grpc++/impl/codegen/sync_cxx11.h",
+    "include/grpc++/impl/codegen/sync_no_cxx11.h",
+    "include/grpc++/impl/codegen/sync_stream.h",
+    "include/grpc++/impl/codegen/time.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
@@ -909,1484 +689,10 @@ cc_library(
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
-    "include/grpc/grpc_cronet.h",
-    "include/grpc/grpc_security.h",
-  ],
-  includes = [
-    "include",
-    ".",
   ],
   deps = [
     "//external:libssl",
-    ":gpr",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc_unsecure",
-  srcs = [
-    "src/core/lib/channel/channel_args.h",
-    "src/core/lib/channel/channel_stack.h",
-    "src/core/lib/channel/channel_stack_builder.h",
-    "src/core/lib/channel/compress_filter.h",
-    "src/core/lib/channel/connected_channel.h",
-    "src/core/lib/channel/context.h",
-    "src/core/lib/channel/deadline_filter.h",
-    "src/core/lib/channel/handshaker.h",
-    "src/core/lib/channel/http_client_filter.h",
-    "src/core/lib/channel/http_server_filter.h",
-    "src/core/lib/channel/message_size_filter.h",
-    "src/core/lib/compression/algorithm_metadata.h",
-    "src/core/lib/compression/message_compress.h",
-    "src/core/lib/debug/trace.h",
-    "src/core/lib/http/format_request.h",
-    "src/core/lib/http/httpcli.h",
-    "src/core/lib/http/parser.h",
-    "src/core/lib/iomgr/closure.h",
-    "src/core/lib/iomgr/combiner.h",
-    "src/core/lib/iomgr/endpoint.h",
-    "src/core/lib/iomgr/endpoint_pair.h",
-    "src/core/lib/iomgr/error.h",
-    "src/core/lib/iomgr/ev_epoll_linux.h",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
-    "src/core/lib/iomgr/ev_poll_posix.h",
-    "src/core/lib/iomgr/ev_posix.h",
-    "src/core/lib/iomgr/exec_ctx.h",
-    "src/core/lib/iomgr/executor.h",
-    "src/core/lib/iomgr/iocp_windows.h",
-    "src/core/lib/iomgr/iomgr.h",
-    "src/core/lib/iomgr/iomgr_internal.h",
-    "src/core/lib/iomgr/iomgr_posix.h",
-    "src/core/lib/iomgr/load_file.h",
-    "src/core/lib/iomgr/network_status_tracker.h",
-    "src/core/lib/iomgr/polling_entity.h",
-    "src/core/lib/iomgr/pollset.h",
-    "src/core/lib/iomgr/pollset_set.h",
-    "src/core/lib/iomgr/pollset_set_windows.h",
-    "src/core/lib/iomgr/pollset_windows.h",
-    "src/core/lib/iomgr/resolve_address.h",
-    "src/core/lib/iomgr/sockaddr.h",
-    "src/core/lib/iomgr/sockaddr_posix.h",
-    "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_windows.h",
-    "src/core/lib/iomgr/socket_utils_posix.h",
-    "src/core/lib/iomgr/socket_windows.h",
-    "src/core/lib/iomgr/tcp_client.h",
-    "src/core/lib/iomgr/tcp_posix.h",
-    "src/core/lib/iomgr/tcp_server.h",
-    "src/core/lib/iomgr/tcp_windows.h",
-    "src/core/lib/iomgr/time_averaged_stats.h",
-    "src/core/lib/iomgr/timer.h",
-    "src/core/lib/iomgr/timer_heap.h",
-    "src/core/lib/iomgr/udp_server.h",
-    "src/core/lib/iomgr/unix_sockets_posix.h",
-    "src/core/lib/iomgr/wakeup_fd_cv.h",
-    "src/core/lib/iomgr/wakeup_fd_pipe.h",
-    "src/core/lib/iomgr/wakeup_fd_posix.h",
-    "src/core/lib/iomgr/workqueue.h",
-    "src/core/lib/iomgr/workqueue_windows.h",
-    "src/core/lib/json/json.h",
-    "src/core/lib/json/json_common.h",
-    "src/core/lib/json/json_reader.h",
-    "src/core/lib/json/json_writer.h",
-    "src/core/lib/surface/api_trace.h",
-    "src/core/lib/surface/call.h",
-    "src/core/lib/surface/call_test_only.h",
-    "src/core/lib/surface/channel.h",
-    "src/core/lib/surface/channel_init.h",
-    "src/core/lib/surface/channel_stack_type.h",
-    "src/core/lib/surface/completion_queue.h",
-    "src/core/lib/surface/event_string.h",
-    "src/core/lib/surface/init.h",
-    "src/core/lib/surface/lame_client.h",
-    "src/core/lib/surface/server.h",
-    "src/core/lib/transport/byte_stream.h",
-    "src/core/lib/transport/connectivity_state.h",
-    "src/core/lib/transport/mdstr_hash_table.h",
-    "src/core/lib/transport/metadata.h",
-    "src/core/lib/transport/metadata_batch.h",
-    "src/core/lib/transport/static_metadata.h",
-    "src/core/lib/transport/timeout_encoding.h",
-    "src/core/lib/transport/transport.h",
-    "src/core/lib/transport/transport_impl.h",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
-    "src/core/ext/transport/chttp2/transport/frame.h",
-    "src/core/ext/transport/chttp2/transport/frame_data.h",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
-    "src/core/ext/transport/chttp2/transport/frame_ping.h",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
-    "src/core/ext/transport/chttp2/transport/frame_settings.h",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
-    "src/core/ext/transport/chttp2/transport/hpack_table.h",
-    "src/core/ext/transport/chttp2/transport/http2_errors.h",
-    "src/core/ext/transport/chttp2/transport/huffsyms.h",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
-    "src/core/ext/transport/chttp2/transport/internal.h",
-    "src/core/ext/transport/chttp2/transport/status_conversion.h",
-    "src/core/ext/transport/chttp2/transport/stream_map.h",
-    "src/core/ext/transport/chttp2/transport/varint.h",
-    "src/core/ext/transport/chttp2/alpn/alpn.h",
-    "src/core/ext/client_config/client_channel.h",
-    "src/core/ext/client_config/client_channel_factory.h",
-    "src/core/ext/client_config/connector.h",
-    "src/core/ext/client_config/http_connect_handshaker.h",
-    "src/core/ext/client_config/initial_connect_string.h",
-    "src/core/ext/client_config/lb_policy.h",
-    "src/core/ext/client_config/lb_policy_factory.h",
-    "src/core/ext/client_config/lb_policy_registry.h",
-    "src/core/ext/client_config/method_config.h",
-    "src/core/ext/client_config/parse_address.h",
-    "src/core/ext/client_config/resolver.h",
-    "src/core/ext/client_config/resolver_factory.h",
-    "src/core/ext/client_config/resolver_registry.h",
-    "src/core/ext/client_config/resolver_result.h",
-    "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_index.h",
-    "src/core/ext/client_config/uri_parser.h",
-    "src/core/ext/load_reporting/load_reporting.h",
-    "src/core/ext/load_reporting/load_reporting_filter.h",
-    "src/core/ext/lb_policy/grpclb/grpclb.h",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
-    "src/core/ext/census/aggregation.h",
-    "src/core/ext/census/base_resources.h",
-    "src/core/ext/census/census_interface.h",
-    "src/core/ext/census/census_rpc_stats.h",
-    "src/core/ext/census/gen/census.pb.h",
-    "src/core/ext/census/gen/trace_context.pb.h",
-    "src/core/ext/census/grpc_filter.h",
-    "src/core/ext/census/mlog.h",
-    "src/core/ext/census/resource.h",
-    "src/core/ext/census/rpc_metric_id.h",
-    "src/core/ext/census/trace_context.h",
-    "src/core/lib/surface/init.c",
-    "src/core/lib/surface/init_unsecure.c",
-    "src/core/lib/channel/channel_args.c",
-    "src/core/lib/channel/channel_stack.c",
-    "src/core/lib/channel/channel_stack_builder.c",
-    "src/core/lib/channel/compress_filter.c",
-    "src/core/lib/channel/connected_channel.c",
-    "src/core/lib/channel/deadline_filter.c",
-    "src/core/lib/channel/handshaker.c",
-    "src/core/lib/channel/http_client_filter.c",
-    "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/channel/message_size_filter.c",
-    "src/core/lib/compression/compression.c",
-    "src/core/lib/compression/message_compress.c",
-    "src/core/lib/debug/trace.c",
-    "src/core/lib/http/format_request.c",
-    "src/core/lib/http/httpcli.c",
-    "src/core/lib/http/parser.c",
-    "src/core/lib/iomgr/closure.c",
-    "src/core/lib/iomgr/combiner.c",
-    "src/core/lib/iomgr/endpoint.c",
-    "src/core/lib/iomgr/endpoint_pair_posix.c",
-    "src/core/lib/iomgr/endpoint_pair_windows.c",
-    "src/core/lib/iomgr/error.c",
-    "src/core/lib/iomgr/ev_epoll_linux.c",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
-    "src/core/lib/iomgr/ev_poll_posix.c",
-    "src/core/lib/iomgr/ev_posix.c",
-    "src/core/lib/iomgr/exec_ctx.c",
-    "src/core/lib/iomgr/executor.c",
-    "src/core/lib/iomgr/iocp_windows.c",
-    "src/core/lib/iomgr/iomgr.c",
-    "src/core/lib/iomgr/iomgr_posix.c",
-    "src/core/lib/iomgr/iomgr_windows.c",
-    "src/core/lib/iomgr/load_file.c",
-    "src/core/lib/iomgr/network_status_tracker.c",
-    "src/core/lib/iomgr/polling_entity.c",
-    "src/core/lib/iomgr/pollset_set_windows.c",
-    "src/core/lib/iomgr/pollset_windows.c",
-    "src/core/lib/iomgr/resolve_address_posix.c",
-    "src/core/lib/iomgr/resolve_address_windows.c",
-    "src/core/lib/iomgr/sockaddr_utils.c",
-    "src/core/lib/iomgr/socket_utils_common_posix.c",
-    "src/core/lib/iomgr/socket_utils_linux.c",
-    "src/core/lib/iomgr/socket_utils_posix.c",
-    "src/core/lib/iomgr/socket_windows.c",
-    "src/core/lib/iomgr/tcp_client_posix.c",
-    "src/core/lib/iomgr/tcp_client_windows.c",
-    "src/core/lib/iomgr/tcp_posix.c",
-    "src/core/lib/iomgr/tcp_server_posix.c",
-    "src/core/lib/iomgr/tcp_server_windows.c",
-    "src/core/lib/iomgr/tcp_windows.c",
-    "src/core/lib/iomgr/time_averaged_stats.c",
-    "src/core/lib/iomgr/timer.c",
-    "src/core/lib/iomgr/timer_heap.c",
-    "src/core/lib/iomgr/udp_server.c",
-    "src/core/lib/iomgr/unix_sockets_posix.c",
-    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
-    "src/core/lib/iomgr/wakeup_fd_cv.c",
-    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
-    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
-    "src/core/lib/iomgr/wakeup_fd_pipe.c",
-    "src/core/lib/iomgr/wakeup_fd_posix.c",
-    "src/core/lib/iomgr/workqueue_windows.c",
-    "src/core/lib/json/json.c",
-    "src/core/lib/json/json_reader.c",
-    "src/core/lib/json/json_string.c",
-    "src/core/lib/json/json_writer.c",
-    "src/core/lib/surface/alarm.c",
-    "src/core/lib/surface/api_trace.c",
-    "src/core/lib/surface/byte_buffer.c",
-    "src/core/lib/surface/byte_buffer_reader.c",
-    "src/core/lib/surface/call.c",
-    "src/core/lib/surface/call_details.c",
-    "src/core/lib/surface/call_log_batch.c",
-    "src/core/lib/surface/channel.c",
-    "src/core/lib/surface/channel_init.c",
-    "src/core/lib/surface/channel_ping.c",
-    "src/core/lib/surface/channel_stack_type.c",
-    "src/core/lib/surface/completion_queue.c",
-    "src/core/lib/surface/event_string.c",
-    "src/core/lib/surface/lame_client.c",
-    "src/core/lib/surface/metadata_array.c",
-    "src/core/lib/surface/server.c",
-    "src/core/lib/surface/validate_metadata.c",
-    "src/core/lib/surface/version.c",
-    "src/core/lib/transport/byte_stream.c",
-    "src/core/lib/transport/connectivity_state.c",
-    "src/core/lib/transport/mdstr_hash_table.c",
-    "src/core/lib/transport/metadata.c",
-    "src/core/lib/transport/metadata_batch.c",
-    "src/core/lib/transport/static_metadata.c",
-    "src/core/lib/transport/timeout_encoding.c",
-    "src/core/lib/transport/transport.c",
-    "src/core/lib/transport/transport_op_string.c",
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.c",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
-    "src/core/ext/transport/chttp2/transport/frame_data.c",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
-    "src/core/ext/transport/chttp2/transport/frame_ping.c",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
-    "src/core/ext/transport/chttp2/transport/frame_settings.c",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
-    "src/core/ext/transport/chttp2/transport/hpack_table.c",
-    "src/core/ext/transport/chttp2/transport/huffsyms.c",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
-    "src/core/ext/transport/chttp2/transport/parsing.c",
-    "src/core/ext/transport/chttp2/transport/status_conversion.c",
-    "src/core/ext/transport/chttp2/transport/stream_lists.c",
-    "src/core/ext/transport/chttp2/transport/stream_map.c",
-    "src/core/ext/transport/chttp2/transport/varint.c",
-    "src/core/ext/transport/chttp2/transport/writing.c",
-    "src/core/ext/transport/chttp2/alpn/alpn.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
-    "src/core/ext/client_config/channel_connectivity.c",
-    "src/core/ext/client_config/client_channel.c",
-    "src/core/ext/client_config/client_channel_factory.c",
-    "src/core/ext/client_config/client_config_plugin.c",
-    "src/core/ext/client_config/connector.c",
-    "src/core/ext/client_config/default_initial_connect_string.c",
-    "src/core/ext/client_config/http_connect_handshaker.c",
-    "src/core/ext/client_config/initial_connect_string.c",
-    "src/core/ext/client_config/lb_policy.c",
-    "src/core/ext/client_config/lb_policy_factory.c",
-    "src/core/ext/client_config/lb_policy_registry.c",
-    "src/core/ext/client_config/method_config.c",
-    "src/core/ext/client_config/parse_address.c",
-    "src/core/ext/client_config/resolver.c",
-    "src/core/ext/client_config/resolver_factory.c",
-    "src/core/ext/client_config/resolver_registry.c",
-    "src/core/ext/client_config/resolver_result.c",
-    "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_index.c",
-    "src/core/ext/client_config/uri_parser.c",
-    "src/core/ext/resolver/dns/native/dns_resolver.c",
-    "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
-    "src/core/ext/load_reporting/load_reporting.c",
-    "src/core/ext/load_reporting/load_reporting_filter.c",
-    "src/core/ext/lb_policy/grpclb/grpclb.c",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
-    "src/core/ext/lb_policy/pick_first/pick_first.c",
-    "src/core/ext/lb_policy/round_robin/round_robin.c",
-    "src/core/ext/census/base_resources.c",
-    "src/core/ext/census/context.c",
-    "src/core/ext/census/gen/census.pb.c",
-    "src/core/ext/census/gen/trace_context.pb.c",
-    "src/core/ext/census/grpc_context.c",
-    "src/core/ext/census/grpc_filter.c",
-    "src/core/ext/census/grpc_plugin.c",
-    "src/core/ext/census/initialize.c",
-    "src/core/ext/census/mlog.c",
-    "src/core/ext/census/operation.c",
-    "src/core/ext/census/placeholders.c",
-    "src/core/ext/census/resource.c",
-    "src/core/ext/census/trace_context.c",
-    "src/core/ext/census/tracing.c",
-    "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
-  ],
-  hdrs = [
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/grpc_posix.h",
-    "include/grpc/grpc_security_constants.h",
-    "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-    "include/grpc/census.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    ":gpr",
-    "//external:nanopb",
-  ],
-  copts = [
-    "-std=gnu99",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc++",
-  srcs = [
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "src/cpp/client/secure_credentials.h",
-    "src/cpp/common/secure_auth_context.h",
-    "src/cpp/server/secure_server_credentials.h",
-    "src/cpp/client/create_channel_internal.h",
-    "src/cpp/common/channel_filter.h",
-    "src/cpp/server/dynamic_thread_pool.h",
-    "src/cpp/server/thread_pool_interface.h",
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/client/secure_credentials.cc",
-    "src/cpp/common/auth_property_iterator.cc",
-    "src/cpp/common/secure_auth_context.cc",
-    "src/cpp/common/secure_channel_arguments.cc",
-    "src/cpp/common/secure_create_auth_context.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/server/secure_server_credentials.cc",
-    "src/cpp/client/channel_cc.cc",
-    "src/cpp/client/client_context.cc",
-    "src/cpp/client/create_channel.cc",
-    "src/cpp/client/create_channel_internal.cc",
-    "src/cpp/client/create_channel_posix.cc",
-    "src/cpp/client/credentials_cc.cc",
-    "src/cpp/client/generic_stub.cc",
-    "src/cpp/common/channel_arguments.cc",
-    "src/cpp/common/channel_filter.cc",
-    "src/cpp/common/completion_queue_cc.cc",
-    "src/cpp/common/core_codegen.cc",
-    "src/cpp/common/rpc_method.cc",
-    "src/cpp/server/async_generic_service.cc",
-    "src/cpp/server/create_default_thread_pool.cc",
-    "src/cpp/server/dynamic_thread_pool.cc",
-    "src/cpp/server/server_builder.cc",
-    "src/cpp/server/server_cc.cc",
-    "src/cpp/server/server_context.cc",
-    "src/cpp/server/server_credentials.cc",
-    "src/cpp/server/server_posix.cc",
-    "src/cpp/util/byte_buffer_cc.cc",
-    "src/cpp/util/slice_cc.cc",
-    "src/cpp/util/status.cc",
-    "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time_cc.cc",
-    "src/cpp/codegen/codegen_init.cc",
-  ],
-  hdrs = [
-    "include/grpc++/alarm.h",
-    "include/grpc++/channel.h",
-    "include/grpc++/client_context.h",
-    "include/grpc++/completion_queue.h",
-    "include/grpc++/create_channel.h",
-    "include/grpc++/create_channel_posix.h",
-    "include/grpc++/generic/async_generic_service.h",
-    "include/grpc++/generic/generic_stub.h",
-    "include/grpc++/grpc++.h",
-    "include/grpc++/impl/call.h",
-    "include/grpc++/impl/client_unary_call.h",
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "include/grpc++/impl/grpc_library.h",
-    "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/rpc_method.h",
-    "include/grpc++/impl/rpc_service_method.h",
-    "include/grpc++/impl/serialization_traits.h",
-    "include/grpc++/impl/server_builder_option.h",
-    "include/grpc++/impl/server_builder_plugin.h",
-    "include/grpc++/impl/server_initializer.h",
-    "include/grpc++/impl/service_type.h",
-    "include/grpc++/impl/sync.h",
-    "include/grpc++/impl/sync_cxx11.h",
-    "include/grpc++/impl/sync_no_cxx11.h",
-    "include/grpc++/impl/thd.h",
-    "include/grpc++/impl/thd_cxx11.h",
-    "include/grpc++/impl/thd_no_cxx11.h",
-    "include/grpc++/security/auth_context.h",
-    "include/grpc++/security/auth_metadata_processor.h",
-    "include/grpc++/security/credentials.h",
-    "include/grpc++/security/server_credentials.h",
-    "include/grpc++/server.h",
-    "include/grpc++/server_builder.h",
-    "include/grpc++/server_context.h",
-    "include/grpc++/server_posix.h",
-    "include/grpc++/support/async_stream.h",
-    "include/grpc++/support/async_unary_call.h",
-    "include/grpc++/support/byte_buffer.h",
-    "include/grpc++/support/channel_arguments.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/slice.h",
-    "include/grpc++/support/status.h",
-    "include/grpc++/support/status_code_enum.h",
-    "include/grpc++/support/string_ref.h",
-    "include/grpc++/support/stub_options.h",
-    "include/grpc++/support/sync_stream.h",
-    "include/grpc++/support/time.h",
-    "include/grpc++/impl/codegen/async_stream.h",
-    "include/grpc++/impl/codegen/async_unary_call.h",
-    "include/grpc++/impl/codegen/call.h",
-    "include/grpc++/impl/codegen/call_hook.h",
-    "include/grpc++/impl/codegen/channel_interface.h",
-    "include/grpc++/impl/codegen/client_context.h",
-    "include/grpc++/impl/codegen/client_unary_call.h",
-    "include/grpc++/impl/codegen/completion_queue.h",
-    "include/grpc++/impl/codegen/completion_queue_tag.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/core_codegen_interface.h",
-    "include/grpc++/impl/codegen/create_auth_context.h",
-    "include/grpc++/impl/codegen/grpc_library.h",
-    "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/rpc_method.h",
-    "include/grpc++/impl/codegen/rpc_service_method.h",
-    "include/grpc++/impl/codegen/security/auth_context.h",
-    "include/grpc++/impl/codegen/serialization_traits.h",
-    "include/grpc++/impl/codegen/server_context.h",
-    "include/grpc++/impl/codegen/server_interface.h",
-    "include/grpc++/impl/codegen/service_type.h",
-    "include/grpc++/impl/codegen/status.h",
-    "include/grpc++/impl/codegen/status_code_enum.h",
-    "include/grpc++/impl/codegen/status_helper.h",
-    "include/grpc++/impl/codegen/string_ref.h",
-    "include/grpc++/impl/codegen/stub_options.h",
-    "include/grpc++/impl/codegen/sync.h",
-    "include/grpc++/impl/codegen/sync_cxx11.h",
-    "include/grpc++/impl/codegen/sync_no_cxx11.h",
-    "include/grpc++/impl/codegen/sync_stream.h",
-    "include/grpc++/impl/codegen/time.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    "//external:libssl",
-    "//external:protobuf_clib",
-    ":grpc",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc++_reflection",
-  srcs = [
-    "src/cpp/ext/proto_server_reflection.h",
-    "src/cpp/ext/proto_server_reflection.cc",
-    "src/cpp/ext/proto_server_reflection_plugin.cc",
-    "src/cpp/ext/reflection.grpc.pb.cc",
-    "src/cpp/ext/reflection.pb.cc",
-  ],
-  hdrs = [
-    "include/grpc++/ext/proto_server_reflection_plugin.h",
-    "include/grpc++/ext/reflection.grpc.pb.h",
-    "include/grpc++/ext/reflection.pb.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
-    "include/grpc++/impl/codegen/async_stream.h",
-    "include/grpc++/impl/codegen/async_unary_call.h",
-    "include/grpc++/impl/codegen/call.h",
-    "include/grpc++/impl/codegen/call_hook.h",
-    "include/grpc++/impl/codegen/channel_interface.h",
-    "include/grpc++/impl/codegen/client_context.h",
-    "include/grpc++/impl/codegen/client_unary_call.h",
-    "include/grpc++/impl/codegen/completion_queue.h",
-    "include/grpc++/impl/codegen/completion_queue_tag.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/core_codegen_interface.h",
-    "include/grpc++/impl/codegen/create_auth_context.h",
-    "include/grpc++/impl/codegen/grpc_library.h",
-    "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/rpc_method.h",
-    "include/grpc++/impl/codegen/rpc_service_method.h",
-    "include/grpc++/impl/codegen/security/auth_context.h",
-    "include/grpc++/impl/codegen/serialization_traits.h",
-    "include/grpc++/impl/codegen/server_context.h",
-    "include/grpc++/impl/codegen/server_interface.h",
-    "include/grpc++/impl/codegen/service_type.h",
-    "include/grpc++/impl/codegen/status.h",
-    "include/grpc++/impl/codegen/status_code_enum.h",
-    "include/grpc++/impl/codegen/status_helper.h",
-    "include/grpc++/impl/codegen/string_ref.h",
-    "include/grpc++/impl/codegen/stub_options.h",
-    "include/grpc++/impl/codegen/sync.h",
-    "include/grpc++/impl/codegen/sync_cxx11.h",
-    "include/grpc++/impl/codegen/sync_no_cxx11.h",
-    "include/grpc++/impl/codegen/sync_stream.h",
-    "include/grpc++/impl/codegen/time.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-    "include/grpc++/impl/codegen/config_protobuf.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    ":grpc++",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc++_unsecure",
-  srcs = [
-    "src/cpp/client/create_channel_internal.h",
-    "src/cpp/common/channel_filter.h",
-    "src/cpp/server/dynamic_thread_pool.h",
-    "src/cpp/server/thread_pool_interface.h",
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/insecure_create_auth_context.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/client/channel_cc.cc",
-    "src/cpp/client/client_context.cc",
-    "src/cpp/client/create_channel.cc",
-    "src/cpp/client/create_channel_internal.cc",
-    "src/cpp/client/create_channel_posix.cc",
-    "src/cpp/client/credentials_cc.cc",
-    "src/cpp/client/generic_stub.cc",
-    "src/cpp/common/channel_arguments.cc",
-    "src/cpp/common/channel_filter.cc",
-    "src/cpp/common/completion_queue_cc.cc",
-    "src/cpp/common/core_codegen.cc",
-    "src/cpp/common/rpc_method.cc",
-    "src/cpp/server/async_generic_service.cc",
-    "src/cpp/server/create_default_thread_pool.cc",
-    "src/cpp/server/dynamic_thread_pool.cc",
-    "src/cpp/server/server_builder.cc",
-    "src/cpp/server/server_cc.cc",
-    "src/cpp/server/server_context.cc",
-    "src/cpp/server/server_credentials.cc",
-    "src/cpp/server/server_posix.cc",
-    "src/cpp/util/byte_buffer_cc.cc",
-    "src/cpp/util/slice_cc.cc",
-    "src/cpp/util/status.cc",
-    "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time_cc.cc",
-    "src/cpp/codegen/codegen_init.cc",
-  ],
-  hdrs = [
-    "include/grpc++/alarm.h",
-    "include/grpc++/channel.h",
-    "include/grpc++/client_context.h",
-    "include/grpc++/completion_queue.h",
-    "include/grpc++/create_channel.h",
-    "include/grpc++/create_channel_posix.h",
-    "include/grpc++/generic/async_generic_service.h",
-    "include/grpc++/generic/generic_stub.h",
-    "include/grpc++/grpc++.h",
-    "include/grpc++/impl/call.h",
-    "include/grpc++/impl/client_unary_call.h",
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "include/grpc++/impl/grpc_library.h",
-    "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/rpc_method.h",
-    "include/grpc++/impl/rpc_service_method.h",
-    "include/grpc++/impl/serialization_traits.h",
-    "include/grpc++/impl/server_builder_option.h",
-    "include/grpc++/impl/server_builder_plugin.h",
-    "include/grpc++/impl/server_initializer.h",
-    "include/grpc++/impl/service_type.h",
-    "include/grpc++/impl/sync.h",
-    "include/grpc++/impl/sync_cxx11.h",
-    "include/grpc++/impl/sync_no_cxx11.h",
-    "include/grpc++/impl/thd.h",
-    "include/grpc++/impl/thd_cxx11.h",
-    "include/grpc++/impl/thd_no_cxx11.h",
-    "include/grpc++/security/auth_context.h",
-    "include/grpc++/security/auth_metadata_processor.h",
-    "include/grpc++/security/credentials.h",
-    "include/grpc++/security/server_credentials.h",
-    "include/grpc++/server.h",
-    "include/grpc++/server_builder.h",
-    "include/grpc++/server_context.h",
-    "include/grpc++/server_posix.h",
-    "include/grpc++/support/async_stream.h",
-    "include/grpc++/support/async_unary_call.h",
-    "include/grpc++/support/byte_buffer.h",
-    "include/grpc++/support/channel_arguments.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/slice.h",
-    "include/grpc++/support/status.h",
-    "include/grpc++/support/status_code_enum.h",
-    "include/grpc++/support/string_ref.h",
-    "include/grpc++/support/stub_options.h",
-    "include/grpc++/support/sync_stream.h",
-    "include/grpc++/support/time.h",
-    "include/grpc++/impl/codegen/async_stream.h",
-    "include/grpc++/impl/codegen/async_unary_call.h",
-    "include/grpc++/impl/codegen/call.h",
-    "include/grpc++/impl/codegen/call_hook.h",
-    "include/grpc++/impl/codegen/channel_interface.h",
-    "include/grpc++/impl/codegen/client_context.h",
-    "include/grpc++/impl/codegen/client_unary_call.h",
-    "include/grpc++/impl/codegen/completion_queue.h",
-    "include/grpc++/impl/codegen/completion_queue_tag.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/core_codegen_interface.h",
-    "include/grpc++/impl/codegen/create_auth_context.h",
-    "include/grpc++/impl/codegen/grpc_library.h",
-    "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/rpc_method.h",
-    "include/grpc++/impl/codegen/rpc_service_method.h",
-    "include/grpc++/impl/codegen/security/auth_context.h",
-    "include/grpc++/impl/codegen/serialization_traits.h",
-    "include/grpc++/impl/codegen/server_context.h",
-    "include/grpc++/impl/codegen/server_interface.h",
-    "include/grpc++/impl/codegen/service_type.h",
-    "include/grpc++/impl/codegen/status.h",
-    "include/grpc++/impl/codegen/status_code_enum.h",
-    "include/grpc++/impl/codegen/status_helper.h",
-    "include/grpc++/impl/codegen/string_ref.h",
-    "include/grpc++/impl/codegen/stub_options.h",
-    "include/grpc++/impl/codegen/sync.h",
-    "include/grpc++/impl/codegen/sync_cxx11.h",
-    "include/grpc++/impl/codegen/sync_no_cxx11.h",
-    "include/grpc++/impl/codegen/sync_stream.h",
-    "include/grpc++/impl/codegen/time.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    "//external:protobuf_clib",
-    ":gpr",
-    ":grpc_unsecure",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc_plugin_support",
-  srcs = [
-    "src/compiler/config.h",
-    "src/compiler/cpp_generator.h",
-    "src/compiler/cpp_generator_helpers.h",
-    "src/compiler/csharp_generator.h",
-    "src/compiler/csharp_generator_helpers.h",
-    "src/compiler/generator_helpers.h",
-    "src/compiler/node_generator.h",
-    "src/compiler/node_generator_helpers.h",
-    "src/compiler/objective_c_generator.h",
-    "src/compiler/objective_c_generator_helpers.h",
-    "src/compiler/php_generator.h",
-    "src/compiler/php_generator_helpers.h",
-    "src/compiler/python_generator.h",
-    "src/compiler/ruby_generator.h",
-    "src/compiler/ruby_generator_helpers-inl.h",
-    "src/compiler/ruby_generator_map-inl.h",
-    "src/compiler/ruby_generator_string-inl.h",
-    "src/compiler/cpp_generator.cc",
-    "src/compiler/csharp_generator.cc",
-    "src/compiler/node_generator.cc",
-    "src/compiler/objective_c_generator.cc",
-    "src/compiler/php_generator.cc",
-    "src/compiler/python_generator.cc",
-    "src/compiler/ruby_generator.cc",
-  ],
-  hdrs = [
-    "include/grpc++/impl/codegen/config_protobuf.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-  ],
-)
-
-
-
-cc_library(
-  name = "grpc_csharp_ext",
-  srcs = [
-    "src/csharp/ext/grpc_csharp_ext.c",
-  ],
-  hdrs = [
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    ":grpc",
-    ":gpr",
-  ],
-)
-
-
-
-
-objc_library(
-  name = "gpr_objc",
-  srcs = [
-    "src/core/lib/profiling/basic_timers.c",
-    "src/core/lib/profiling/stap_timers.c",
-    "src/core/lib/support/alloc.c",
-    "src/core/lib/support/avl.c",
-    "src/core/lib/support/backoff.c",
-    "src/core/lib/support/cmdline.c",
-    "src/core/lib/support/cpu_iphone.c",
-    "src/core/lib/support/cpu_linux.c",
-    "src/core/lib/support/cpu_posix.c",
-    "src/core/lib/support/cpu_windows.c",
-    "src/core/lib/support/env_linux.c",
-    "src/core/lib/support/env_posix.c",
-    "src/core/lib/support/env_windows.c",
-    "src/core/lib/support/histogram.c",
-    "src/core/lib/support/host_port.c",
-    "src/core/lib/support/log.c",
-    "src/core/lib/support/log_android.c",
-    "src/core/lib/support/log_linux.c",
-    "src/core/lib/support/log_posix.c",
-    "src/core/lib/support/log_windows.c",
-    "src/core/lib/support/mpscq.c",
-    "src/core/lib/support/murmur_hash.c",
-    "src/core/lib/support/percent_encoding.c",
-    "src/core/lib/support/slice.c",
-    "src/core/lib/support/slice_buffer.c",
-    "src/core/lib/support/stack_lockfree.c",
-    "src/core/lib/support/string.c",
-    "src/core/lib/support/string_posix.c",
-    "src/core/lib/support/string_util_windows.c",
-    "src/core/lib/support/string_windows.c",
-    "src/core/lib/support/subprocess_posix.c",
-    "src/core/lib/support/subprocess_windows.c",
-    "src/core/lib/support/sync.c",
-    "src/core/lib/support/sync_posix.c",
-    "src/core/lib/support/sync_windows.c",
-    "src/core/lib/support/thd.c",
-    "src/core/lib/support/thd_posix.c",
-    "src/core/lib/support/thd_windows.c",
-    "src/core/lib/support/time.c",
-    "src/core/lib/support/time_posix.c",
-    "src/core/lib/support/time_precise.c",
-    "src/core/lib/support/time_windows.c",
-    "src/core/lib/support/tls_pthread.c",
-    "src/core/lib/support/tmpfile_msys.c",
-    "src/core/lib/support/tmpfile_posix.c",
-    "src/core/lib/support/tmpfile_windows.c",
-    "src/core/lib/support/wrap_memcpy.c",
-  ],
-  hdrs = [
-    "include/grpc/support/alloc.h",
-    "include/grpc/support/atm.h",
-    "include/grpc/support/atm_gcc_atomic.h",
-    "include/grpc/support/atm_gcc_sync.h",
-    "include/grpc/support/atm_windows.h",
-    "include/grpc/support/avl.h",
-    "include/grpc/support/cmdline.h",
-    "include/grpc/support/cpu.h",
-    "include/grpc/support/histogram.h",
-    "include/grpc/support/host_port.h",
-    "include/grpc/support/log.h",
-    "include/grpc/support/log_windows.h",
-    "include/grpc/support/port_platform.h",
-    "include/grpc/support/slice.h",
-    "include/grpc/support/slice_buffer.h",
-    "include/grpc/support/string_util.h",
-    "include/grpc/support/subprocess.h",
-    "include/grpc/support/sync.h",
-    "include/grpc/support/sync_generic.h",
-    "include/grpc/support/sync_posix.h",
-    "include/grpc/support/sync_windows.h",
-    "include/grpc/support/thd.h",
-    "include/grpc/support/time.h",
-    "include/grpc/support/tls.h",
-    "include/grpc/support/tls_gcc.h",
-    "include/grpc/support/tls_msvc.h",
-    "include/grpc/support/tls_pthread.h",
-    "include/grpc/support/useful.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-    "src/core/lib/profiling/timers.h",
-    "src/core/lib/support/backoff.h",
-    "src/core/lib/support/block_annotate.h",
-    "src/core/lib/support/env.h",
-    "src/core/lib/support/mpscq.h",
-    "src/core/lib/support/murmur_hash.h",
-    "src/core/lib/support/percent_encoding.h",
-    "src/core/lib/support/stack_lockfree.h",
-    "src/core/lib/support/string.h",
-    "src/core/lib/support/string_windows.h",
-    "src/core/lib/support/thd_internal.h",
-    "src/core/lib/support/time_precise.h",
-    "src/core/lib/support/tmpfile.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-  ],
-)
-
-
-
-objc_library(
-  name = "grpc_objc",
-  srcs = [
-    "src/core/lib/surface/init.c",
-    "src/core/lib/channel/channel_args.c",
-    "src/core/lib/channel/channel_stack.c",
-    "src/core/lib/channel/channel_stack_builder.c",
-    "src/core/lib/channel/compress_filter.c",
-    "src/core/lib/channel/connected_channel.c",
-    "src/core/lib/channel/deadline_filter.c",
-    "src/core/lib/channel/handshaker.c",
-    "src/core/lib/channel/http_client_filter.c",
-    "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/channel/message_size_filter.c",
-    "src/core/lib/compression/compression.c",
-    "src/core/lib/compression/message_compress.c",
-    "src/core/lib/debug/trace.c",
-    "src/core/lib/http/format_request.c",
-    "src/core/lib/http/httpcli.c",
-    "src/core/lib/http/parser.c",
-    "src/core/lib/iomgr/closure.c",
-    "src/core/lib/iomgr/combiner.c",
-    "src/core/lib/iomgr/endpoint.c",
-    "src/core/lib/iomgr/endpoint_pair_posix.c",
-    "src/core/lib/iomgr/endpoint_pair_windows.c",
-    "src/core/lib/iomgr/error.c",
-    "src/core/lib/iomgr/ev_epoll_linux.c",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
-    "src/core/lib/iomgr/ev_poll_posix.c",
-    "src/core/lib/iomgr/ev_posix.c",
-    "src/core/lib/iomgr/exec_ctx.c",
-    "src/core/lib/iomgr/executor.c",
-    "src/core/lib/iomgr/iocp_windows.c",
-    "src/core/lib/iomgr/iomgr.c",
-    "src/core/lib/iomgr/iomgr_posix.c",
-    "src/core/lib/iomgr/iomgr_windows.c",
-    "src/core/lib/iomgr/load_file.c",
-    "src/core/lib/iomgr/network_status_tracker.c",
-    "src/core/lib/iomgr/polling_entity.c",
-    "src/core/lib/iomgr/pollset_set_windows.c",
-    "src/core/lib/iomgr/pollset_windows.c",
-    "src/core/lib/iomgr/resolve_address_posix.c",
-    "src/core/lib/iomgr/resolve_address_windows.c",
-    "src/core/lib/iomgr/sockaddr_utils.c",
-    "src/core/lib/iomgr/socket_utils_common_posix.c",
-    "src/core/lib/iomgr/socket_utils_linux.c",
-    "src/core/lib/iomgr/socket_utils_posix.c",
-    "src/core/lib/iomgr/socket_windows.c",
-    "src/core/lib/iomgr/tcp_client_posix.c",
-    "src/core/lib/iomgr/tcp_client_windows.c",
-    "src/core/lib/iomgr/tcp_posix.c",
-    "src/core/lib/iomgr/tcp_server_posix.c",
-    "src/core/lib/iomgr/tcp_server_windows.c",
-    "src/core/lib/iomgr/tcp_windows.c",
-    "src/core/lib/iomgr/time_averaged_stats.c",
-    "src/core/lib/iomgr/timer.c",
-    "src/core/lib/iomgr/timer_heap.c",
-    "src/core/lib/iomgr/udp_server.c",
-    "src/core/lib/iomgr/unix_sockets_posix.c",
-    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
-    "src/core/lib/iomgr/wakeup_fd_cv.c",
-    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
-    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
-    "src/core/lib/iomgr/wakeup_fd_pipe.c",
-    "src/core/lib/iomgr/wakeup_fd_posix.c",
-    "src/core/lib/iomgr/workqueue_windows.c",
-    "src/core/lib/json/json.c",
-    "src/core/lib/json/json_reader.c",
-    "src/core/lib/json/json_string.c",
-    "src/core/lib/json/json_writer.c",
-    "src/core/lib/surface/alarm.c",
-    "src/core/lib/surface/api_trace.c",
-    "src/core/lib/surface/byte_buffer.c",
-    "src/core/lib/surface/byte_buffer_reader.c",
-    "src/core/lib/surface/call.c",
-    "src/core/lib/surface/call_details.c",
-    "src/core/lib/surface/call_log_batch.c",
-    "src/core/lib/surface/channel.c",
-    "src/core/lib/surface/channel_init.c",
-    "src/core/lib/surface/channel_ping.c",
-    "src/core/lib/surface/channel_stack_type.c",
-    "src/core/lib/surface/completion_queue.c",
-    "src/core/lib/surface/event_string.c",
-    "src/core/lib/surface/lame_client.c",
-    "src/core/lib/surface/metadata_array.c",
-    "src/core/lib/surface/server.c",
-    "src/core/lib/surface/validate_metadata.c",
-    "src/core/lib/surface/version.c",
-    "src/core/lib/transport/byte_stream.c",
-    "src/core/lib/transport/connectivity_state.c",
-    "src/core/lib/transport/mdstr_hash_table.c",
-    "src/core/lib/transport/metadata.c",
-    "src/core/lib/transport/metadata_batch.c",
-    "src/core/lib/transport/static_metadata.c",
-    "src/core/lib/transport/timeout_encoding.c",
-    "src/core/lib/transport/transport.c",
-    "src/core/lib/transport/transport_op_string.c",
-    "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.c",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
-    "src/core/ext/transport/chttp2/transport/frame_data.c",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
-    "src/core/ext/transport/chttp2/transport/frame_ping.c",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
-    "src/core/ext/transport/chttp2/transport/frame_settings.c",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
-    "src/core/ext/transport/chttp2/transport/hpack_table.c",
-    "src/core/ext/transport/chttp2/transport/huffsyms.c",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
-    "src/core/ext/transport/chttp2/transport/parsing.c",
-    "src/core/ext/transport/chttp2/transport/status_conversion.c",
-    "src/core/ext/transport/chttp2/transport/stream_lists.c",
-    "src/core/ext/transport/chttp2/transport/stream_map.c",
-    "src/core/ext/transport/chttp2/transport/varint.c",
-    "src/core/ext/transport/chttp2/transport/writing.c",
-    "src/core/ext/transport/chttp2/alpn/alpn.c",
-    "src/core/lib/http/httpcli_security_connector.c",
-    "src/core/lib/security/context/security_context.c",
-    "src/core/lib/security/credentials/composite/composite_credentials.c",
-    "src/core/lib/security/credentials/credentials.c",
-    "src/core/lib/security/credentials/credentials_metadata.c",
-    "src/core/lib/security/credentials/fake/fake_credentials.c",
-    "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_windows.c",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
-    "src/core/lib/security/credentials/iam/iam_credentials.c",
-    "src/core/lib/security/credentials/jwt/json_token.c",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
-    "src/core/lib/security/transport/client_auth_filter.c",
-    "src/core/lib/security/transport/handshake.c",
-    "src/core/lib/security/transport/secure_endpoint.c",
-    "src/core/lib/security/transport/security_connector.c",
-    "src/core/lib/security/transport/server_auth_filter.c",
-    "src/core/lib/security/transport/tsi_error.c",
-    "src/core/lib/security/util/b64.c",
-    "src/core/lib/security/util/json_util.c",
-    "src/core/lib/surface/init_secure.c",
-    "src/core/lib/tsi/fake_transport_security.c",
-    "src/core/lib/tsi/ssl_transport_security.c",
-    "src/core/lib/tsi/transport_security.c",
-    "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
-    "src/core/ext/client_config/channel_connectivity.c",
-    "src/core/ext/client_config/client_channel.c",
-    "src/core/ext/client_config/client_channel_factory.c",
-    "src/core/ext/client_config/client_config_plugin.c",
-    "src/core/ext/client_config/connector.c",
-    "src/core/ext/client_config/default_initial_connect_string.c",
-    "src/core/ext/client_config/http_connect_handshaker.c",
-    "src/core/ext/client_config/initial_connect_string.c",
-    "src/core/ext/client_config/lb_policy.c",
-    "src/core/ext/client_config/lb_policy_factory.c",
-    "src/core/ext/client_config/lb_policy_registry.c",
-    "src/core/ext/client_config/method_config.c",
-    "src/core/ext/client_config/parse_address.c",
-    "src/core/ext/client_config/resolver.c",
-    "src/core/ext/client_config/resolver_factory.c",
-    "src/core/ext/client_config/resolver_registry.c",
-    "src/core/ext/client_config/resolver_result.c",
-    "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_index.c",
-    "src/core/ext/client_config/uri_parser.c",
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
-    "src/core/ext/lb_policy/grpclb/grpclb.c",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
-    "src/core/ext/lb_policy/pick_first/pick_first.c",
-    "src/core/ext/lb_policy/round_robin/round_robin.c",
-    "src/core/ext/resolver/dns/native/dns_resolver.c",
-    "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
-    "src/core/ext/load_reporting/load_reporting.c",
-    "src/core/ext/load_reporting/load_reporting_filter.c",
-    "src/core/ext/census/base_resources.c",
-    "src/core/ext/census/context.c",
-    "src/core/ext/census/gen/census.pb.c",
-    "src/core/ext/census/gen/trace_context.pb.c",
-    "src/core/ext/census/grpc_context.c",
-    "src/core/ext/census/grpc_filter.c",
-    "src/core/ext/census/grpc_plugin.c",
-    "src/core/ext/census/initialize.c",
-    "src/core/ext/census/mlog.c",
-    "src/core/ext/census/operation.c",
-    "src/core/ext/census/placeholders.c",
-    "src/core/ext/census/resource.c",
-    "src/core/ext/census/trace_context.c",
-    "src/core/ext/census/tracing.c",
-    "src/core/plugin_registry/grpc_plugin_registry.c",
-  ],
-  hdrs = [
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/grpc_posix.h",
-    "include/grpc/grpc_security_constants.h",
-    "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-    "include/grpc/grpc_security.h",
-    "include/grpc/census.h",
-    "src/core/lib/channel/channel_args.h",
-    "src/core/lib/channel/channel_stack.h",
-    "src/core/lib/channel/channel_stack_builder.h",
-    "src/core/lib/channel/compress_filter.h",
-    "src/core/lib/channel/connected_channel.h",
-    "src/core/lib/channel/context.h",
-    "src/core/lib/channel/deadline_filter.h",
-    "src/core/lib/channel/handshaker.h",
-    "src/core/lib/channel/http_client_filter.h",
-    "src/core/lib/channel/http_server_filter.h",
-    "src/core/lib/channel/message_size_filter.h",
-    "src/core/lib/compression/algorithm_metadata.h",
-    "src/core/lib/compression/message_compress.h",
-    "src/core/lib/debug/trace.h",
-    "src/core/lib/http/format_request.h",
-    "src/core/lib/http/httpcli.h",
-    "src/core/lib/http/parser.h",
-    "src/core/lib/iomgr/closure.h",
-    "src/core/lib/iomgr/combiner.h",
-    "src/core/lib/iomgr/endpoint.h",
-    "src/core/lib/iomgr/endpoint_pair.h",
-    "src/core/lib/iomgr/error.h",
-    "src/core/lib/iomgr/ev_epoll_linux.h",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
-    "src/core/lib/iomgr/ev_poll_posix.h",
-    "src/core/lib/iomgr/ev_posix.h",
-    "src/core/lib/iomgr/exec_ctx.h",
-    "src/core/lib/iomgr/executor.h",
-    "src/core/lib/iomgr/iocp_windows.h",
-    "src/core/lib/iomgr/iomgr.h",
-    "src/core/lib/iomgr/iomgr_internal.h",
-    "src/core/lib/iomgr/iomgr_posix.h",
-    "src/core/lib/iomgr/load_file.h",
-    "src/core/lib/iomgr/network_status_tracker.h",
-    "src/core/lib/iomgr/polling_entity.h",
-    "src/core/lib/iomgr/pollset.h",
-    "src/core/lib/iomgr/pollset_set.h",
-    "src/core/lib/iomgr/pollset_set_windows.h",
-    "src/core/lib/iomgr/pollset_windows.h",
-    "src/core/lib/iomgr/resolve_address.h",
-    "src/core/lib/iomgr/sockaddr.h",
-    "src/core/lib/iomgr/sockaddr_posix.h",
-    "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_windows.h",
-    "src/core/lib/iomgr/socket_utils_posix.h",
-    "src/core/lib/iomgr/socket_windows.h",
-    "src/core/lib/iomgr/tcp_client.h",
-    "src/core/lib/iomgr/tcp_posix.h",
-    "src/core/lib/iomgr/tcp_server.h",
-    "src/core/lib/iomgr/tcp_windows.h",
-    "src/core/lib/iomgr/time_averaged_stats.h",
-    "src/core/lib/iomgr/timer.h",
-    "src/core/lib/iomgr/timer_heap.h",
-    "src/core/lib/iomgr/udp_server.h",
-    "src/core/lib/iomgr/unix_sockets_posix.h",
-    "src/core/lib/iomgr/wakeup_fd_cv.h",
-    "src/core/lib/iomgr/wakeup_fd_pipe.h",
-    "src/core/lib/iomgr/wakeup_fd_posix.h",
-    "src/core/lib/iomgr/workqueue.h",
-    "src/core/lib/iomgr/workqueue_windows.h",
-    "src/core/lib/json/json.h",
-    "src/core/lib/json/json_common.h",
-    "src/core/lib/json/json_reader.h",
-    "src/core/lib/json/json_writer.h",
-    "src/core/lib/surface/api_trace.h",
-    "src/core/lib/surface/call.h",
-    "src/core/lib/surface/call_test_only.h",
-    "src/core/lib/surface/channel.h",
-    "src/core/lib/surface/channel_init.h",
-    "src/core/lib/surface/channel_stack_type.h",
-    "src/core/lib/surface/completion_queue.h",
-    "src/core/lib/surface/event_string.h",
-    "src/core/lib/surface/init.h",
-    "src/core/lib/surface/lame_client.h",
-    "src/core/lib/surface/server.h",
-    "src/core/lib/transport/byte_stream.h",
-    "src/core/lib/transport/connectivity_state.h",
-    "src/core/lib/transport/mdstr_hash_table.h",
-    "src/core/lib/transport/metadata.h",
-    "src/core/lib/transport/metadata_batch.h",
-    "src/core/lib/transport/static_metadata.h",
-    "src/core/lib/transport/timeout_encoding.h",
-    "src/core/lib/transport/transport.h",
-    "src/core/lib/transport/transport_impl.h",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
-    "src/core/ext/transport/chttp2/transport/frame.h",
-    "src/core/ext/transport/chttp2/transport/frame_data.h",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
-    "src/core/ext/transport/chttp2/transport/frame_ping.h",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
-    "src/core/ext/transport/chttp2/transport/frame_settings.h",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
-    "src/core/ext/transport/chttp2/transport/hpack_table.h",
-    "src/core/ext/transport/chttp2/transport/http2_errors.h",
-    "src/core/ext/transport/chttp2/transport/huffsyms.h",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
-    "src/core/ext/transport/chttp2/transport/internal.h",
-    "src/core/ext/transport/chttp2/transport/status_conversion.h",
-    "src/core/ext/transport/chttp2/transport/stream_map.h",
-    "src/core/ext/transport/chttp2/transport/varint.h",
-    "src/core/ext/transport/chttp2/alpn/alpn.h",
-    "src/core/lib/security/context/security_context.h",
-    "src/core/lib/security/credentials/composite/composite_credentials.h",
-    "src/core/lib/security/credentials/credentials.h",
-    "src/core/lib/security/credentials/fake/fake_credentials.h",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
-    "src/core/lib/security/credentials/iam/iam_credentials.h",
-    "src/core/lib/security/credentials/jwt/json_token.h",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
-    "src/core/lib/security/transport/auth_filters.h",
-    "src/core/lib/security/transport/handshake.h",
-    "src/core/lib/security/transport/secure_endpoint.h",
-    "src/core/lib/security/transport/security_connector.h",
-    "src/core/lib/security/transport/tsi_error.h",
-    "src/core/lib/security/util/b64.h",
-    "src/core/lib/security/util/json_util.h",
-    "src/core/lib/tsi/fake_transport_security.h",
-    "src/core/lib/tsi/ssl_transport_security.h",
-    "src/core/lib/tsi/ssl_types.h",
-    "src/core/lib/tsi/transport_security.h",
-    "src/core/lib/tsi/transport_security_interface.h",
-    "src/core/ext/client_config/client_channel.h",
-    "src/core/ext/client_config/client_channel_factory.h",
-    "src/core/ext/client_config/connector.h",
-    "src/core/ext/client_config/http_connect_handshaker.h",
-    "src/core/ext/client_config/initial_connect_string.h",
-    "src/core/ext/client_config/lb_policy.h",
-    "src/core/ext/client_config/lb_policy_factory.h",
-    "src/core/ext/client_config/lb_policy_registry.h",
-    "src/core/ext/client_config/method_config.h",
-    "src/core/ext/client_config/parse_address.h",
-    "src/core/ext/client_config/resolver.h",
-    "src/core/ext/client_config/resolver_factory.h",
-    "src/core/ext/client_config/resolver_registry.h",
-    "src/core/ext/client_config/resolver_result.h",
-    "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_index.h",
-    "src/core/ext/client_config/uri_parser.h",
-    "src/core/ext/lb_policy/grpclb/grpclb.h",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
-    "src/core/ext/load_reporting/load_reporting.h",
-    "src/core/ext/load_reporting/load_reporting_filter.h",
-    "src/core/ext/census/aggregation.h",
-    "src/core/ext/census/base_resources.h",
-    "src/core/ext/census/census_interface.h",
-    "src/core/ext/census/census_rpc_stats.h",
-    "src/core/ext/census/gen/census.pb.h",
-    "src/core/ext/census/gen/trace_context.pb.h",
-    "src/core/ext/census/grpc_filter.h",
-    "src/core/ext/census/mlog.h",
-    "src/core/ext/census/resource.h",
-    "src/core/ext/census/rpc_metric_id.h",
-    "src/core/ext/census/trace_context.h",
-  ],
-  includes = [
-    "include",
-    ".",
-  ],
-  deps = [
-    ":gpr_objc",
-    "//external:libssl_objc",
-    "//external:nanopb",
-  ],
-  sdk_dylibs = ["libz"],
-)
-
-
-
-cc_binary(
-  name = "grpc_cpp_plugin",
-  srcs = [
-    "src/compiler/cpp_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_csharp_plugin",
-  srcs = [
-    "src/compiler/csharp_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_node_plugin",
-  srcs = [
-    "src/compiler/node_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_objective_c_plugin",
-  srcs = [
-    "src/compiler/objective_c_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_php_plugin",
-  srcs = [
-    "src/compiler/php_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_python_plugin",
-  srcs = [
-    "src/compiler/python_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-cc_binary(
-  name = "grpc_ruby_plugin",
-  srcs = [
-    "src/compiler/ruby_plugin.cc",
-  ],
-  deps = [
-    "//external:protobuf_compiler",
-    ":grpc_plugin_support",
-  ],
-)
-
-
-
-
-
-
-
-
-objc_path = "src/objective-c"
-
-rx_library_path = objc_path + "/RxLibrary"
-
-objc_library(
-  name = "rx_library",
-  hdrs = glob([
-    rx_library_path + "/*.h",
-    rx_library_path + "/transformations/*.h",
-  ]),
-  srcs = glob([
-    rx_library_path + "/*.m",
-    rx_library_path + "/transformations/*.m",
-  ]),
-  includes = [objc_path],
-  deps = [
-    ":rx_library_private",
-  ],
-)
-
-objc_library(
-  name = "rx_library_private",
-  hdrs = glob([rx_library_path + "/private/*.h"]),
-  srcs = glob([rx_library_path + "/private/*.m"]),
-  visibility = ["//visibility:private"],
-)
-
-objc_client_path = objc_path + "/GRPCClient"
-
-objc_library(
-  name = "grpc_client",
-  hdrs = glob([
-    objc_client_path + "/*.h",
-    objc_client_path + "/private/*.h",
-  ]),
-  srcs = glob([
-    objc_client_path + "/*.m",
-    objc_client_path + "/private/*.m",
-  ]),
-  includes = [objc_path],
-  bundles = [":gRPCCertificates"],
-  deps = [
-    ":grpc_objc",
-    ":rx_library",
-  ],
-)
-
-objc_bundle_library(
-    # The choice of name is signicant here, since it determines the bundle name.
-    name = "gRPCCertificates",
-    resources = ["etc/roots.pem"],
-)
-
-proto_objc_rpc_path = objc_path + "/ProtoRPC"
-
-objc_library(
-  name = "proto_objc_rpc",
-  hdrs = glob([
-    proto_objc_rpc_path + "/*.h",
-  ]),
-  srcs = glob([
-    proto_objc_rpc_path + "/*.m",
-  ]),
-  includes = [objc_path],
-  deps = [
-    ":grpc_client",
-    ":rx_library",
-    "//external:protobuf_objc",
+    "//external:protobuf_clib",
+    ":grpc",
   ],
 )
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000000..6a1b70e152
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,42 @@
+bind(
+    name = "nanopb",
+    actual = "//third_party/nanopb",
+)
+
+bind(
+    name = "libssl",
+    actual = "@submodule_boringssl//:ssl",
+)
+
+bind(
+    name = "zlib",
+    actual = "@submodule_zlib//:z",
+)
+
+bind(
+    name = "protobuf_clib",
+    actual = "@submodule_protobuf//:protoc_lib",
+)
+
+bind(
+    name = "protobuf_compiler",
+    actual = "@submodule_protobuf//:protoc_lib",
+)
+
+new_local_repository(
+    name = "submodule_boringssl",
+    path = "third_party/boringssl",
+    build_file = "third_party/boringssl/BUILD",
+)
+
+new_local_repository(
+    name = "submodule_zlib",
+    path = "third_party/zlib",
+    build_file = "third_party/zlib.BUILD",
+)
+
+new_local_repository(
+    name = "submodule_protobuf",
+    path = "third_party/protobuf",
+    build_file = "third_party/protobuf/BUILD",
+)
diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
new file mode 100644
index 0000000000..1d6d1a42c2
--- /dev/null
+++ b/grpc-build-system.bzl
@@ -0,0 +1,31 @@
+def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, language = "C++"):
+  copts = []
+  if language == "C":
+    copts = ["-std=c99"]
+  native.cc_library(
+    name = name,
+    srcs = srcs,
+    hdrs = hdrs,
+    deps = deps,
+    copts = copts,
+    includes = [
+        "include"
+    ]
+  )
+
+
+def nanopb():
+  native.cc_library(
+    name = "nanopb",
+    srcs = [
+      '//third_party/nanopb/pb_common.c',
+      '//third_party/nanopb/pb_decode.c',
+      '//third_party/nanopb/pb_encode.c',
+    ],
+    hdrs = [
+      '//third_party/nanopb/pb.h',
+      '//third_party/nanopb/pb_common.h',
+      '//third_party/nanopb/pb_decode.h',
+      '//third_party/nanopb/pb_encode.h',
+    ]
+  )
diff --git a/templates/BUILD.template b/templates/BUILD.template
deleted file mode 100644
index af23fb2799..0000000000
--- a/templates/BUILD.template
+++ /dev/null
@@ -1,256 +0,0 @@
-%YAML 1.2
---- |
-  # GRPC Bazel BUILD file.
-  # This currently builds C, C++ and Objective-C code.
-  # This file has been automatically generated from a template file.
-  # Please look at the templates directory instead.
-  # This file can be regenerated from the template by running
-  # tools/buildgen/generate_projects.sh
-  
-  # 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.
-  
-  licenses(["notice"])  # 3-clause BSD
-  
-  exports_files(["LICENSE"])
-  
-  package(default_visibility = ["//visibility:public"])
-  
-  <%!
-  def get_deps(target_dict):
-    deps = []
-    if target_dict.get('secure', False):
-      deps = [
-        "//external:libssl",
-      ]
-    if target_dict.get('build', None) == 'protoc':
-      deps.append("//external:protobuf_compiler")
-    if (target_dict['name'] == 'grpc++_unsecure' or
-        target_dict['name'] == 'grpc++' or
-        target_dict['name'] == 'grpc++_codegen_lib'):
-      deps.append("//external:protobuf_clib")
-    elif target_dict['name'] == 'grpc':
-      deps.append("//external:zlib")
-    for d in target_dict.get('deps', []):
-      if d.find('//') == 0 or d[0] == ':':
-        deps.append(d)
-      else:
-        deps.append(':%s' % (d))
-    return deps
-  %>
-
-  % for lib in libs:
-  % if lib.build in ("all", "protoc"):
-  ${cc_library(lib)}
-  % endif
-  % endfor
-  
-  % for lib in libs:
-  % if lib.name in ("grpc", "gpr"):
-  ${objc_library(lib)}
-  % endif
-  % endfor
-  
-  % for tgt in targets:
-  % if tgt.build == 'protoc':
-  ${cc_binary(tgt)}
-  % endif
-  % endfor
-  
-  <%def name="cc_library(lib)">
-  <%
-    lib_hdrs = lib.get("headers", [])
-    hdrs = [h for h in lib_hdrs if not h.startswith('third_party/nanopb')]
-    srcs = [s for s in lib.src if not s.startswith('third_party/nanopb')]
-    uses_nanopb = len(lib_hdrs) != len(hdrs) or len(srcs) != len(lib.src)
-  %>
-  cc_library(
-    name = "${lib.name}",
-    srcs = [
-  % for hdr in hdrs:
-      "${hdr}",
-  % endfor
-  % for src in srcs:
-      "${src}",
-  % endfor
-    ],
-    hdrs = [
-  % for hdr in lib.get("public_headers", []):
-      "${hdr}",
-  % endfor
-    ],
-    includes = [
-      "include",
-      ".",
-    ],
-    deps = [
-  % for dep in get_deps(lib):
-      "${dep}",
-  % endfor
-  % if uses_nanopb:
-      "//external:nanopb",
-  % endif
-    ],
-  % if lib.name in ("grpc", "grpc_unsecure"):
-    copts = [
-      "-std=gnu99",
-    ],
-  % endif
-  )
-  </%def>
-  
-  <%def name="objc_library(lib)">
-  <%
-    lib_hdrs = lib.get("headers", [])
-    hdrs = [h for h in lib_hdrs if not h.startswith('third_party/nanopb')]
-    srcs = [s for s in lib.src if not s.startswith('third_party/nanopb')]
-    uses_nanopb = len(lib_hdrs) != len(hdrs) or len(srcs) != len(lib.src)
-  %>
-  objc_library(
-    name = "${lib.name}_objc",
-    srcs = [
-  % for src in srcs:
-      "${src}",
-  % endfor
-    ],
-    hdrs = [
-  % for hdr in lib.get("public_headers", []):
-      "${hdr}",
-  % endfor
-  % for hdr in hdrs:
-      "${hdr}",
-  % endfor
-    ],
-    includes = [
-      "include",
-      ".",
-    ],
-    deps = [
-  % for dep in lib.get("deps", []):
-      ":${dep}_objc",
-  % endfor
-  % if lib.get('secure', False):
-      "//external:libssl_objc",
-  % endif
-  % if uses_nanopb:
-      "//external:nanopb",
-  % endif
-    ],
-  % if lib.get("baselib", false):
-    sdk_dylibs = ["libz"],
-  % endif
-  )
-  </%def>
-  
-  <%def name="cc_binary(tgt)">
-  cc_binary(
-    name = "${tgt.name}",
-    srcs = [
-  % for src in tgt.src:
-      "${src}",
-  % endfor
-    ],
-    deps = [
-  % for dep in get_deps(tgt):
-      "${dep}",
-  % endfor
-    ],
-  )
-  </%def>
-  
-  objc_path = "src/objective-c"
-  
-  rx_library_path = objc_path + "/RxLibrary"
-  
-  objc_library(
-    name = "rx_library",
-    hdrs = glob([
-      rx_library_path + "/*.h",
-      rx_library_path + "/transformations/*.h",
-    ]),
-    srcs = glob([
-      rx_library_path + "/*.m",
-      rx_library_path + "/transformations/*.m",
-    ]),
-    includes = [objc_path],
-    deps = [
-      ":rx_library_private",
-    ],
-  )
-  
-  objc_library(
-    name = "rx_library_private",
-    hdrs = glob([rx_library_path + "/private/*.h"]),
-    srcs = glob([rx_library_path + "/private/*.m"]),
-    visibility = ["//visibility:private"],
-  )
-  
-  objc_client_path = objc_path + "/GRPCClient"
-  
-  objc_library(
-    name = "grpc_client",
-    hdrs = glob([
-      objc_client_path + "/*.h",
-      objc_client_path + "/private/*.h",
-    ]),
-    srcs = glob([
-      objc_client_path + "/*.m",
-      objc_client_path + "/private/*.m",
-    ]),
-    includes = [objc_path],
-    bundles = [":gRPCCertificates"],
-    deps = [
-      ":grpc_objc",
-      ":rx_library",
-    ],
-  )
-  
-  objc_bundle_library(
-      # The choice of name is signicant here, since it determines the bundle name.
-      name = "gRPCCertificates",
-      resources = ["etc/roots.pem"],
-  )
-  
-  proto_objc_rpc_path = objc_path + "/ProtoRPC"
-  
-  objc_library(
-    name = "proto_objc_rpc",
-    hdrs = glob([
-      proto_objc_rpc_path + "/*.h",
-    ]),
-    srcs = glob([
-      proto_objc_rpc_path + "/*.m",
-    ]),
-    includes = [objc_path],
-    deps = [
-      ":grpc_client",
-      ":rx_library",
-      "//external:protobuf_objc",
-    ],
-  )
diff --git a/third_party/boringssl b/third_party/boringssl
index c880e42ba1..d4f6204cf1 160000
--- a/third_party/boringssl
+++ b/third_party/boringssl
@@ -1 +1 @@
-Subproject commit c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9
+Subproject commit d4f6204cf17ac99cfcbb2a6803483af650c88256
diff --git a/third_party/zlib.BUILD b/third_party/zlib.BUILD
new file mode 100644
index 0000000000..323c2868a8
--- /dev/null
+++ b/third_party/zlib.BUILD
@@ -0,0 +1,37 @@
+cc_library(
+  name = "z",
+  linkstatic = 1,
+  srcs = [
+    'adler32.c',
+    'compress.c',
+    'crc32.c',
+    'deflate.c',
+    'infback.c',
+    'inffast.c',
+    'inflate.c',
+    'inftrees.c',
+    'trees.c',
+    'uncompr.c',
+    'zutil.c',
+  ],
+  hdrs = [
+    'crc32.h',
+    'deflate.h',
+    'gzguts.h',
+    'inffast.h',
+    'inffixed.h',
+    'inflate.h',
+    'inftrees.h',
+    'trees.h',
+    'zconf.h',
+    'zlib.h',
+    'zutil.h',
+  ],
+  includes = [
+      'include',
+  ],
+  visibility = [
+    "//visibility:public",
+  ],
+)
+
-- 
GitLab


From 60ca22fef5e6e89311eee11c7aa6d7a6a5aff430 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 10:23:53 +0200
Subject: [PATCH 002/344] Basic testing.

---
 grpc-build-system.bzl   |   1 +
 test/core/support/BUILD | 125 ++++++++++++++++++++++++++++++++++++++++
 test/core/util/BUILD    |  45 +++++++++++++++
 3 files changed, 171 insertions(+)
 create mode 100644 test/core/support/BUILD
 create mode 100644 test/core/util/BUILD

diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index 1d6d1a42c2..c18c57f087 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -8,6 +8,7 @@ def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, l
     hdrs = hdrs,
     deps = deps,
     copts = copts,
+    linkopts = ["-pthread"],
     includes = [
         "include"
     ]
diff --git a/test/core/support/BUILD b/test/core/support/BUILD
new file mode 100644
index 0000000000..50b8ca37c2
--- /dev/null
+++ b/test/core/support/BUILD
@@ -0,0 +1,125 @@
+cc_test(
+    name = "alloc_test",
+    srcs = ["alloc_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "avl_test",
+    srcs = ["avl_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "backoff_test",
+    srcs = ["backoff_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "cmdline_test",
+    srcs = ["cmdline_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "cpu_test",
+    srcs = ["cpu_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "env_test",
+    srcs = ["env_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "histogram_test",
+    srcs = ["histogram_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "host_port_test",
+    srcs = ["host_port_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "log_test",
+    srcs = ["log_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "mpscq_test",
+    srcs = ["mpscq_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "murmur_hash_test",
+    srcs = ["murmur_hash_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "percent_encoding_test",
+    srcs = ["percent_encoding_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "slice_buffer_test",
+    srcs = ["slice_buffer_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "slice_test",
+    srcs = ["slice_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "stack_lockfree_test",
+    srcs = ["stack_lockfree_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "string_test",
+    srcs = ["string_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "sync_test",
+    srcs = ["sync_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "thd_test",
+    srcs = ["thd_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "time_test",
+    srcs = ["time_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "tls_test",
+    srcs = ["tls_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+    name = "useful_test",
+    srcs = ["useful_test.c"],
+    deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+)
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
new file mode 100644
index 0000000000..60dd6d9895
--- /dev/null
+++ b/test/core/util/BUILD
@@ -0,0 +1,45 @@
+
+
+cc_library(
+    name = "gpr_test_util",
+    srcs = [
+        "test_config.c",
+    ],
+    hdrs = [
+        "test_config.h",
+    ],
+    deps = ["//:gpr"],
+    visibility = ["//:__subpackages__"],
+)
+
+cc_library(
+    name = "grpc_test_util",
+    srcs = [
+        "grpc_profiler.c",
+        "memory_counters.c",
+        "mock_endpoint.c",
+        "one_corpus_entry_fuzzer.c",
+        "parse_hexstring.c",
+        "passthru_endpoint.c",
+        "port_posix.c",
+        "port_server_client.c",
+        "port_windows.c",
+        "reconnect_server.c",
+        "slice_splitter.c",
+        "test_tcp_server.c",
+    ],
+    hdrs = [
+        "grpc_profiler.h",
+        "memory_counters.h",
+        "mock_endpoint.h",
+        "parse_hexstring.h",
+        "passthru_endpoint.h",
+        "port.h",
+        "port_server_client.h",
+        "reconnect_server.h",
+        "slice_splitter.h",
+        "test_tcp_server.h",
+    ],
+    deps = [":gpr_test_util", "//:grpc"],
+    visibility = ["//:__subpackages__"],
+)
-- 
GitLab


From 423ecff2dea164ba96a14d06cad35ad307a128b8 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 09:45:09 -0700
Subject: [PATCH 003/344] Add copyright

---
 grpc-build-system.bzl | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index c18c57f087..c1a61efd12 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, language = "C++"):
   copts = []
   if language == "C":
-- 
GitLab


From e8dbd8aaae5d813546abe4956361c4e6512d8c88 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 18:54:36 +0200
Subject: [PATCH 004/344] Adding back external_deps and public_hdrs.

---
 BUILD                 | 14 +++++++++-----
 grpc-build-system.bzl | 29 +++++++++--------------------
 2 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/BUILD b/BUILD
index a0320bc5bf..eeca064189 100644
--- a/BUILD
+++ b/BUILD
@@ -537,11 +537,13 @@ grpc_cc_library(
     "include/grpc/grpc_security.h",
     "include/grpc/census.h",
   ],
+  external_deps = [
+    "libssl",
+    "zlib",
+    "nanopb",
+  ],
   deps = [
-    "//external:libssl",
-    "//external:zlib",
     ":gpr",
-    "//external:nanopb",
   ],
   language = "C",
 )
@@ -690,9 +692,11 @@ grpc_cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
   ],
+  external_deps = [
+    "libssl",
+    "protobuf_clib",
+  ],
   deps = [
-    "//external:libssl",
-    "//external:protobuf_clib",
     ":grpc",
   ],
 )
diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index c18c57f087..8ae362624c 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -1,32 +1,21 @@
-def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, language = "C++"):
+#
+# This is for the gRPC build system. This isn't intended to be used outsite of
+# the BUILD file for gRPC. It contains the mapping for the template system we
+# use to generate other platform's build system files.
+#
+
+def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps = [], deps = [], standalone = False, language = "C++"):
   copts = []
   if language == "C":
     copts = ["-std=c99"]
   native.cc_library(
     name = name,
     srcs = srcs,
-    hdrs = hdrs,
-    deps = deps,
+    hdrs = hdrs + public_hdrs,
+    deps = deps + ["//external:" + dep for dep in external_deps],
     copts = copts,
     linkopts = ["-pthread"],
     includes = [
         "include"
     ]
   )
-
-
-def nanopb():
-  native.cc_library(
-    name = "nanopb",
-    srcs = [
-      '//third_party/nanopb/pb_common.c',
-      '//third_party/nanopb/pb_decode.c',
-      '//third_party/nanopb/pb_encode.c',
-    ],
-    hdrs = [
-      '//third_party/nanopb/pb.h',
-      '//third_party/nanopb/pb_common.h',
-      '//third_party/nanopb/pb_decode.h',
-      '//third_party/nanopb/pb_encode.h',
-    ]
-  )
-- 
GitLab


From ed5215dc87067b741167b0a4f29c6feeafd5857c Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 10:49:13 -0700
Subject: [PATCH 005/344] fix merge

---
 grpc-build-system.bzl | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index 393aa42ca0..0ef3a0ea07 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -28,8 +28,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, language = "C++"):
-=======
 #
 # This is for the gRPC build system. This isn't intended to be used outsite of
 # the BUILD file for gRPC. It contains the mapping for the template system we
@@ -37,7 +35,6 @@ def grpc_cc_library(name, srcs = [], hdrs = [], deps = [], standalone = False, l
 #
 
 def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps = [], deps = [], standalone = False, language = "C++"):
->>>>>>> e8dbd8aaae5d813546abe4956361c4e6512d8c88
   copts = []
   if language == "C":
     copts = ["-std=c99"]
-- 
GitLab


From 857c29f7b334125178a4e3003f943c27237663e0 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 10:49:53 -0700
Subject: [PATCH 006/344] fix merge

---
 grpc-build-system.bzl | 1 -
 1 file changed, 1 deletion(-)

diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index 0ef3a0ea07..187cc3e424 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -1,4 +1,3 @@
-<<<<<<< HEAD
 # Copyright 2016, Google Inc.
 # All rights reserved.
 #
-- 
GitLab


From ad57f1678e51eae42b2ae2679063b8ba0982038f Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 11:32:28 -0700
Subject: [PATCH 007/344] Begin fuzzing framework

---
 test/core/support/BUILD        |  9 ++++++++
 test/core/util/BUILD           | 13 ++++++++---
 test/core/util/grpc_fuzzer.bzl | 42 ++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 test/core/util/grpc_fuzzer.bzl

diff --git a/test/core/support/BUILD b/test/core/support/BUILD
index eee086d85e..499bd0940f 100644
--- a/test/core/support/BUILD
+++ b/test/core/support/BUILD
@@ -27,6 +27,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.
 
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
 cc_test(
     name = "alloc_test",
     srcs = ["alloc_test.c"],
@@ -152,3 +154,10 @@ cc_test(
     srcs = ["useful_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
 )
+
+grpc_fuzzer(
+  name = "percent_encode_fuzzer",
+  srcs = ["percent_encode_fuzzer.c"],
+  deps = ["//:gpr"],
+  corpus = "percent_encode_corpus"
+)
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index 79e6cfbeeb..82207913ef 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -4,9 +4,11 @@ cc_library(
     name = "gpr_test_util",
     srcs = [
         "test_config.c",
+        "memory_counters.c",
     ],
     hdrs = [
         "test_config.h",
+        "memory_counters.h",
     ],
     deps = ["//:gpr"],
     visibility = ["//:__subpackages__"],
@@ -16,7 +18,6 @@ cc_library(
     name = "grpc_test_util",
     srcs = [
         "grpc_profiler.c",
-        "memory_counters.c",
         "mock_endpoint.c",
         "parse_hexstring.c",
         "passthru_endpoint.c",
@@ -29,7 +30,6 @@ cc_library(
     ],
     hdrs = [
         "grpc_profiler.h",
-        "memory_counters.h",
         "mock_endpoint.h",
         "parse_hexstring.h",
         "passthru_endpoint.h",
@@ -40,5 +40,12 @@ cc_library(
         "test_tcp_server.h",
     ],
     deps = [":gpr_test_util", "//:grpc"],
-    visibility = ["//:__subpackages__"],
+    visibility = ["//test:__subpackages__"],
+)
+
+cc_library(
+  name = "one_corpus_entry_fuzzer",
+  srcs = ["one_corpus_entry_fuzzer.c"],
+  deps = [":gpr_test_util", "//:grpc"],
+  visibility = ["//test:__subpackages__"],
 )
diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl
new file mode 100644
index 0000000000..1db3aa4234
--- /dev/null
+++ b/test/core/util/grpc_fuzzer.bzl
@@ -0,0 +1,42 @@
+# Copyright 2016, 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.
+
+def grpc_fuzzer(name, corpus, srcs = [], deps = []):
+  native.cc_library(
+    name = "%s/one_entry" % name,
+    srcs = srcs,
+    deps = deps + ["//test/core/util:one_corpus_entry_fuzzer"],
+  )
+  for entry in native.glob(['%s/*' % corpus]):
+    native.cc_test(
+      name = '%s/one_entry/%s' % (name, entry),
+      deps = [':%s/one_entry' % name],
+      args = [entry],
+      data = [entry]
+    )
-- 
GitLab


From 31a1bbd4bc7dc2097ddff45bf661b287b092aab2 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 11:45:59 -0700
Subject: [PATCH 008/344] Make fuzzer unit tests work

---
 test/core/support/BUILD        | 21 +++++++++++++++++++++
 test/core/util/grpc_fuzzer.bzl |  2 +-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/test/core/support/BUILD b/test/core/support/BUILD
index 499bd0940f..375cf25cb7 100644
--- a/test/core/support/BUILD
+++ b/test/core/support/BUILD
@@ -33,126 +33,147 @@ cc_test(
     name = "alloc_test",
     srcs = ["alloc_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "avl_test",
     srcs = ["avl_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "backoff_test",
     srcs = ["backoff_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "cmdline_test",
     srcs = ["cmdline_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "cpu_test",
     srcs = ["cpu_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "env_test",
     srcs = ["env_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "histogram_test",
     srcs = ["histogram_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "host_port_test",
     srcs = ["host_port_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "log_test",
     srcs = ["log_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "mpscq_test",
     srcs = ["mpscq_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "murmur_hash_test",
     srcs = ["murmur_hash_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "percent_encoding_test",
     srcs = ["percent_encoding_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "slice_buffer_test",
     srcs = ["slice_buffer_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "slice_test",
     srcs = ["slice_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "stack_lockfree_test",
     srcs = ["stack_lockfree_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "string_test",
     srcs = ["string_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "sync_test",
     srcs = ["sync_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "thd_test",
     srcs = ["thd_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "time_test",
     srcs = ["time_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "tls_test",
     srcs = ["tls_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 cc_test(
     name = "useful_test",
     srcs = ["useful_test.c"],
     deps = ["//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
 )
 
 grpc_fuzzer(
diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl
index 1db3aa4234..d9a227641c 100644
--- a/test/core/util/grpc_fuzzer.bzl
+++ b/test/core/util/grpc_fuzzer.bzl
@@ -37,6 +37,6 @@ def grpc_fuzzer(name, corpus, srcs = [], deps = []):
     native.cc_test(
       name = '%s/one_entry/%s' % (name, entry),
       deps = [':%s/one_entry' % name],
-      args = [entry],
+      args = ['$(location %s)' % entry],
       data = [entry]
     )
-- 
GitLab


From d3e645f07d2c939c1dc7aa1bfda70d592d8491ca Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 12:15:27 -0700
Subject: [PATCH 009/344] e2e fuzzers

---
 test/core/support/BUILD        | 9 +++++++++
 test/core/util/BUILD           | 1 +
 test/core/util/grpc_fuzzer.bzl | 5 +++--
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/test/core/support/BUILD b/test/core/support/BUILD
index 375cf25cb7..ac33176f00 100644
--- a/test/core/support/BUILD
+++ b/test/core/support/BUILD
@@ -182,3 +182,12 @@ grpc_fuzzer(
   deps = ["//:gpr"],
   corpus = "percent_encode_corpus"
 )
+
+
+grpc_fuzzer(
+    name = "percent_decode_fuzzer",
+    srcs = ["percent_decode_fuzzer.c"],
+    deps = ["//:gpr"],
+    corpus = "percent_decode_corpus"
+)
+
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index 82207913ef..e44e4e2105 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -41,6 +41,7 @@ cc_library(
     ],
     deps = [":gpr_test_util", "//:grpc"],
     visibility = ["//test:__subpackages__"],
+    copts = ["-std=c99"],
 )
 
 cc_library(
diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl
index d9a227641c..3ec9e4e485 100644
--- a/test/core/util/grpc_fuzzer.bzl
+++ b/test/core/util/grpc_fuzzer.bzl
@@ -27,16 +27,17 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-def grpc_fuzzer(name, corpus, srcs = [], deps = []):
+def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs):
   native.cc_library(
     name = "%s/one_entry" % name,
     srcs = srcs,
     deps = deps + ["//test/core/util:one_corpus_entry_fuzzer"],
+    **kwargs
   )
   for entry in native.glob(['%s/*' % corpus]):
     native.cc_test(
       name = '%s/one_entry/%s' % (name, entry),
       deps = [':%s/one_entry' % name],
       args = ['$(location %s)' % entry],
-      data = [entry]
+      data = [entry],
     )
-- 
GitLab


From f4f2eac66d6fbec4822ca0b08edf0cf96fa4f1f1 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 12:26:53 -0700
Subject: [PATCH 010/344] All fuzzers

---
 test/core/client_config/BUILD    | 39 ++++++++++++++++++++++
 test/core/end2end/fuzzers/BUILD  | 55 ++++++++++++++++++++++++++++++++
 test/core/http/BUILD             | 47 +++++++++++++++++++++++++++
 test/core/json/BUILD             | 39 ++++++++++++++++++++++
 test/core/nanopb/BUILD           | 47 +++++++++++++++++++++++++++
 test/core/transport/chttp2/BUILD | 38 ++++++++++++++++++++++
 6 files changed, 265 insertions(+)
 create mode 100644 test/core/client_config/BUILD
 create mode 100644 test/core/end2end/fuzzers/BUILD
 create mode 100644 test/core/http/BUILD
 create mode 100644 test/core/json/BUILD
 create mode 100644 test/core/nanopb/BUILD
 create mode 100644 test/core/transport/chttp2/BUILD

diff --git a/test/core/client_config/BUILD b/test/core/client_config/BUILD
new file mode 100644
index 0000000000..856206d8ff
--- /dev/null
+++ b/test/core/client_config/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "uri_fuzzer",
+  srcs = ["uri_fuzzer_test.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "uri_corpus",
+  copts = ["-std=c99"],
+)
+
diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD
new file mode 100644
index 0000000000..d08603148e
--- /dev/null
+++ b/test/core/end2end/fuzzers/BUILD
@@ -0,0 +1,55 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "api_fuzzer",
+  srcs = ["api_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "api_fuzzer_corpus",
+  copts = ["-std=c99"],
+)
+
+grpc_fuzzer(
+  name = "client_fuzzer",
+  srcs = ["client_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "client_fuzzer_corpus",
+  copts = ["-std=c99"],
+)
+
+grpc_fuzzer(
+  name = "server_fuzzer",
+  srcs = ["server_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "server_fuzzer_corpus",
+  copts = ["-std=c99"],
+)
+
diff --git a/test/core/http/BUILD b/test/core/http/BUILD
new file mode 100644
index 0000000000..58d265bd8f
--- /dev/null
+++ b/test/core/http/BUILD
@@ -0,0 +1,47 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "response_fuzzer",
+  srcs = ["response_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "response_corpus",
+  copts = ["-std=c99"],
+)
+
+grpc_fuzzer(
+  name = "request_fuzzer",
+  srcs = ["request_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "request_corpus",
+  copts = ["-std=c99"],
+)
+
diff --git a/test/core/json/BUILD b/test/core/json/BUILD
new file mode 100644
index 0000000000..4b3fbd6076
--- /dev/null
+++ b/test/core/json/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "json_fuzzer",
+  srcs = ["fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "corpus",
+  copts = ["-std=c99"],
+)
+
diff --git a/test/core/nanopb/BUILD b/test/core/nanopb/BUILD
new file mode 100644
index 0000000000..bdf79b7fef
--- /dev/null
+++ b/test/core/nanopb/BUILD
@@ -0,0 +1,47 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "fuzzer_response",
+  srcs = ["fuzzer_response.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "corpus_response",
+  copts = ["-std=c99"],
+)
+
+grpc_fuzzer(
+  name = "fuzzer_serverlist",
+  srcs = ["fuzzer_serverlist.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "corpus_serverlist",
+  copts = ["-std=c99"],
+)
+
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
new file mode 100644
index 0000000000..5dd205174f
--- /dev/null
+++ b/test/core/transport/chttp2/BUILD
@@ -0,0 +1,38 @@
+# Copyright 2016, 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.
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "hpack_parser_fuzzer",
+  srcs = ["hpack_parser_fuzzer_test.c"],
+  deps = ["//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "hpack_parser_corpus"
+)
+
-- 
GitLab


From fab4ab4e3a9f34bbed9333762c241e3dda708ebd Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 12:36:42 -0700
Subject: [PATCH 011/344] Bad client tests converted

---
 test/core/bad_client/BUILD              | 32 ++++++++
 test/core/bad_client/gen_build_yaml.py  | 99 -------------------------
 test/core/bad_client/generate_tests.bzl | 68 +++++++++++++++++
 test/core/end2end/BUILD                 |  3 +-
 4 files changed, 102 insertions(+), 100 deletions(-)
 create mode 100644 test/core/bad_client/BUILD
 delete mode 100755 test/core/bad_client/gen_build_yaml.py
 create mode 100755 test/core/bad_client/generate_tests.bzl

diff --git a/test/core/bad_client/BUILD b/test/core/bad_client/BUILD
new file mode 100644
index 0000000000..5406eb9a4b
--- /dev/null
+++ b/test/core/bad_client/BUILD
@@ -0,0 +1,32 @@
+# Copyright 2016, 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.
+
+load(":generate_tests.bzl", "grpc_bad_client_tests")
+
+grpc_bad_client_tests()
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py
deleted file mode 100755
index fb86525b1a..0000000000
--- a/test/core/bad_client/gen_build_yaml.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python2.7
-# 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.
-
-
-"""Generates the appropriate build.json data for all the bad_client tests."""
-
-
-import collections
-import yaml
-
-TestOptions = collections.namedtuple('TestOptions', 'flaky cpu_cost')
-default_test_options = TestOptions(False, 1.0)
-
-# maps test names to options
-BAD_CLIENT_TESTS = {
-    'badreq': default_test_options,
-    'connection_prefix': default_test_options._replace(cpu_cost=0.2),
-    'headers': default_test_options._replace(cpu_cost=0.2),
-    'initial_settings_frame': default_test_options._replace(cpu_cost=0.2),
-    'head_of_line_blocking': default_test_options,
-    'large_metadata': default_test_options,
-    'server_registered_method': default_test_options,
-    'simple_request': default_test_options,
-    'window_overflow': default_test_options,
-    'unknown_frame': default_test_options,
-}
-
-def main():
-  json = {
-      '#': 'generated with test/bad_client/gen_build_json.py',
-      'libs': [
-          {
-            'name': 'bad_client_test',
-            'build': 'private',
-            'language': 'c',
-            'src': [
-              'test/core/bad_client/bad_client.c'
-            ],
-            'headers': [
-              'test/core/bad_client/bad_client.h'
-            ],
-            'vs_proj_dir': 'test/bad_client',
-            'deps': [
-              'grpc_test_util_unsecure',
-              'grpc_unsecure',
-              'gpr_test_util',
-              'gpr'
-            ]
-          }],
-      'targets': [
-          {
-              'name': '%s_bad_client_test' % t,
-              'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost,
-              'build': 'test',
-              'language': 'c',
-              'secure': 'no',
-              'src': ['test/core/bad_client/tests/%s.c' % t],
-              'vs_proj_dir': 'test',
-              'deps': [
-                  'bad_client_test',
-                  'grpc_test_util_unsecure',
-                  'grpc_unsecure',
-                  'gpr_test_util',
-                  'gpr'
-              ]
-          }
-      for t in sorted(BAD_CLIENT_TESTS.keys())]}
-  print yaml.dump(json)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl
new file mode 100755
index 0000000000..694ddeeab6
--- /dev/null
+++ b/test/core/bad_client/generate_tests.bzl
@@ -0,0 +1,68 @@
+#!/usr/bin/env python2.7
+# 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.
+
+
+"""Generates the appropriate build.json data for all the bad_client tests."""
+
+
+def test_options():
+  return struct()
+
+
+# maps test names to options
+BAD_CLIENT_TESTS = {
+    'badreq': test_options(),
+    'connection_prefix': test_options(),
+    'headers': test_options(),
+    'initial_settings_frame': test_options(),
+    'head_of_line_blocking': test_options(),
+    'large_metadata': test_options(),
+    'server_registered_method': test_options(),
+    'simple_request': test_options(),
+    'window_overflow': test_options(),
+    'unknown_frame': test_options(),
+}
+
+def grpc_bad_client_tests():
+  native.cc_library(
+      name = 'bad_client_test',
+      srcs = ['bad_client.c'],
+      hdrs = ['bad_client.h'],
+      copts = ['-std=c99'],
+      deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier']
+  )
+  for t, topt in BAD_CLIENT_TESTS.items():
+    native.cc_test(
+        name = '%s_bad_client_test' % t,
+        srcs = ['tests/%s.c' % t],
+        deps = [':bad_client_test'],
+        copts = ['-std=c99'],
+    )
+
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index a0b10709ce..f32bd2251a 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -33,7 +33,8 @@ cc_library(
   name = 'cq_verifier',
   srcs = ['cq_verifier.c'],
   hdrs = ['cq_verifier.h'],
-  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+  deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'],
+  visibility = ["//test:__subpackages__"],
 )
 
 cc_library(
-- 
GitLab


From 7e7fd9603cce01f455674c0576166b4d1c9ebdd2 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 22:00:08 +0200
Subject: [PATCH 012/344] Split the BUILD file into sub-libraries, and made the
 end2end tests use ssl certs.

---
 BUILD                                         | 1056 ++++++++++++-----
 .../client_config}/message_size_filter.c      |    0
 .../client_config}/message_size_filter.h      |    0
 test/core/end2end/BUILD                       |    6 +
 4 files changed, 750 insertions(+), 312 deletions(-)
 rename src/core/{lib/channel => ext/client_config}/message_size_filter.c (100%)
 rename src/core/{lib/channel => ext/client_config}/message_size_filter.h (100%)

diff --git a/BUILD b/BUILD
index eeca064189..b1bbbffb4b 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,4 @@
-# GRPC Bazel BUILD file.
+# gRPC Bazel BUILD file.
 #
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -42,20 +42,223 @@ version = "1.1.0-dev"
 
 grpc_cc_library(
   name = "gpr",
+  deps = [
+    "gpr_base",
+  ],
+  language = "c",
+  standalone = True,
+)
+
+grpc_cc_library(
+  name = "grpc",
+  srcs = [
+    "src/core/lib/surface/init.c",
+    "src/core/plugin_registry/grpc_plugin_registry.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_chttp2_server_secure",
+    "grpc_transport_chttp2_client_secure",
+    "grpc_transport_chttp2_server_insecure",
+    "grpc_transport_chttp2_client_insecure",
+    "grpc_lb_policy_grpclb",
+    "grpc_lb_policy_pick_first",
+    "grpc_lb_policy_round_robin",
+    "grpc_resolver_dns_native",
+    "grpc_resolver_sockaddr",
+    "grpc_load_reporting",
+    "grpc_secure",
+    "census",
+  ],
+  language = "c",
+  standalone = True,
+)
+
+grpc_cc_library(
+  name = "grpc_cronet",
+  srcs = [
+    "src/core/lib/surface/init.c",
+    "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_cronet_client_secure",
+    "grpc_transport_chttp2_client_secure",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_unsecure",
+  srcs = [
+    "src/core/lib/surface/init.c",
+    "src/core/lib/surface/init_unsecure.c",
+    "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_chttp2_server_insecure",
+    "grpc_transport_chttp2_client_insecure",
+    "grpc_resolver_dns_native",
+    "grpc_resolver_sockaddr",
+    "grpc_load_reporting",
+    "grpc_lb_policy_grpclb",
+    "grpc_lb_policy_pick_first",
+    "grpc_lb_policy_round_robin",
+    "census",
+  ],
+  language = "c",
+  standalone = True,
+)
+
+grpc_cc_library(
+  name = "grpc++",
+  srcs = [
+    "src/cpp/client/insecure_credentials.cc",
+    "src/cpp/client/secure_credentials.cc",
+    "src/cpp/common/auth_property_iterator.cc",
+    "src/cpp/common/secure_auth_context.cc",
+    "src/cpp/common/secure_channel_arguments.cc",
+    "src/cpp/common/secure_create_auth_context.cc",
+    "src/cpp/server/insecure_server_credentials.cc",
+    "src/cpp/server/secure_server_credentials.cc",
+  ],
+  hdrs = [
+    "include/grpc++/impl/codegen/core_codegen.h",
+    "src/cpp/client/secure_credentials.h",
+    "src/cpp/common/secure_auth_context.h",
+    "src/cpp/server/secure_server_credentials.h",
+  ],
+  deps = [
+    "gpr",
+    "grpc",
+    "grpc++_base",
+    "grpc++_codegen_base",
+    "grpc++_codegen_base_src",
+  ],
+  language = "c++",
+  standalone = True,
+)
+
+grpc_cc_library(
+  name = "grpc++_unsecure",
+  srcs = [
+    "src/cpp/client/insecure_credentials.cc",
+    "src/cpp/common/insecure_create_auth_context.cc",
+    "src/cpp/server/insecure_server_credentials.cc",
+  ],
+  hdrs = [
+  ],
+  public_hdrs = [
+  ],
+  deps = [
+    "gpr",
+    "grpc_unsecure",
+    "grpc++_base",
+    "grpc++_codegen_base",
+    "grpc++_codegen_base_src",
+  ],
+  language = "c++",
+  standalone = True,
+)
+
+grpc_cc_library(
+  name = "grpc_plugin_support",
+  srcs = [
+    "src/compiler/cpp_generator.cc",
+    "src/compiler/csharp_generator.cc",
+    "src/compiler/node_generator.cc",
+    "src/compiler/objective_c_generator.cc",
+    "src/compiler/php_generator.cc",
+    "src/compiler/python_generator.cc",
+    "src/compiler/ruby_generator.cc",
+  ],
+  hdrs = [
+    "src/compiler/config.h",
+    "src/compiler/cpp_generator.h",
+    "src/compiler/cpp_generator_helpers.h",
+    "src/compiler/csharp_generator.h",
+    "src/compiler/csharp_generator_helpers.h",
+    "src/compiler/generator_helpers.h",
+    "src/compiler/node_generator.h",
+    "src/compiler/node_generator_helpers.h",
+    "src/compiler/objective_c_generator.h",
+    "src/compiler/objective_c_generator_helpers.h",
+    "src/compiler/php_generator.h",
+    "src/compiler/php_generator_helpers.h",
+    "src/compiler/python_generator.h",
+    "src/compiler/ruby_generator.h",
+    "src/compiler/ruby_generator_helpers-inl.h",
+    "src/compiler/ruby_generator_map-inl.h",
+    "src/compiler/ruby_generator_string-inl.h",
+  ],
+  external_deps = [
+    "protobuf_compiler",
+  ],
+  deps = [
+    "grpc++_config_proto",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "grpc_csharp_ext",
+  srcs = [
+    "src/csharp/ext/grpc_csharp_ext.c",
+  ],
+  deps = [
+    "grpc",
+    "gpr",
+  ],
+  language = "csharp",
+)
+
+grpc_cc_library(
+  name = "census",
+  srcs = [
+    "src/core/ext/census/base_resources.c",
+    "src/core/ext/census/context.c",
+    "src/core/ext/census/gen/census.pb.c",
+    "src/core/ext/census/gen/trace_context.pb.c",
+    "src/core/ext/census/grpc_context.c",
+    "src/core/ext/census/grpc_filter.c",
+    "src/core/ext/census/grpc_plugin.c",
+    "src/core/ext/census/initialize.c",
+    "src/core/ext/census/mlog.c",
+    "src/core/ext/census/operation.c",
+    "src/core/ext/census/placeholders.c",
+    "src/core/ext/census/resource.c",
+    "src/core/ext/census/trace_context.c",
+    "src/core/ext/census/tracing.c",
+  ],
+  hdrs = [
+    "src/core/ext/census/aggregation.h",
+    "src/core/ext/census/base_resources.h",
+    "src/core/ext/census/census_interface.h",
+    "src/core/ext/census/census_rpc_stats.h",
+    "src/core/ext/census/gen/census.pb.h",
+    "src/core/ext/census/gen/trace_context.pb.h",
+    "src/core/ext/census/grpc_filter.h",
+    "src/core/ext/census/mlog.h",
+    "src/core/ext/census/resource.h",
+    "src/core/ext/census/rpc_metric_id.h",
+    "src/core/ext/census/trace_context.h",
+  ],
+  public_hdrs = [
+    "include/grpc/census.h",
+  ],
+  external_deps = [
+    "nanopb",
+  ],
+  deps = [
+    "grpc_base",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "gpr_base",
   srcs = [
-    "src/core/lib/profiling/timers.h",
-    "src/core/lib/support/backoff.h",
-    "src/core/lib/support/block_annotate.h",
-    "src/core/lib/support/env.h",
-    "src/core/lib/support/mpscq.h",
-    "src/core/lib/support/murmur_hash.h",
-    "src/core/lib/support/percent_encoding.h",
-    "src/core/lib/support/stack_lockfree.h",
-    "src/core/lib/support/string.h",
-    "src/core/lib/support/string_windows.h",
-    "src/core/lib/support/thd_internal.h",
-    "src/core/lib/support/time_precise.h",
-    "src/core/lib/support/tmpfile.h",
     "src/core/lib/profiling/basic_timers.c",
     "src/core/lib/profiling/stap_timers.c",
     "src/core/lib/support/alloc.c",
@@ -105,6 +308,21 @@ grpc_cc_library(
     "src/core/lib/support/wrap_memcpy.c",
   ],
   hdrs = [
+    "src/core/lib/profiling/timers.h",
+    "src/core/lib/support/backoff.h",
+    "src/core/lib/support/block_annotate.h",
+    "src/core/lib/support/env.h",
+    "src/core/lib/support/mpscq.h",
+    "src/core/lib/support/murmur_hash.h",
+    "src/core/lib/support/percent_encoding.h",
+    "src/core/lib/support/stack_lockfree.h",
+    "src/core/lib/support/string.h",
+    "src/core/lib/support/string_windows.h",
+    "src/core/lib/support/thd_internal.h",
+    "src/core/lib/support/time_precise.h",
+    "src/core/lib/support/tmpfile.h",
+  ],
+  public_hdrs = [
     "include/grpc/support/alloc.h",
     "include/grpc/support/atm.h",
     "include/grpc/support/atm_gcc_atomic.h",
@@ -133,6 +351,16 @@ grpc_cc_library(
     "include/grpc/support/tls_msvc.h",
     "include/grpc/support/tls_pthread.h",
     "include/grpc/support/useful.h",
+  ],
+  deps = [
+    "gpr_codegen",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "gpr_codegen",
+  public_hdrs = [
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
@@ -145,13 +373,106 @@ grpc_cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
   ],
+  language = "c",
 )
 
-
-
 grpc_cc_library(
-  name = "grpc",
+  name = "grpc_base",
   srcs = [
+    "src/core/lib/channel/channel_args.c",
+    "src/core/lib/channel/channel_stack.c",
+    "src/core/lib/channel/channel_stack_builder.c",
+    "src/core/lib/channel/compress_filter.c",
+    "src/core/lib/channel/connected_channel.c",
+    "src/core/lib/channel/deadline_filter.c",
+    "src/core/lib/channel/handshaker.c",
+    "src/core/lib/channel/http_client_filter.c",
+    "src/core/lib/channel/http_server_filter.c",
+    "src/core/lib/compression/compression.c",
+    "src/core/lib/compression/message_compress.c",
+    "src/core/lib/debug/trace.c",
+    "src/core/lib/http/format_request.c",
+    "src/core/lib/http/httpcli.c",
+    "src/core/lib/http/parser.c",
+    "src/core/lib/iomgr/closure.c",
+    "src/core/lib/iomgr/combiner.c",
+    "src/core/lib/iomgr/endpoint.c",
+    "src/core/lib/iomgr/endpoint_pair_posix.c",
+    "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/error.c",
+    "src/core/lib/iomgr/ev_epoll_linux.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
+    "src/core/lib/iomgr/ev_poll_posix.c",
+    "src/core/lib/iomgr/ev_posix.c",
+    "src/core/lib/iomgr/exec_ctx.c",
+    "src/core/lib/iomgr/executor.c",
+    "src/core/lib/iomgr/iocp_windows.c",
+    "src/core/lib/iomgr/iomgr.c",
+    "src/core/lib/iomgr/iomgr_posix.c",
+    "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/load_file.c",
+    "src/core/lib/iomgr/network_status_tracker.c",
+    "src/core/lib/iomgr/polling_entity.c",
+    "src/core/lib/iomgr/pollset_set_windows.c",
+    "src/core/lib/iomgr/pollset_windows.c",
+    "src/core/lib/iomgr/resolve_address_posix.c",
+    "src/core/lib/iomgr/resolve_address_windows.c",
+    "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_utils_common_posix.c",
+    "src/core/lib/iomgr/socket_utils_linux.c",
+    "src/core/lib/iomgr/socket_utils_posix.c",
+    "src/core/lib/iomgr/socket_windows.c",
+    "src/core/lib/iomgr/tcp_client_posix.c",
+    "src/core/lib/iomgr/tcp_client_windows.c",
+    "src/core/lib/iomgr/tcp_posix.c",
+    "src/core/lib/iomgr/tcp_server_posix.c",
+    "src/core/lib/iomgr/tcp_server_windows.c",
+    "src/core/lib/iomgr/tcp_windows.c",
+    "src/core/lib/iomgr/time_averaged_stats.c",
+    "src/core/lib/iomgr/timer.c",
+    "src/core/lib/iomgr/timer_heap.c",
+    "src/core/lib/iomgr/udp_server.c",
+    "src/core/lib/iomgr/unix_sockets_posix.c",
+    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
+    "src/core/lib/iomgr/wakeup_fd_cv.c",
+    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
+    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
+    "src/core/lib/iomgr/wakeup_fd_pipe.c",
+    "src/core/lib/iomgr/wakeup_fd_posix.c",
+    "src/core/lib/iomgr/workqueue_windows.c",
+    "src/core/lib/json/json.c",
+    "src/core/lib/json/json_reader.c",
+    "src/core/lib/json/json_string.c",
+    "src/core/lib/json/json_writer.c",
+    "src/core/lib/surface/alarm.c",
+    "src/core/lib/surface/api_trace.c",
+    "src/core/lib/surface/byte_buffer.c",
+    "src/core/lib/surface/byte_buffer_reader.c",
+    "src/core/lib/surface/call.c",
+    "src/core/lib/surface/call_details.c",
+    "src/core/lib/surface/call_log_batch.c",
+    "src/core/lib/surface/channel.c",
+    "src/core/lib/surface/channel_init.c",
+    "src/core/lib/surface/channel_ping.c",
+    "src/core/lib/surface/channel_stack_type.c",
+    "src/core/lib/surface/completion_queue.c",
+    "src/core/lib/surface/event_string.c",
+    "src/core/lib/surface/lame_client.c",
+    "src/core/lib/surface/metadata_array.c",
+    "src/core/lib/surface/server.c",
+    "src/core/lib/surface/validate_metadata.c",
+    "src/core/lib/surface/version.c",
+    "src/core/lib/transport/byte_stream.c",
+    "src/core/lib/transport/connectivity_state.c",
+    "src/core/lib/transport/mdstr_hash_table.c",
+    "src/core/lib/transport/metadata.c",
+    "src/core/lib/transport/metadata_batch.c",
+    "src/core/lib/transport/static_metadata.c",
+    "src/core/lib/transport/timeout_encoding.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
+  ],
+  hdrs = [
     "src/core/lib/channel/channel_args.h",
     "src/core/lib/channel/channel_stack.h",
     "src/core/lib/channel/channel_stack_builder.h",
@@ -162,7 +483,6 @@ grpc_cc_library(
     "src/core/lib/channel/handshaker.h",
     "src/core/lib/channel/http_client_filter.h",
     "src/core/lib/channel/http_server_filter.h",
-    "src/core/lib/channel/message_size_filter.h",
     "src/core/lib/compression/algorithm_metadata.h",
     "src/core/lib/compression/message_compress.h",
     "src/core/lib/debug/trace.h",
@@ -236,51 +556,52 @@ grpc_cc_library(
     "src/core/lib/transport/timeout_encoding.h",
     "src/core/lib/transport/transport.h",
     "src/core/lib/transport/transport_impl.h",
-    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
-    "src/core/ext/transport/chttp2/transport/frame.h",
-    "src/core/ext/transport/chttp2/transport/frame_data.h",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
-    "src/core/ext/transport/chttp2/transport/frame_ping.h",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
-    "src/core/ext/transport/chttp2/transport/frame_settings.h",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
-    "src/core/ext/transport/chttp2/transport/hpack_table.h",
-    "src/core/ext/transport/chttp2/transport/http2_errors.h",
-    "src/core/ext/transport/chttp2/transport/huffsyms.h",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
-    "src/core/ext/transport/chttp2/transport/internal.h",
-    "src/core/ext/transport/chttp2/transport/status_conversion.h",
-    "src/core/ext/transport/chttp2/transport/stream_map.h",
-    "src/core/ext/transport/chttp2/transport/varint.h",
-    "src/core/ext/transport/chttp2/alpn/alpn.h",
-    "src/core/lib/security/context/security_context.h",
-    "src/core/lib/security/credentials/composite/composite_credentials.h",
-    "src/core/lib/security/credentials/credentials.h",
-    "src/core/lib/security/credentials/fake/fake_credentials.h",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
-    "src/core/lib/security/credentials/iam/iam_credentials.h",
-    "src/core/lib/security/credentials/jwt/json_token.h",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
-    "src/core/lib/security/transport/auth_filters.h",
-    "src/core/lib/security/transport/handshake.h",
-    "src/core/lib/security/transport/secure_endpoint.h",
-    "src/core/lib/security/transport/security_connector.h",
-    "src/core/lib/security/transport/tsi_error.h",
-    "src/core/lib/security/util/b64.h",
-    "src/core/lib/security/util/json_util.h",
-    "src/core/lib/tsi/fake_transport_security.h",
-    "src/core/lib/tsi/ssl_transport_security.h",
-    "src/core/lib/tsi/ssl_types.h",
-    "src/core/lib/tsi/transport_security.h",
-    "src/core/lib/tsi/transport_security_interface.h",
+  ],
+  public_hdrs = [
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
+    "include/grpc/status.h",
+  ],
+  external_deps = [
+    "zlib",
+  ],
+  deps = [
+    "grpc_codegen",
+    "gpr_base",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_client_config",
+  srcs = [
+    "src/core/ext/client_config/channel_connectivity.c",
+    "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
+    "src/core/ext/client_config/client_config_plugin.c",
+    "src/core/ext/client_config/connector.c",
+    "src/core/ext/client_config/default_initial_connect_string.c",
+    "src/core/ext/client_config/http_connect_handshaker.c",
+    "src/core/ext/client_config/initial_connect_string.c",
+    "src/core/ext/client_config/lb_policy.c",
+    "src/core/ext/client_config/lb_policy_factory.c",
+    "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/message_size_filter.c",
+    "src/core/ext/client_config/method_config.c",
+    "src/core/ext/client_config/parse_address.c",
+    "src/core/ext/client_config/resolver.c",
+    "src/core/ext/client_config/resolver_factory.c",
+    "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/resolver_result.c",
+    "src/core/ext/client_config/subchannel.c",
+    "src/core/ext/client_config/subchannel_index.c",
+    "src/core/ext/client_config/uri_parser.c",
+  ],
+  hdrs = [
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel_factory.h",
     "src/core/ext/client_config/connector.h",
@@ -289,6 +610,7 @@ grpc_cc_library(
     "src/core/ext/client_config/lb_policy.h",
     "src/core/ext/client_config/lb_policy_factory.h",
     "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/message_size_filter.h",
     "src/core/ext/client_config/method_config.h",
     "src/core/ext/client_config/parse_address.h",
     "src/core/ext/client_config/resolver.h",
@@ -298,117 +620,179 @@ grpc_cc_library(
     "src/core/ext/client_config/subchannel.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
+  ],
+  deps = [
+    "grpc_base",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_codegen",
+  public_hdrs = [
+    "include/grpc/impl/codegen/byte_buffer_reader.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+  ],
+  deps = [
+    "gpr_codegen",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_lb_policy_grpclb",
+  srcs = [
+    "src/core/ext/lb_policy/grpclb/grpclb.c",
+    "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
+    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+  ],
+  hdrs = [
     "src/core/ext/lb_policy/grpclb/grpclb.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+  ],
+  external_deps = [
+    "nanopb",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_lb_policy_pick_first",
+  srcs = [
+    "src/core/ext/lb_policy/pick_first/pick_first.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_lb_policy_round_robin",
+  srcs = [
+    "src/core/ext/lb_policy/round_robin/round_robin.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_load_reporting",
+  srcs = [
+    "src/core/ext/load_reporting/load_reporting.c",
+    "src/core/ext/load_reporting/load_reporting_filter.c",
+  ],
+  hdrs = [
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting_filter.h",
-    "src/core/ext/census/aggregation.h",
-    "src/core/ext/census/base_resources.h",
-    "src/core/ext/census/census_interface.h",
-    "src/core/ext/census/census_rpc_stats.h",
-    "src/core/ext/census/gen/census.pb.h",
-    "src/core/ext/census/gen/trace_context.pb.h",
-    "src/core/ext/census/grpc_filter.h",
-    "src/core/ext/census/mlog.h",
-    "src/core/ext/census/resource.h",
-    "src/core/ext/census/rpc_metric_id.h",
-    "src/core/ext/census/trace_context.h",
-    "src/core/lib/surface/init.c",
-    "src/core/lib/channel/channel_args.c",
-    "src/core/lib/channel/channel_stack.c",
-    "src/core/lib/channel/channel_stack_builder.c",
-    "src/core/lib/channel/compress_filter.c",
-    "src/core/lib/channel/connected_channel.c",
-    "src/core/lib/channel/deadline_filter.c",
-    "src/core/lib/channel/handshaker.c",
-    "src/core/lib/channel/http_client_filter.c",
-    "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/channel/message_size_filter.c",
-    "src/core/lib/compression/compression.c",
-    "src/core/lib/compression/message_compress.c",
-    "src/core/lib/debug/trace.c",
-    "src/core/lib/http/format_request.c",
-    "src/core/lib/http/httpcli.c",
-    "src/core/lib/http/parser.c",
-    "src/core/lib/iomgr/closure.c",
-    "src/core/lib/iomgr/combiner.c",
-    "src/core/lib/iomgr/endpoint.c",
-    "src/core/lib/iomgr/endpoint_pair_posix.c",
-    "src/core/lib/iomgr/endpoint_pair_windows.c",
-    "src/core/lib/iomgr/error.c",
-    "src/core/lib/iomgr/ev_epoll_linux.c",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
-    "src/core/lib/iomgr/ev_poll_posix.c",
-    "src/core/lib/iomgr/ev_posix.c",
-    "src/core/lib/iomgr/exec_ctx.c",
-    "src/core/lib/iomgr/executor.c",
-    "src/core/lib/iomgr/iocp_windows.c",
-    "src/core/lib/iomgr/iomgr.c",
-    "src/core/lib/iomgr/iomgr_posix.c",
-    "src/core/lib/iomgr/iomgr_windows.c",
-    "src/core/lib/iomgr/load_file.c",
-    "src/core/lib/iomgr/network_status_tracker.c",
-    "src/core/lib/iomgr/polling_entity.c",
-    "src/core/lib/iomgr/pollset_set_windows.c",
-    "src/core/lib/iomgr/pollset_windows.c",
-    "src/core/lib/iomgr/resolve_address_posix.c",
-    "src/core/lib/iomgr/resolve_address_windows.c",
-    "src/core/lib/iomgr/sockaddr_utils.c",
-    "src/core/lib/iomgr/socket_utils_common_posix.c",
-    "src/core/lib/iomgr/socket_utils_linux.c",
-    "src/core/lib/iomgr/socket_utils_posix.c",
-    "src/core/lib/iomgr/socket_windows.c",
-    "src/core/lib/iomgr/tcp_client_posix.c",
-    "src/core/lib/iomgr/tcp_client_windows.c",
-    "src/core/lib/iomgr/tcp_posix.c",
-    "src/core/lib/iomgr/tcp_server_posix.c",
-    "src/core/lib/iomgr/tcp_server_windows.c",
-    "src/core/lib/iomgr/tcp_windows.c",
-    "src/core/lib/iomgr/time_averaged_stats.c",
-    "src/core/lib/iomgr/timer.c",
-    "src/core/lib/iomgr/timer_heap.c",
-    "src/core/lib/iomgr/udp_server.c",
-    "src/core/lib/iomgr/unix_sockets_posix.c",
-    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
-    "src/core/lib/iomgr/wakeup_fd_cv.c",
-    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
-    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
-    "src/core/lib/iomgr/wakeup_fd_pipe.c",
-    "src/core/lib/iomgr/wakeup_fd_posix.c",
-    "src/core/lib/iomgr/workqueue_windows.c",
-    "src/core/lib/json/json.c",
-    "src/core/lib/json/json_reader.c",
-    "src/core/lib/json/json_string.c",
-    "src/core/lib/json/json_writer.c",
-    "src/core/lib/surface/alarm.c",
-    "src/core/lib/surface/api_trace.c",
-    "src/core/lib/surface/byte_buffer.c",
-    "src/core/lib/surface/byte_buffer_reader.c",
-    "src/core/lib/surface/call.c",
-    "src/core/lib/surface/call_details.c",
-    "src/core/lib/surface/call_log_batch.c",
-    "src/core/lib/surface/channel.c",
-    "src/core/lib/surface/channel_init.c",
-    "src/core/lib/surface/channel_ping.c",
-    "src/core/lib/surface/channel_stack_type.c",
-    "src/core/lib/surface/completion_queue.c",
-    "src/core/lib/surface/event_string.c",
-    "src/core/lib/surface/lame_client.c",
-    "src/core/lib/surface/metadata_array.c",
-    "src/core/lib/surface/server.c",
-    "src/core/lib/surface/validate_metadata.c",
-    "src/core/lib/surface/version.c",
-    "src/core/lib/transport/byte_stream.c",
-    "src/core/lib/transport/connectivity_state.c",
-    "src/core/lib/transport/mdstr_hash_table.c",
-    "src/core/lib/transport/metadata.c",
-    "src/core/lib/transport/metadata_batch.c",
-    "src/core/lib/transport/static_metadata.c",
-    "src/core/lib/transport/timeout_encoding.c",
-    "src/core/lib/transport/transport.c",
-    "src/core/lib/transport/transport_op_string.c",
-    "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c",
+  ],
+  deps = [
+    "grpc_base",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_resolver_dns_native",
+  srcs = [
+    "src/core/ext/resolver/dns/native/dns_resolver.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_resolver_sockaddr",
+  srcs = [
+    "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_secure",
+  srcs = [
+    "src/core/lib/http/httpcli_security_connector.c",
+    "src/core/lib/security/context/security_context.c",
+    "src/core/lib/security/credentials/composite/composite_credentials.c",
+    "src/core/lib/security/credentials/credentials.c",
+    "src/core/lib/security/credentials/credentials_metadata.c",
+    "src/core/lib/security/credentials/fake/fake_credentials.c",
+    "src/core/lib/security/credentials/google_default/credentials_posix.c",
+    "src/core/lib/security/credentials/google_default/credentials_windows.c",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
+    "src/core/lib/security/credentials/iam/iam_credentials.c",
+    "src/core/lib/security/credentials/jwt/json_token.c",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
+    "src/core/lib/security/transport/client_auth_filter.c",
+    "src/core/lib/security/transport/handshake.c",
+    "src/core/lib/security/transport/secure_endpoint.c",
+    "src/core/lib/security/transport/security_connector.c",
+    "src/core/lib/security/transport/server_auth_filter.c",
+    "src/core/lib/security/transport/tsi_error.c",
+    "src/core/lib/security/util/b64.c",
+    "src/core/lib/security/util/json_util.c",
+    "src/core/lib/surface/init_secure.c",
+  ],
+  hdrs = [
+    "src/core/lib/security/context/security_context.h",
+    "src/core/lib/security/credentials/composite/composite_credentials.h",
+    "src/core/lib/security/credentials/credentials.h",
+    "src/core/lib/security/credentials/fake/fake_credentials.h",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
+    "src/core/lib/security/credentials/iam/iam_credentials.h",
+    "src/core/lib/security/credentials/jwt/json_token.h",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
+    "src/core/lib/security/transport/auth_filters.h",
+    "src/core/lib/security/transport/handshake.h",
+    "src/core/lib/security/transport/secure_endpoint.h",
+    "src/core/lib/security/transport/security_connector.h",
+    "src/core/lib/security/transport/tsi_error.h",
+    "src/core/lib/security/util/b64.h",
+    "src/core/lib/security/util/json_util.h",
+  ],
+  public_hdrs = [
+    "include/grpc/grpc_security.h",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_chttp2_alpn",
+    "tsi",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2",
+  srcs = [
     "src/core/ext/transport/chttp2/transport/bin_decoder.c",
     "src/core/ext/transport/chttp2/transport/bin_encoder.c",
     "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
@@ -430,144 +814,152 @@ grpc_cc_library(
     "src/core/ext/transport/chttp2/transport/stream_map.c",
     "src/core/ext/transport/chttp2/transport/varint.c",
     "src/core/ext/transport/chttp2/transport/writing.c",
+  ],
+  hdrs = [
+    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
+    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
+    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+    "src/core/ext/transport/chttp2/transport/frame.h",
+    "src/core/ext/transport/chttp2/transport/frame_data.h",
+    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
+    "src/core/ext/transport/chttp2/transport/frame_ping.h",
+    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
+    "src/core/ext/transport/chttp2/transport/frame_settings.h",
+    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
+    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
+    "src/core/ext/transport/chttp2/transport/hpack_table.h",
+    "src/core/ext/transport/chttp2/transport/http2_errors.h",
+    "src/core/ext/transport/chttp2/transport/huffsyms.h",
+    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+    "src/core/ext/transport/chttp2/transport/internal.h",
+    "src/core/ext/transport/chttp2/transport/status_conversion.h",
+    "src/core/ext/transport/chttp2/transport/stream_map.h",
+    "src/core/ext/transport/chttp2/transport/varint.h",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_chttp2_alpn",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2_alpn",
+  srcs = [
     "src/core/ext/transport/chttp2/alpn/alpn.c",
-    "src/core/lib/http/httpcli_security_connector.c",
-    "src/core/lib/security/context/security_context.c",
-    "src/core/lib/security/credentials/composite/composite_credentials.c",
-    "src/core/lib/security/credentials/credentials.c",
-    "src/core/lib/security/credentials/credentials_metadata.c",
-    "src/core/lib/security/credentials/fake/fake_credentials.c",
-    "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_windows.c",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
-    "src/core/lib/security/credentials/iam/iam_credentials.c",
-    "src/core/lib/security/credentials/jwt/json_token.c",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
-    "src/core/lib/security/transport/client_auth_filter.c",
-    "src/core/lib/security/transport/handshake.c",
-    "src/core/lib/security/transport/secure_endpoint.c",
-    "src/core/lib/security/transport/security_connector.c",
-    "src/core/lib/security/transport/server_auth_filter.c",
-    "src/core/lib/security/transport/tsi_error.c",
-    "src/core/lib/security/util/b64.c",
-    "src/core/lib/security/util/json_util.c",
-    "src/core/lib/surface/init_secure.c",
-    "src/core/lib/tsi/fake_transport_security.c",
-    "src/core/lib/tsi/ssl_transport_security.c",
-    "src/core/lib/tsi/transport_security.c",
+  ],
+  hdrs = [
+    "src/core/ext/transport/chttp2/alpn/alpn.h",
+  ],
+  deps = [
+    "gpr",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2_client_insecure",
+  srcs = [
+    "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
+  ],
+  deps = [
+    "grpc_transport_chttp2",
+    "grpc_base",
+    "grpc_client_config",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2_client_secure",
+  srcs = [
     "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
-    "src/core/ext/client_config/channel_connectivity.c",
-    "src/core/ext/client_config/client_channel.c",
-    "src/core/ext/client_config/client_channel_factory.c",
-    "src/core/ext/client_config/client_config_plugin.c",
-    "src/core/ext/client_config/connector.c",
-    "src/core/ext/client_config/default_initial_connect_string.c",
-    "src/core/ext/client_config/http_connect_handshaker.c",
-    "src/core/ext/client_config/initial_connect_string.c",
-    "src/core/ext/client_config/lb_policy.c",
-    "src/core/ext/client_config/lb_policy_factory.c",
-    "src/core/ext/client_config/lb_policy_registry.c",
-    "src/core/ext/client_config/method_config.c",
-    "src/core/ext/client_config/parse_address.c",
-    "src/core/ext/client_config/resolver.c",
-    "src/core/ext/client_config/resolver_factory.c",
-    "src/core/ext/client_config/resolver_registry.c",
-    "src/core/ext/client_config/resolver_result.c",
-    "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_index.c",
-    "src/core/ext/client_config/uri_parser.c",
+  ],
+  deps = [
+    "grpc_transport_chttp2",
+    "grpc_base",
+    "grpc_client_config",
+    "grpc_secure",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2_server_insecure",
+  srcs = [
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
-    "src/core/ext/lb_policy/grpclb/grpclb.c",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
-    "src/core/ext/lb_policy/pick_first/pick_first.c",
-    "src/core/ext/lb_policy/round_robin/round_robin.c",
-    "src/core/ext/resolver/dns/native/dns_resolver.c",
-    "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
-    "src/core/ext/load_reporting/load_reporting.c",
-    "src/core/ext/load_reporting/load_reporting_filter.c",
-    "src/core/ext/census/base_resources.c",
-    "src/core/ext/census/context.c",
-    "src/core/ext/census/gen/census.pb.c",
-    "src/core/ext/census/gen/trace_context.pb.c",
-    "src/core/ext/census/grpc_context.c",
-    "src/core/ext/census/grpc_filter.c",
-    "src/core/ext/census/grpc_plugin.c",
-    "src/core/ext/census/initialize.c",
-    "src/core/ext/census/mlog.c",
-    "src/core/ext/census/operation.c",
-    "src/core/ext/census/placeholders.c",
-    "src/core/ext/census/resource.c",
-    "src/core/ext/census/trace_context.c",
-    "src/core/ext/census/tracing.c",
-    "src/core/plugin_registry/grpc_plugin_registry.c",
+  ],
+  deps = [
+    "grpc_transport_chttp2",
+    "grpc_base",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_chttp2_server_secure",
+  srcs = [
+    "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c",
+  ],
+  deps = [
+    "grpc_transport_chttp2",
+    "grpc_base",
+    "grpc_secure",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "grpc_transport_cronet_client_secure",
+  srcs = [
+    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+    "src/core/ext/transport/cronet/transport/cronet_transport.c",
   ],
   hdrs = [
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/grpc_posix.h",
-    "include/grpc/grpc_security_constants.h",
-    "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
+    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
+  ],
+  public_hdrs = [
+    "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/census.h",
+    "include/grpc/grpc_security_constants.h",
+  ],
+  deps = [
+    "grpc_base",
+    "grpc_transport_chttp2",
+  ],
+  language = "c",
+)
+
+grpc_cc_library(
+  name = "tsi",
+  srcs = [
+    "src/core/lib/tsi/fake_transport_security.c",
+    "src/core/lib/tsi/ssl_transport_security.c",
+    "src/core/lib/tsi/transport_security.c",
+  ],
+  hdrs = [
+    "src/core/lib/tsi/fake_transport_security.h",
+    "src/core/lib/tsi/ssl_transport_security.h",
+    "src/core/lib/tsi/ssl_types.h",
+    "src/core/lib/tsi/transport_security.h",
+    "src/core/lib/tsi/transport_security_interface.h",
   ],
   external_deps = [
     "libssl",
-    "zlib",
-    "nanopb",
   ],
   deps = [
-    ":gpr",
+    "gpr",
   ],
-  language = "C",
+  language = "c",
 )
 
-
 grpc_cc_library(
-  name = "grpc++",
+  name = "grpc++_base",
   srcs = [
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "src/cpp/client/secure_credentials.h",
-    "src/cpp/common/secure_auth_context.h",
-    "src/cpp/server/secure_server_credentials.h",
-    "src/cpp/client/create_channel_internal.h",
-    "src/cpp/common/channel_filter.h",
-    "src/cpp/server/dynamic_thread_pool.h",
-    "src/cpp/server/thread_pool_interface.h",
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/client/secure_credentials.cc",
-    "src/cpp/common/auth_property_iterator.cc",
-    "src/cpp/common/secure_auth_context.cc",
-    "src/cpp/common/secure_channel_arguments.cc",
-    "src/cpp/common/secure_create_auth_context.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/server/secure_server_credentials.cc",
     "src/cpp/client/channel_cc.cc",
     "src/cpp/client/client_context.cc",
     "src/cpp/client/create_channel.cc",
@@ -593,9 +985,14 @@ grpc_cc_library(
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time_cc.cc",
-    "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
+    "src/cpp/client/create_channel_internal.h",
+    "src/cpp/common/channel_filter.h",
+    "src/cpp/server/dynamic_thread_pool.h",
+    "src/cpp/server/thread_pool_interface.h",
+  ],
+  public_hdrs = [
     "include/grpc++/alarm.h",
     "include/grpc++/channel.h",
     "include/grpc++/client_context.h",
@@ -643,6 +1040,17 @@ grpc_cc_library(
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/time.h",
+  ],
+  deps = [
+    "grpc",
+    "grpc++_codegen_base",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "grpc++_codegen_base",
+  public_hdrs = [
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -674,29 +1082,53 @@ grpc_cc_library(
     "include/grpc++/impl/codegen/sync_no_cxx11.h",
     "include/grpc++/impl/codegen/sync_stream.h",
     "include/grpc++/impl/codegen/time.h",
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
   ],
-  external_deps = [
-    "libssl",
-    "protobuf_clib",
+  deps = [
+    "grpc_codegen",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "grpc++_codegen_base_src",
+  srcs = [
+    "src/cpp/codegen/codegen_init.cc",
+  ],
+  deps = [
+    "grpc++_codegen_base",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "grpc++_codegen_proto",
+  public_hdrs = [
+    "include/grpc++/impl/codegen/proto_utils.h",
+  ],
+  deps = [
+    "grpc++_codegen_base",
+    "grpc++_config_proto",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "grpc++_config_proto",
+  public_hdrs = [
+    "include/grpc++/impl/codegen/config_protobuf.h",
+  ],
+  language = "c++",
+)
+
+grpc_cc_library(
+  name = "thrift_util",
+  public_hdrs = [
+    "include/grpc++/impl/codegen/thrift_serializer.h",
+    "include/grpc++/impl/codegen/thrift_utils.h",
   ],
   deps = [
-    ":grpc",
+    "grpc++_codegen_base",
   ],
+  language = "c++",
 )
+
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/ext/client_config/message_size_filter.c
similarity index 100%
rename from src/core/lib/channel/message_size_filter.c
rename to src/core/ext/client_config/message_size_filter.c
diff --git a/src/core/lib/channel/message_size_filter.h b/src/core/ext/client_config/message_size_filter.h
similarity index 100%
rename from src/core/lib/channel/message_size_filter.h
rename to src/core/ext/client_config/message_size_filter.h
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index a0b10709ce..3a04f97b0f 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -39,6 +39,12 @@ cc_library(
 cc_library(
   name = 'ssl_test_data',
   hdrs = ['data/ssl_test_data.h'],
+  srcs = [
+    "data/client_certs.c",
+    "data/server1_cert.c",
+    "data/server1_key.c",
+    "data/test_root_cert.c",
+  ]
 )
 
 cc_library(
-- 
GitLab


From 674c66cd3794396a54c73866f2223eb60c5c8b6b Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 13:08:52 -0700
Subject: [PATCH 013/344] Bad ssl tests converted

---
 grpc-build-system.bzl                |   2 +-
 test/core/bad_ssl/BUILD              |  32 ++++++++
 test/core/bad_ssl/gen_build_yaml.py  | 106 ---------------------------
 test/core/bad_ssl/generate_tests.bzl |  52 +++++++++++++
 test/core/end2end/BUILD              |   1 +
 5 files changed, 86 insertions(+), 107 deletions(-)
 create mode 100644 test/core/bad_ssl/BUILD
 delete mode 100755 test/core/bad_ssl/gen_build_yaml.py
 create mode 100755 test/core/bad_ssl/generate_tests.bzl

diff --git a/grpc-build-system.bzl b/grpc-build-system.bzl
index 187cc3e424..653d58ef7f 100644
--- a/grpc-build-system.bzl
+++ b/grpc-build-system.bzl
@@ -35,7 +35,7 @@
 
 def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps = [], deps = [], standalone = False, language = "C++"):
   copts = []
-  if language == "C":
+  if language.upper() == "C":
     copts = ["-std=c99"]
   native.cc_library(
     name = name,
diff --git a/test/core/bad_ssl/BUILD b/test/core/bad_ssl/BUILD
new file mode 100644
index 0000000000..630733dd4d
--- /dev/null
+++ b/test/core/bad_ssl/BUILD
@@ -0,0 +1,32 @@
+# Copyright 2016, 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.
+
+load(":generate_tests.bzl", "grpc_bad_ssl_tests")
+
+grpc_bad_ssl_tests()
diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py
deleted file mode 100755
index c17b17eb13..0000000000
--- a/test/core/bad_ssl/gen_build_yaml.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python2.7
-# 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.
-
-
-"""Generates the appropriate build.json data for all the end2end tests."""
-
-
-import collections
-import yaml
-
-TestOptions = collections.namedtuple('TestOptions', 'flaky cpu_cost')
-default_test_options = TestOptions(False, 1.0)
-
-# maps test names to options
-BAD_CLIENT_TESTS = {
-    'cert': default_test_options._replace(cpu_cost=0.1),
-    # Disabling this test because it does not link correctly as written
-    # 'alpn': default_test_options._replace(cpu_cost=0.1),
-}
-
-def main():
-  json = {
-      '#': 'generated with test/bad_ssl/gen_build_json.py',
-      'libs': [
-          {
-              'name': 'bad_ssl_test_server',
-              'build': 'private',
-              'language': 'c',
-              'src': ['test/core/bad_ssl/server_common.c'],
-              'headers': ['test/core/bad_ssl/server_common.h'],
-              'vs_proj_dir': 'test',
-              'platforms': ['linux', 'posix', 'mac'],
-              'deps': [
-                  'grpc_test_util',
-                  'grpc',
-                  'gpr_test_util',
-                  'gpr'
-              ]
-          }
-      ],
-      'targets': [
-          {
-              'name': 'bad_ssl_%s_server' % t,
-              'build': 'test',
-              'language': 'c',
-              'run': False,
-              'src': ['test/core/bad_ssl/servers/%s.c' % t],
-              'vs_proj_dir': 'test/bad_ssl',
-              'platforms': ['linux', 'posix', 'mac'],
-              'deps': [
-                  'bad_ssl_test_server',
-                  'grpc_test_util',
-                  'grpc',
-                  'gpr_test_util',
-                  'gpr'
-              ]
-          }
-      for t in sorted(BAD_CLIENT_TESTS.keys())] + [
-          {
-              'name': 'bad_ssl_%s_test' % t,
-              'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost,
-              'build': 'test',
-              'language': 'c',
-              'src': ['test/core/bad_ssl/bad_ssl_test.c'],
-              'vs_proj_dir': 'test',
-              'platforms': ['linux', 'posix', 'mac'],
-              'deps': [
-                  'grpc_test_util',
-                  'grpc',
-                  'gpr_test_util',
-                  'gpr'
-              ]
-          }
-      for t in sorted(BAD_CLIENT_TESTS.keys())]}
-  print yaml.dump(json)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/test/core/bad_ssl/generate_tests.bzl b/test/core/bad_ssl/generate_tests.bzl
new file mode 100755
index 0000000000..78474bc1ca
--- /dev/null
+++ b/test/core/bad_ssl/generate_tests.bzl
@@ -0,0 +1,52 @@
+#!/usr/bin/env python2.7
+# 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.
+
+
+def test_options():
+  return struct()
+
+
+# maps test names to options
+BAD_SSL_TESTS = ['cert', 'alpn']
+
+def grpc_bad_ssl_tests():
+  native.cc_library(
+      name = 'bad_ssl_test_server',
+      srcs = ['server_common.c'],
+      hdrs = ['server_common.h'],
+      deps = ['//test/core/util:grpc_test_util', '//:grpc', '//test/core/end2end:ssl_test_data']
+  )
+  for t in BAD_SSL_TESTS:
+    native.cc_test(
+        name = 'bad_ssl_%s_server' % t,
+        srcs = ['servers/%s.c' % t],
+        deps = [':bad_ssl_test_server'],
+    )
+
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index fd425c3f3a..bb439fb18d 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -39,6 +39,7 @@ cc_library(
 
 cc_library(
   name = 'ssl_test_data',
+  visibility = ["//test:__subpackages__"],
   hdrs = ['data/ssl_test_data.h'],
   srcs = [
     "data/client_certs.c",
-- 
GitLab


From 4dba2ea20cb81e1fd1f863ca2c58ab4be7e4fea2 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 22:16:37 +0200
Subject: [PATCH 014/344] Moving message_size stuff out of core lib.

---
 src/core/ext/client_config/message_size_filter.c |  2 +-
 src/core/lib/surface/init.c                      | 10 ----------
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/src/core/ext/client_config/message_size_filter.c b/src/core/ext/client_config/message_size_filter.c
index 1382f19945..a435ad5543 100644
--- a/src/core/ext/client_config/message_size_filter.c
+++ b/src/core/ext/client_config/message_size_filter.c
@@ -29,7 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "src/core/lib/channel/message_size_filter.h"
+#include "src/core/ext/client_config/message_size_filter.h"
 
 #include <limits.h>
 #include <string.h>
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 8ca0643ba7..2c8f28ee45 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -46,7 +46,6 @@
 #include "src/core/lib/channel/deadline_filter.h"
 #include "src/core/lib/channel/http_client_filter.h"
 #include "src/core/lib/channel/http_server_filter.h"
-#include "src/core/lib/channel/message_size_filter.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -106,15 +105,6 @@ static void register_builtin_channel_init() {
   grpc_channel_init_register_stage(
       GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
       (void *)&grpc_server_deadline_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_message_size_filter);
-  grpc_channel_init_register_stage(
-      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      prepend_filter, (void *)&grpc_message_size_filter);
-  grpc_channel_init_register_stage(
-      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
-      (void *)&grpc_message_size_filter);
   grpc_channel_init_register_stage(
       GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
       (void *)&grpc_compress_filter);
-- 
GitLab


From d196c8adb3b8ace4bc1a0a0d43c10ce03bf51d7b Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 20 Oct 2016 13:22:51 -0700
Subject: [PATCH 015/344] Fixes

---
 test/core/end2end/BUILD              | 5 +++++
 test/core/end2end/generate_tests.bzl | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index bb439fb18d..681cea1de7 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -34,6 +34,7 @@ cc_library(
   srcs = ['cq_verifier.c'],
   hdrs = ['cq_verifier.h'],
   deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'],
+  copts = ['-std=c99'],
   visibility = ["//test:__subpackages__"],
 )
 
@@ -41,6 +42,7 @@ cc_library(
   name = 'ssl_test_data',
   visibility = ["//test:__subpackages__"],
   hdrs = ['data/ssl_test_data.h'],
+  copts = ['-std=c99'],
   srcs = [
     "data/client_certs.c",
     "data/server1_cert.c",
@@ -53,6 +55,7 @@ cc_library(
   name = 'fake_resolver',
   hdrs = ['fake_resolver.h'],
   srcs = ['fake_resolver.c'],
+  copts = ['-std=c99'],
   deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
 )
 
@@ -60,6 +63,7 @@ cc_library(
   name = 'http_proxy',
   hdrs = ['fixtures/http_proxy.h'],
   srcs = ['fixtures/http_proxy.c'],
+  copts = ['-std=c99'],
   deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
 )
 
@@ -67,6 +71,7 @@ cc_library(
   name = 'proxy',
   hdrs = ['fixtures/proxy.h'],
   srcs = ['fixtures/proxy.c'],
+  copts = ['-std=c99'],
   deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
 )
 
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index d6b0aaa2f4..aae8b4f7bd 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -158,6 +158,7 @@ def grpc_end2end_tests():
       'tests/cancel_test_helpers.h',
       'end2end_tests.h'
     ],
+    copts = ['-std=c99'],
     deps = [
       ':cq_verifier',
       ':ssl_test_data',
@@ -175,6 +176,7 @@ def grpc_end2end_tests():
     native.cc_library(
       name = '%s_test_lib' % f,
       srcs = ['fixtures/%s.c' % f],
+      copts = ['-std=c99'],
       deps = [':end2end_tests']
     )
     for t, topt in END2END_TESTS.items():
@@ -183,5 +185,5 @@ def grpc_end2end_tests():
       native.cc_test(
         name = '%s_test@%s' % (f, t),
         args = [t],
-        deps = [':%s_test_lib' % f]
+        deps = [':%s_test_lib' % f],
       )
-- 
GitLab


From d58c375d764c65d699cfd0e4536c3e8f631e8221 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 22:30:16 +0200
Subject: [PATCH 016/344] Buildify.

---
 BUILD                  | 1972 ++++++++++++++++++++--------------------
 third_party/zlib.BUILD |   69 +-
 2 files changed, 1018 insertions(+), 1023 deletions(-)

diff --git a/BUILD b/BUILD
index b1bbbffb4b..7230183155 100644
--- a/BUILD
+++ b/BUILD
@@ -38,1097 +38,1093 @@ package(default_visibility = ["//visibility:public"])
 load(":grpc-build-system.bzl", "grpc_cc_library")
 
 g_stands_for = "good"
+
 version = "1.1.0-dev"
 
 grpc_cc_library(
-  name = "gpr",
-  deps = [
-    "gpr_base",
-  ],
-  language = "c",
-  standalone = True,
+    name = "gpr",
+    language = "c",
+    standalone = True,
+    deps = [
+        "gpr_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc",
-  srcs = [
-    "src/core/lib/surface/init.c",
-    "src/core/plugin_registry/grpc_plugin_registry.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_chttp2_server_secure",
-    "grpc_transport_chttp2_client_secure",
-    "grpc_transport_chttp2_server_insecure",
-    "grpc_transport_chttp2_client_insecure",
-    "grpc_lb_policy_grpclb",
-    "grpc_lb_policy_pick_first",
-    "grpc_lb_policy_round_robin",
-    "grpc_resolver_dns_native",
-    "grpc_resolver_sockaddr",
-    "grpc_load_reporting",
-    "grpc_secure",
-    "census",
-  ],
-  language = "c",
-  standalone = True,
+    name = "grpc",
+    srcs = [
+        "src/core/lib/surface/init.c",
+        "src/core/plugin_registry/grpc_plugin_registry.c",
+    ],
+    language = "c",
+    standalone = True,
+    deps = [
+        "census",
+        "grpc_base",
+        "grpc_lb_policy_grpclb",
+        "grpc_lb_policy_pick_first",
+        "grpc_lb_policy_round_robin",
+        "grpc_load_reporting",
+        "grpc_resolver_dns_native",
+        "grpc_resolver_sockaddr",
+        "grpc_secure",
+        "grpc_transport_chttp2_client_insecure",
+        "grpc_transport_chttp2_client_secure",
+        "grpc_transport_chttp2_server_insecure",
+        "grpc_transport_chttp2_server_secure",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_cronet",
-  srcs = [
-    "src/core/lib/surface/init.c",
-    "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_cronet_client_secure",
-    "grpc_transport_chttp2_client_secure",
-  ],
-  language = "c",
+    name = "grpc_cronet",
+    srcs = [
+        "src/core/lib/surface/init.c",
+        "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_transport_chttp2_client_secure",
+        "grpc_transport_cronet_client_secure",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_unsecure",
-  srcs = [
-    "src/core/lib/surface/init.c",
-    "src/core/lib/surface/init_unsecure.c",
-    "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_chttp2_server_insecure",
-    "grpc_transport_chttp2_client_insecure",
-    "grpc_resolver_dns_native",
-    "grpc_resolver_sockaddr",
-    "grpc_load_reporting",
-    "grpc_lb_policy_grpclb",
-    "grpc_lb_policy_pick_first",
-    "grpc_lb_policy_round_robin",
-    "census",
-  ],
-  language = "c",
-  standalone = True,
+    name = "grpc_unsecure",
+    srcs = [
+        "src/core/lib/surface/init.c",
+        "src/core/lib/surface/init_unsecure.c",
+        "src/core/plugin_registry/grpc_unsecure_plugin_registry.c",
+    ],
+    language = "c",
+    standalone = True,
+    deps = [
+        "census",
+        "grpc_base",
+        "grpc_lb_policy_grpclb",
+        "grpc_lb_policy_pick_first",
+        "grpc_lb_policy_round_robin",
+        "grpc_load_reporting",
+        "grpc_resolver_dns_native",
+        "grpc_resolver_sockaddr",
+        "grpc_transport_chttp2_client_insecure",
+        "grpc_transport_chttp2_server_insecure",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++",
-  srcs = [
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/client/secure_credentials.cc",
-    "src/cpp/common/auth_property_iterator.cc",
-    "src/cpp/common/secure_auth_context.cc",
-    "src/cpp/common/secure_channel_arguments.cc",
-    "src/cpp/common/secure_create_auth_context.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/server/secure_server_credentials.cc",
-  ],
-  hdrs = [
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "src/cpp/client/secure_credentials.h",
-    "src/cpp/common/secure_auth_context.h",
-    "src/cpp/server/secure_server_credentials.h",
-  ],
-  deps = [
-    "gpr",
-    "grpc",
-    "grpc++_base",
-    "grpc++_codegen_base",
-    "grpc++_codegen_base_src",
-  ],
-  language = "c++",
-  standalone = True,
+    name = "grpc++",
+    srcs = [
+        "src/cpp/client/insecure_credentials.cc",
+        "src/cpp/client/secure_credentials.cc",
+        "src/cpp/common/auth_property_iterator.cc",
+        "src/cpp/common/secure_auth_context.cc",
+        "src/cpp/common/secure_channel_arguments.cc",
+        "src/cpp/common/secure_create_auth_context.cc",
+        "src/cpp/server/insecure_server_credentials.cc",
+        "src/cpp/server/secure_server_credentials.cc",
+    ],
+    hdrs = [
+        "include/grpc++/impl/codegen/core_codegen.h",
+        "src/cpp/client/secure_credentials.h",
+        "src/cpp/common/secure_auth_context.h",
+        "src/cpp/server/secure_server_credentials.h",
+    ],
+    language = "c++",
+    standalone = True,
+    deps = [
+        "gpr",
+        "grpc",
+        "grpc++_base",
+        "grpc++_codegen_base",
+        "grpc++_codegen_base_src",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_unsecure",
-  srcs = [
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/insecure_create_auth_context.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-  ],
-  hdrs = [
-  ],
-  public_hdrs = [
-  ],
-  deps = [
-    "gpr",
-    "grpc_unsecure",
-    "grpc++_base",
-    "grpc++_codegen_base",
-    "grpc++_codegen_base_src",
-  ],
-  language = "c++",
-  standalone = True,
+    name = "grpc++_unsecure",
+    srcs = [
+        "src/cpp/client/insecure_credentials.cc",
+        "src/cpp/common/insecure_create_auth_context.cc",
+        "src/cpp/server/insecure_server_credentials.cc",
+    ],
+    language = "c++",
+    standalone = True,
+    deps = [
+        "gpr",
+        "grpc++_base",
+        "grpc++_codegen_base",
+        "grpc++_codegen_base_src",
+        "grpc_unsecure",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_plugin_support",
-  srcs = [
-    "src/compiler/cpp_generator.cc",
-    "src/compiler/csharp_generator.cc",
-    "src/compiler/node_generator.cc",
-    "src/compiler/objective_c_generator.cc",
-    "src/compiler/php_generator.cc",
-    "src/compiler/python_generator.cc",
-    "src/compiler/ruby_generator.cc",
-  ],
-  hdrs = [
-    "src/compiler/config.h",
-    "src/compiler/cpp_generator.h",
-    "src/compiler/cpp_generator_helpers.h",
-    "src/compiler/csharp_generator.h",
-    "src/compiler/csharp_generator_helpers.h",
-    "src/compiler/generator_helpers.h",
-    "src/compiler/node_generator.h",
-    "src/compiler/node_generator_helpers.h",
-    "src/compiler/objective_c_generator.h",
-    "src/compiler/objective_c_generator_helpers.h",
-    "src/compiler/php_generator.h",
-    "src/compiler/php_generator_helpers.h",
-    "src/compiler/python_generator.h",
-    "src/compiler/ruby_generator.h",
-    "src/compiler/ruby_generator_helpers-inl.h",
-    "src/compiler/ruby_generator_map-inl.h",
-    "src/compiler/ruby_generator_string-inl.h",
-  ],
-  external_deps = [
-    "protobuf_compiler",
-  ],
-  deps = [
-    "grpc++_config_proto",
-  ],
-  language = "c++",
+    name = "grpc_plugin_support",
+    srcs = [
+        "src/compiler/cpp_generator.cc",
+        "src/compiler/csharp_generator.cc",
+        "src/compiler/node_generator.cc",
+        "src/compiler/objective_c_generator.cc",
+        "src/compiler/php_generator.cc",
+        "src/compiler/python_generator.cc",
+        "src/compiler/ruby_generator.cc",
+    ],
+    hdrs = [
+        "src/compiler/config.h",
+        "src/compiler/cpp_generator.h",
+        "src/compiler/cpp_generator_helpers.h",
+        "src/compiler/csharp_generator.h",
+        "src/compiler/csharp_generator_helpers.h",
+        "src/compiler/generator_helpers.h",
+        "src/compiler/node_generator.h",
+        "src/compiler/node_generator_helpers.h",
+        "src/compiler/objective_c_generator.h",
+        "src/compiler/objective_c_generator_helpers.h",
+        "src/compiler/php_generator.h",
+        "src/compiler/php_generator_helpers.h",
+        "src/compiler/python_generator.h",
+        "src/compiler/ruby_generator.h",
+        "src/compiler/ruby_generator_helpers-inl.h",
+        "src/compiler/ruby_generator_map-inl.h",
+        "src/compiler/ruby_generator_string-inl.h",
+    ],
+    external_deps = [
+        "protobuf_compiler",
+    ],
+    language = "c++",
+    deps = [
+        "grpc++_config_proto",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_csharp_ext",
-  srcs = [
-    "src/csharp/ext/grpc_csharp_ext.c",
-  ],
-  deps = [
-    "grpc",
-    "gpr",
-  ],
-  language = "csharp",
+    name = "grpc_csharp_ext",
+    srcs = [
+        "src/csharp/ext/grpc_csharp_ext.c",
+    ],
+    language = "csharp",
+    deps = [
+        "gpr",
+        "grpc",
+    ],
 )
 
 grpc_cc_library(
-  name = "census",
-  srcs = [
-    "src/core/ext/census/base_resources.c",
-    "src/core/ext/census/context.c",
-    "src/core/ext/census/gen/census.pb.c",
-    "src/core/ext/census/gen/trace_context.pb.c",
-    "src/core/ext/census/grpc_context.c",
-    "src/core/ext/census/grpc_filter.c",
-    "src/core/ext/census/grpc_plugin.c",
-    "src/core/ext/census/initialize.c",
-    "src/core/ext/census/mlog.c",
-    "src/core/ext/census/operation.c",
-    "src/core/ext/census/placeholders.c",
-    "src/core/ext/census/resource.c",
-    "src/core/ext/census/trace_context.c",
-    "src/core/ext/census/tracing.c",
-  ],
-  hdrs = [
-    "src/core/ext/census/aggregation.h",
-    "src/core/ext/census/base_resources.h",
-    "src/core/ext/census/census_interface.h",
-    "src/core/ext/census/census_rpc_stats.h",
-    "src/core/ext/census/gen/census.pb.h",
-    "src/core/ext/census/gen/trace_context.pb.h",
-    "src/core/ext/census/grpc_filter.h",
-    "src/core/ext/census/mlog.h",
-    "src/core/ext/census/resource.h",
-    "src/core/ext/census/rpc_metric_id.h",
-    "src/core/ext/census/trace_context.h",
-  ],
-  public_hdrs = [
-    "include/grpc/census.h",
-  ],
-  external_deps = [
-    "nanopb",
-  ],
-  deps = [
-    "grpc_base",
-  ],
-  language = "c",
+    name = "census",
+    srcs = [
+        "src/core/ext/census/base_resources.c",
+        "src/core/ext/census/context.c",
+        "src/core/ext/census/gen/census.pb.c",
+        "src/core/ext/census/gen/trace_context.pb.c",
+        "src/core/ext/census/grpc_context.c",
+        "src/core/ext/census/grpc_filter.c",
+        "src/core/ext/census/grpc_plugin.c",
+        "src/core/ext/census/initialize.c",
+        "src/core/ext/census/mlog.c",
+        "src/core/ext/census/operation.c",
+        "src/core/ext/census/placeholders.c",
+        "src/core/ext/census/resource.c",
+        "src/core/ext/census/trace_context.c",
+        "src/core/ext/census/tracing.c",
+    ],
+    hdrs = [
+        "src/core/ext/census/aggregation.h",
+        "src/core/ext/census/base_resources.h",
+        "src/core/ext/census/census_interface.h",
+        "src/core/ext/census/census_rpc_stats.h",
+        "src/core/ext/census/gen/census.pb.h",
+        "src/core/ext/census/gen/trace_context.pb.h",
+        "src/core/ext/census/grpc_filter.h",
+        "src/core/ext/census/mlog.h",
+        "src/core/ext/census/resource.h",
+        "src/core/ext/census/rpc_metric_id.h",
+        "src/core/ext/census/trace_context.h",
+    ],
+    external_deps = [
+        "nanopb",
+    ],
+    language = "c",
+    public_hdrs = [
+        "include/grpc/census.h",
+    ],
+    deps = [
+        "grpc_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "gpr_base",
-  srcs = [
-    "src/core/lib/profiling/basic_timers.c",
-    "src/core/lib/profiling/stap_timers.c",
-    "src/core/lib/support/alloc.c",
-    "src/core/lib/support/avl.c",
-    "src/core/lib/support/backoff.c",
-    "src/core/lib/support/cmdline.c",
-    "src/core/lib/support/cpu_iphone.c",
-    "src/core/lib/support/cpu_linux.c",
-    "src/core/lib/support/cpu_posix.c",
-    "src/core/lib/support/cpu_windows.c",
-    "src/core/lib/support/env_linux.c",
-    "src/core/lib/support/env_posix.c",
-    "src/core/lib/support/env_windows.c",
-    "src/core/lib/support/histogram.c",
-    "src/core/lib/support/host_port.c",
-    "src/core/lib/support/log.c",
-    "src/core/lib/support/log_android.c",
-    "src/core/lib/support/log_linux.c",
-    "src/core/lib/support/log_posix.c",
-    "src/core/lib/support/log_windows.c",
-    "src/core/lib/support/mpscq.c",
-    "src/core/lib/support/murmur_hash.c",
-    "src/core/lib/support/percent_encoding.c",
-    "src/core/lib/support/slice.c",
-    "src/core/lib/support/slice_buffer.c",
-    "src/core/lib/support/stack_lockfree.c",
-    "src/core/lib/support/string.c",
-    "src/core/lib/support/string_posix.c",
-    "src/core/lib/support/string_util_windows.c",
-    "src/core/lib/support/string_windows.c",
-    "src/core/lib/support/subprocess_posix.c",
-    "src/core/lib/support/subprocess_windows.c",
-    "src/core/lib/support/sync.c",
-    "src/core/lib/support/sync_posix.c",
-    "src/core/lib/support/sync_windows.c",
-    "src/core/lib/support/thd.c",
-    "src/core/lib/support/thd_posix.c",
-    "src/core/lib/support/thd_windows.c",
-    "src/core/lib/support/time.c",
-    "src/core/lib/support/time_posix.c",
-    "src/core/lib/support/time_precise.c",
-    "src/core/lib/support/time_windows.c",
-    "src/core/lib/support/tls_pthread.c",
-    "src/core/lib/support/tmpfile_msys.c",
-    "src/core/lib/support/tmpfile_posix.c",
-    "src/core/lib/support/tmpfile_windows.c",
-    "src/core/lib/support/wrap_memcpy.c",
-  ],
-  hdrs = [
-    "src/core/lib/profiling/timers.h",
-    "src/core/lib/support/backoff.h",
-    "src/core/lib/support/block_annotate.h",
-    "src/core/lib/support/env.h",
-    "src/core/lib/support/mpscq.h",
-    "src/core/lib/support/murmur_hash.h",
-    "src/core/lib/support/percent_encoding.h",
-    "src/core/lib/support/stack_lockfree.h",
-    "src/core/lib/support/string.h",
-    "src/core/lib/support/string_windows.h",
-    "src/core/lib/support/thd_internal.h",
-    "src/core/lib/support/time_precise.h",
-    "src/core/lib/support/tmpfile.h",
-  ],
-  public_hdrs = [
-    "include/grpc/support/alloc.h",
-    "include/grpc/support/atm.h",
-    "include/grpc/support/atm_gcc_atomic.h",
-    "include/grpc/support/atm_gcc_sync.h",
-    "include/grpc/support/atm_windows.h",
-    "include/grpc/support/avl.h",
-    "include/grpc/support/cmdline.h",
-    "include/grpc/support/cpu.h",
-    "include/grpc/support/histogram.h",
-    "include/grpc/support/host_port.h",
-    "include/grpc/support/log.h",
-    "include/grpc/support/log_windows.h",
-    "include/grpc/support/port_platform.h",
-    "include/grpc/support/slice.h",
-    "include/grpc/support/slice_buffer.h",
-    "include/grpc/support/string_util.h",
-    "include/grpc/support/subprocess.h",
-    "include/grpc/support/sync.h",
-    "include/grpc/support/sync_generic.h",
-    "include/grpc/support/sync_posix.h",
-    "include/grpc/support/sync_windows.h",
-    "include/grpc/support/thd.h",
-    "include/grpc/support/time.h",
-    "include/grpc/support/tls.h",
-    "include/grpc/support/tls_gcc.h",
-    "include/grpc/support/tls_msvc.h",
-    "include/grpc/support/tls_pthread.h",
-    "include/grpc/support/useful.h",
-  ],
-  deps = [
-    "gpr_codegen",
-  ],
-  language = "c",
+    name = "gpr_base",
+    srcs = [
+        "src/core/lib/profiling/basic_timers.c",
+        "src/core/lib/profiling/stap_timers.c",
+        "src/core/lib/support/alloc.c",
+        "src/core/lib/support/avl.c",
+        "src/core/lib/support/backoff.c",
+        "src/core/lib/support/cmdline.c",
+        "src/core/lib/support/cpu_iphone.c",
+        "src/core/lib/support/cpu_linux.c",
+        "src/core/lib/support/cpu_posix.c",
+        "src/core/lib/support/cpu_windows.c",
+        "src/core/lib/support/env_linux.c",
+        "src/core/lib/support/env_posix.c",
+        "src/core/lib/support/env_windows.c",
+        "src/core/lib/support/histogram.c",
+        "src/core/lib/support/host_port.c",
+        "src/core/lib/support/log.c",
+        "src/core/lib/support/log_android.c",
+        "src/core/lib/support/log_linux.c",
+        "src/core/lib/support/log_posix.c",
+        "src/core/lib/support/log_windows.c",
+        "src/core/lib/support/mpscq.c",
+        "src/core/lib/support/murmur_hash.c",
+        "src/core/lib/support/percent_encoding.c",
+        "src/core/lib/support/slice.c",
+        "src/core/lib/support/slice_buffer.c",
+        "src/core/lib/support/stack_lockfree.c",
+        "src/core/lib/support/string.c",
+        "src/core/lib/support/string_posix.c",
+        "src/core/lib/support/string_util_windows.c",
+        "src/core/lib/support/string_windows.c",
+        "src/core/lib/support/subprocess_posix.c",
+        "src/core/lib/support/subprocess_windows.c",
+        "src/core/lib/support/sync.c",
+        "src/core/lib/support/sync_posix.c",
+        "src/core/lib/support/sync_windows.c",
+        "src/core/lib/support/thd.c",
+        "src/core/lib/support/thd_posix.c",
+        "src/core/lib/support/thd_windows.c",
+        "src/core/lib/support/time.c",
+        "src/core/lib/support/time_posix.c",
+        "src/core/lib/support/time_precise.c",
+        "src/core/lib/support/time_windows.c",
+        "src/core/lib/support/tls_pthread.c",
+        "src/core/lib/support/tmpfile_msys.c",
+        "src/core/lib/support/tmpfile_posix.c",
+        "src/core/lib/support/tmpfile_windows.c",
+        "src/core/lib/support/wrap_memcpy.c",
+    ],
+    hdrs = [
+        "src/core/lib/profiling/timers.h",
+        "src/core/lib/support/backoff.h",
+        "src/core/lib/support/block_annotate.h",
+        "src/core/lib/support/env.h",
+        "src/core/lib/support/mpscq.h",
+        "src/core/lib/support/murmur_hash.h",
+        "src/core/lib/support/percent_encoding.h",
+        "src/core/lib/support/stack_lockfree.h",
+        "src/core/lib/support/string.h",
+        "src/core/lib/support/string_windows.h",
+        "src/core/lib/support/thd_internal.h",
+        "src/core/lib/support/time_precise.h",
+        "src/core/lib/support/tmpfile.h",
+    ],
+    language = "c",
+    public_hdrs = [
+        "include/grpc/support/alloc.h",
+        "include/grpc/support/atm.h",
+        "include/grpc/support/atm_gcc_atomic.h",
+        "include/grpc/support/atm_gcc_sync.h",
+        "include/grpc/support/atm_windows.h",
+        "include/grpc/support/avl.h",
+        "include/grpc/support/cmdline.h",
+        "include/grpc/support/cpu.h",
+        "include/grpc/support/histogram.h",
+        "include/grpc/support/host_port.h",
+        "include/grpc/support/log.h",
+        "include/grpc/support/log_windows.h",
+        "include/grpc/support/port_platform.h",
+        "include/grpc/support/slice.h",
+        "include/grpc/support/slice_buffer.h",
+        "include/grpc/support/string_util.h",
+        "include/grpc/support/subprocess.h",
+        "include/grpc/support/sync.h",
+        "include/grpc/support/sync_generic.h",
+        "include/grpc/support/sync_posix.h",
+        "include/grpc/support/sync_windows.h",
+        "include/grpc/support/thd.h",
+        "include/grpc/support/time.h",
+        "include/grpc/support/tls.h",
+        "include/grpc/support/tls_gcc.h",
+        "include/grpc/support/tls_msvc.h",
+        "include/grpc/support/tls_pthread.h",
+        "include/grpc/support/useful.h",
+    ],
+    deps = [
+        "gpr_codegen",
+    ],
 )
 
 grpc_cc_library(
-  name = "gpr_codegen",
-  public_hdrs = [
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/gpr_types.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_windows.h",
-  ],
-  language = "c",
+    name = "gpr_codegen",
+    language = "c",
+    public_hdrs = [
+        "include/grpc/impl/codegen/atm.h",
+        "include/grpc/impl/codegen/atm_gcc_atomic.h",
+        "include/grpc/impl/codegen/atm_gcc_sync.h",
+        "include/grpc/impl/codegen/atm_windows.h",
+        "include/grpc/impl/codegen/gpr_types.h",
+        "include/grpc/impl/codegen/port_platform.h",
+        "include/grpc/impl/codegen/slice.h",
+        "include/grpc/impl/codegen/sync.h",
+        "include/grpc/impl/codegen/sync_generic.h",
+        "include/grpc/impl/codegen/sync_posix.h",
+        "include/grpc/impl/codegen/sync_windows.h",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_base",
-  srcs = [
-    "src/core/lib/channel/channel_args.c",
-    "src/core/lib/channel/channel_stack.c",
-    "src/core/lib/channel/channel_stack_builder.c",
-    "src/core/lib/channel/compress_filter.c",
-    "src/core/lib/channel/connected_channel.c",
-    "src/core/lib/channel/deadline_filter.c",
-    "src/core/lib/channel/handshaker.c",
-    "src/core/lib/channel/http_client_filter.c",
-    "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression.c",
-    "src/core/lib/compression/message_compress.c",
-    "src/core/lib/debug/trace.c",
-    "src/core/lib/http/format_request.c",
-    "src/core/lib/http/httpcli.c",
-    "src/core/lib/http/parser.c",
-    "src/core/lib/iomgr/closure.c",
-    "src/core/lib/iomgr/combiner.c",
-    "src/core/lib/iomgr/endpoint.c",
-    "src/core/lib/iomgr/endpoint_pair_posix.c",
-    "src/core/lib/iomgr/endpoint_pair_windows.c",
-    "src/core/lib/iomgr/error.c",
-    "src/core/lib/iomgr/ev_epoll_linux.c",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
-    "src/core/lib/iomgr/ev_poll_posix.c",
-    "src/core/lib/iomgr/ev_posix.c",
-    "src/core/lib/iomgr/exec_ctx.c",
-    "src/core/lib/iomgr/executor.c",
-    "src/core/lib/iomgr/iocp_windows.c",
-    "src/core/lib/iomgr/iomgr.c",
-    "src/core/lib/iomgr/iomgr_posix.c",
-    "src/core/lib/iomgr/iomgr_windows.c",
-    "src/core/lib/iomgr/load_file.c",
-    "src/core/lib/iomgr/network_status_tracker.c",
-    "src/core/lib/iomgr/polling_entity.c",
-    "src/core/lib/iomgr/pollset_set_windows.c",
-    "src/core/lib/iomgr/pollset_windows.c",
-    "src/core/lib/iomgr/resolve_address_posix.c",
-    "src/core/lib/iomgr/resolve_address_windows.c",
-    "src/core/lib/iomgr/sockaddr_utils.c",
-    "src/core/lib/iomgr/socket_utils_common_posix.c",
-    "src/core/lib/iomgr/socket_utils_linux.c",
-    "src/core/lib/iomgr/socket_utils_posix.c",
-    "src/core/lib/iomgr/socket_windows.c",
-    "src/core/lib/iomgr/tcp_client_posix.c",
-    "src/core/lib/iomgr/tcp_client_windows.c",
-    "src/core/lib/iomgr/tcp_posix.c",
-    "src/core/lib/iomgr/tcp_server_posix.c",
-    "src/core/lib/iomgr/tcp_server_windows.c",
-    "src/core/lib/iomgr/tcp_windows.c",
-    "src/core/lib/iomgr/time_averaged_stats.c",
-    "src/core/lib/iomgr/timer.c",
-    "src/core/lib/iomgr/timer_heap.c",
-    "src/core/lib/iomgr/udp_server.c",
-    "src/core/lib/iomgr/unix_sockets_posix.c",
-    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
-    "src/core/lib/iomgr/wakeup_fd_cv.c",
-    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
-    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
-    "src/core/lib/iomgr/wakeup_fd_pipe.c",
-    "src/core/lib/iomgr/wakeup_fd_posix.c",
-    "src/core/lib/iomgr/workqueue_windows.c",
-    "src/core/lib/json/json.c",
-    "src/core/lib/json/json_reader.c",
-    "src/core/lib/json/json_string.c",
-    "src/core/lib/json/json_writer.c",
-    "src/core/lib/surface/alarm.c",
-    "src/core/lib/surface/api_trace.c",
-    "src/core/lib/surface/byte_buffer.c",
-    "src/core/lib/surface/byte_buffer_reader.c",
-    "src/core/lib/surface/call.c",
-    "src/core/lib/surface/call_details.c",
-    "src/core/lib/surface/call_log_batch.c",
-    "src/core/lib/surface/channel.c",
-    "src/core/lib/surface/channel_init.c",
-    "src/core/lib/surface/channel_ping.c",
-    "src/core/lib/surface/channel_stack_type.c",
-    "src/core/lib/surface/completion_queue.c",
-    "src/core/lib/surface/event_string.c",
-    "src/core/lib/surface/lame_client.c",
-    "src/core/lib/surface/metadata_array.c",
-    "src/core/lib/surface/server.c",
-    "src/core/lib/surface/validate_metadata.c",
-    "src/core/lib/surface/version.c",
-    "src/core/lib/transport/byte_stream.c",
-    "src/core/lib/transport/connectivity_state.c",
-    "src/core/lib/transport/mdstr_hash_table.c",
-    "src/core/lib/transport/metadata.c",
-    "src/core/lib/transport/metadata_batch.c",
-    "src/core/lib/transport/static_metadata.c",
-    "src/core/lib/transport/timeout_encoding.c",
-    "src/core/lib/transport/transport.c",
-    "src/core/lib/transport/transport_op_string.c",
-  ],
-  hdrs = [
-    "src/core/lib/channel/channel_args.h",
-    "src/core/lib/channel/channel_stack.h",
-    "src/core/lib/channel/channel_stack_builder.h",
-    "src/core/lib/channel/compress_filter.h",
-    "src/core/lib/channel/connected_channel.h",
-    "src/core/lib/channel/context.h",
-    "src/core/lib/channel/deadline_filter.h",
-    "src/core/lib/channel/handshaker.h",
-    "src/core/lib/channel/http_client_filter.h",
-    "src/core/lib/channel/http_server_filter.h",
-    "src/core/lib/compression/algorithm_metadata.h",
-    "src/core/lib/compression/message_compress.h",
-    "src/core/lib/debug/trace.h",
-    "src/core/lib/http/format_request.h",
-    "src/core/lib/http/httpcli.h",
-    "src/core/lib/http/parser.h",
-    "src/core/lib/iomgr/closure.h",
-    "src/core/lib/iomgr/combiner.h",
-    "src/core/lib/iomgr/endpoint.h",
-    "src/core/lib/iomgr/endpoint_pair.h",
-    "src/core/lib/iomgr/error.h",
-    "src/core/lib/iomgr/ev_epoll_linux.h",
-    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
-    "src/core/lib/iomgr/ev_poll_posix.h",
-    "src/core/lib/iomgr/ev_posix.h",
-    "src/core/lib/iomgr/exec_ctx.h",
-    "src/core/lib/iomgr/executor.h",
-    "src/core/lib/iomgr/iocp_windows.h",
-    "src/core/lib/iomgr/iomgr.h",
-    "src/core/lib/iomgr/iomgr_internal.h",
-    "src/core/lib/iomgr/iomgr_posix.h",
-    "src/core/lib/iomgr/load_file.h",
-    "src/core/lib/iomgr/network_status_tracker.h",
-    "src/core/lib/iomgr/polling_entity.h",
-    "src/core/lib/iomgr/pollset.h",
-    "src/core/lib/iomgr/pollset_set.h",
-    "src/core/lib/iomgr/pollset_set_windows.h",
-    "src/core/lib/iomgr/pollset_windows.h",
-    "src/core/lib/iomgr/resolve_address.h",
-    "src/core/lib/iomgr/sockaddr.h",
-    "src/core/lib/iomgr/sockaddr_posix.h",
-    "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_windows.h",
-    "src/core/lib/iomgr/socket_utils_posix.h",
-    "src/core/lib/iomgr/socket_windows.h",
-    "src/core/lib/iomgr/tcp_client.h",
-    "src/core/lib/iomgr/tcp_posix.h",
-    "src/core/lib/iomgr/tcp_server.h",
-    "src/core/lib/iomgr/tcp_windows.h",
-    "src/core/lib/iomgr/time_averaged_stats.h",
-    "src/core/lib/iomgr/timer.h",
-    "src/core/lib/iomgr/timer_heap.h",
-    "src/core/lib/iomgr/udp_server.h",
-    "src/core/lib/iomgr/unix_sockets_posix.h",
-    "src/core/lib/iomgr/wakeup_fd_cv.h",
-    "src/core/lib/iomgr/wakeup_fd_pipe.h",
-    "src/core/lib/iomgr/wakeup_fd_posix.h",
-    "src/core/lib/iomgr/workqueue.h",
-    "src/core/lib/iomgr/workqueue_windows.h",
-    "src/core/lib/json/json.h",
-    "src/core/lib/json/json_common.h",
-    "src/core/lib/json/json_reader.h",
-    "src/core/lib/json/json_writer.h",
-    "src/core/lib/surface/api_trace.h",
-    "src/core/lib/surface/call.h",
-    "src/core/lib/surface/call_test_only.h",
-    "src/core/lib/surface/channel.h",
-    "src/core/lib/surface/channel_init.h",
-    "src/core/lib/surface/channel_stack_type.h",
-    "src/core/lib/surface/completion_queue.h",
-    "src/core/lib/surface/event_string.h",
-    "src/core/lib/surface/init.h",
-    "src/core/lib/surface/lame_client.h",
-    "src/core/lib/surface/server.h",
-    "src/core/lib/transport/byte_stream.h",
-    "src/core/lib/transport/connectivity_state.h",
-    "src/core/lib/transport/mdstr_hash_table.h",
-    "src/core/lib/transport/metadata.h",
-    "src/core/lib/transport/metadata_batch.h",
-    "src/core/lib/transport/static_metadata.h",
-    "src/core/lib/transport/timeout_encoding.h",
-    "src/core/lib/transport/transport.h",
-    "src/core/lib/transport/transport_impl.h",
-  ],
-  public_hdrs = [
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/grpc_posix.h",
-    "include/grpc/grpc_security_constants.h",
-    "include/grpc/status.h",
-  ],
-  external_deps = [
-    "zlib",
-  ],
-  deps = [
-    "grpc_codegen",
-    "gpr_base",
-  ],
-  language = "c",
+    name = "grpc_base",
+    srcs = [
+        "src/core/lib/channel/channel_args.c",
+        "src/core/lib/channel/channel_stack.c",
+        "src/core/lib/channel/channel_stack_builder.c",
+        "src/core/lib/channel/compress_filter.c",
+        "src/core/lib/channel/connected_channel.c",
+        "src/core/lib/channel/deadline_filter.c",
+        "src/core/lib/channel/handshaker.c",
+        "src/core/lib/channel/http_client_filter.c",
+        "src/core/lib/channel/http_server_filter.c",
+        "src/core/lib/compression/compression.c",
+        "src/core/lib/compression/message_compress.c",
+        "src/core/lib/debug/trace.c",
+        "src/core/lib/http/format_request.c",
+        "src/core/lib/http/httpcli.c",
+        "src/core/lib/http/parser.c",
+        "src/core/lib/iomgr/closure.c",
+        "src/core/lib/iomgr/combiner.c",
+        "src/core/lib/iomgr/endpoint.c",
+        "src/core/lib/iomgr/endpoint_pair_posix.c",
+        "src/core/lib/iomgr/endpoint_pair_windows.c",
+        "src/core/lib/iomgr/error.c",
+        "src/core/lib/iomgr/ev_epoll_linux.c",
+        "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
+        "src/core/lib/iomgr/ev_poll_posix.c",
+        "src/core/lib/iomgr/ev_posix.c",
+        "src/core/lib/iomgr/exec_ctx.c",
+        "src/core/lib/iomgr/executor.c",
+        "src/core/lib/iomgr/iocp_windows.c",
+        "src/core/lib/iomgr/iomgr.c",
+        "src/core/lib/iomgr/iomgr_posix.c",
+        "src/core/lib/iomgr/iomgr_windows.c",
+        "src/core/lib/iomgr/load_file.c",
+        "src/core/lib/iomgr/network_status_tracker.c",
+        "src/core/lib/iomgr/polling_entity.c",
+        "src/core/lib/iomgr/pollset_set_windows.c",
+        "src/core/lib/iomgr/pollset_windows.c",
+        "src/core/lib/iomgr/resolve_address_posix.c",
+        "src/core/lib/iomgr/resolve_address_windows.c",
+        "src/core/lib/iomgr/sockaddr_utils.c",
+        "src/core/lib/iomgr/socket_utils_common_posix.c",
+        "src/core/lib/iomgr/socket_utils_linux.c",
+        "src/core/lib/iomgr/socket_utils_posix.c",
+        "src/core/lib/iomgr/socket_windows.c",
+        "src/core/lib/iomgr/tcp_client_posix.c",
+        "src/core/lib/iomgr/tcp_client_windows.c",
+        "src/core/lib/iomgr/tcp_posix.c",
+        "src/core/lib/iomgr/tcp_server_posix.c",
+        "src/core/lib/iomgr/tcp_server_windows.c",
+        "src/core/lib/iomgr/tcp_windows.c",
+        "src/core/lib/iomgr/time_averaged_stats.c",
+        "src/core/lib/iomgr/timer.c",
+        "src/core/lib/iomgr/timer_heap.c",
+        "src/core/lib/iomgr/udp_server.c",
+        "src/core/lib/iomgr/unix_sockets_posix.c",
+        "src/core/lib/iomgr/unix_sockets_posix_noop.c",
+        "src/core/lib/iomgr/wakeup_fd_cv.c",
+        "src/core/lib/iomgr/wakeup_fd_eventfd.c",
+        "src/core/lib/iomgr/wakeup_fd_nospecial.c",
+        "src/core/lib/iomgr/wakeup_fd_pipe.c",
+        "src/core/lib/iomgr/wakeup_fd_posix.c",
+        "src/core/lib/iomgr/workqueue_windows.c",
+        "src/core/lib/json/json.c",
+        "src/core/lib/json/json_reader.c",
+        "src/core/lib/json/json_string.c",
+        "src/core/lib/json/json_writer.c",
+        "src/core/lib/surface/alarm.c",
+        "src/core/lib/surface/api_trace.c",
+        "src/core/lib/surface/byte_buffer.c",
+        "src/core/lib/surface/byte_buffer_reader.c",
+        "src/core/lib/surface/call.c",
+        "src/core/lib/surface/call_details.c",
+        "src/core/lib/surface/call_log_batch.c",
+        "src/core/lib/surface/channel.c",
+        "src/core/lib/surface/channel_init.c",
+        "src/core/lib/surface/channel_ping.c",
+        "src/core/lib/surface/channel_stack_type.c",
+        "src/core/lib/surface/completion_queue.c",
+        "src/core/lib/surface/event_string.c",
+        "src/core/lib/surface/lame_client.c",
+        "src/core/lib/surface/metadata_array.c",
+        "src/core/lib/surface/server.c",
+        "src/core/lib/surface/validate_metadata.c",
+        "src/core/lib/surface/version.c",
+        "src/core/lib/transport/byte_stream.c",
+        "src/core/lib/transport/connectivity_state.c",
+        "src/core/lib/transport/mdstr_hash_table.c",
+        "src/core/lib/transport/metadata.c",
+        "src/core/lib/transport/metadata_batch.c",
+        "src/core/lib/transport/static_metadata.c",
+        "src/core/lib/transport/timeout_encoding.c",
+        "src/core/lib/transport/transport.c",
+        "src/core/lib/transport/transport_op_string.c",
+    ],
+    hdrs = [
+        "src/core/lib/channel/channel_args.h",
+        "src/core/lib/channel/channel_stack.h",
+        "src/core/lib/channel/channel_stack_builder.h",
+        "src/core/lib/channel/compress_filter.h",
+        "src/core/lib/channel/connected_channel.h",
+        "src/core/lib/channel/context.h",
+        "src/core/lib/channel/deadline_filter.h",
+        "src/core/lib/channel/handshaker.h",
+        "src/core/lib/channel/http_client_filter.h",
+        "src/core/lib/channel/http_server_filter.h",
+        "src/core/lib/compression/algorithm_metadata.h",
+        "src/core/lib/compression/message_compress.h",
+        "src/core/lib/debug/trace.h",
+        "src/core/lib/http/format_request.h",
+        "src/core/lib/http/httpcli.h",
+        "src/core/lib/http/parser.h",
+        "src/core/lib/iomgr/closure.h",
+        "src/core/lib/iomgr/combiner.h",
+        "src/core/lib/iomgr/endpoint.h",
+        "src/core/lib/iomgr/endpoint_pair.h",
+        "src/core/lib/iomgr/error.h",
+        "src/core/lib/iomgr/ev_epoll_linux.h",
+        "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
+        "src/core/lib/iomgr/ev_poll_posix.h",
+        "src/core/lib/iomgr/ev_posix.h",
+        "src/core/lib/iomgr/exec_ctx.h",
+        "src/core/lib/iomgr/executor.h",
+        "src/core/lib/iomgr/iocp_windows.h",
+        "src/core/lib/iomgr/iomgr.h",
+        "src/core/lib/iomgr/iomgr_internal.h",
+        "src/core/lib/iomgr/iomgr_posix.h",
+        "src/core/lib/iomgr/load_file.h",
+        "src/core/lib/iomgr/network_status_tracker.h",
+        "src/core/lib/iomgr/polling_entity.h",
+        "src/core/lib/iomgr/pollset.h",
+        "src/core/lib/iomgr/pollset_set.h",
+        "src/core/lib/iomgr/pollset_set_windows.h",
+        "src/core/lib/iomgr/pollset_windows.h",
+        "src/core/lib/iomgr/resolve_address.h",
+        "src/core/lib/iomgr/sockaddr.h",
+        "src/core/lib/iomgr/sockaddr_posix.h",
+        "src/core/lib/iomgr/sockaddr_utils.h",
+        "src/core/lib/iomgr/sockaddr_windows.h",
+        "src/core/lib/iomgr/socket_utils_posix.h",
+        "src/core/lib/iomgr/socket_windows.h",
+        "src/core/lib/iomgr/tcp_client.h",
+        "src/core/lib/iomgr/tcp_posix.h",
+        "src/core/lib/iomgr/tcp_server.h",
+        "src/core/lib/iomgr/tcp_windows.h",
+        "src/core/lib/iomgr/time_averaged_stats.h",
+        "src/core/lib/iomgr/timer.h",
+        "src/core/lib/iomgr/timer_heap.h",
+        "src/core/lib/iomgr/udp_server.h",
+        "src/core/lib/iomgr/unix_sockets_posix.h",
+        "src/core/lib/iomgr/wakeup_fd_cv.h",
+        "src/core/lib/iomgr/wakeup_fd_pipe.h",
+        "src/core/lib/iomgr/wakeup_fd_posix.h",
+        "src/core/lib/iomgr/workqueue.h",
+        "src/core/lib/iomgr/workqueue_windows.h",
+        "src/core/lib/json/json.h",
+        "src/core/lib/json/json_common.h",
+        "src/core/lib/json/json_reader.h",
+        "src/core/lib/json/json_writer.h",
+        "src/core/lib/surface/api_trace.h",
+        "src/core/lib/surface/call.h",
+        "src/core/lib/surface/call_test_only.h",
+        "src/core/lib/surface/channel.h",
+        "src/core/lib/surface/channel_init.h",
+        "src/core/lib/surface/channel_stack_type.h",
+        "src/core/lib/surface/completion_queue.h",
+        "src/core/lib/surface/event_string.h",
+        "src/core/lib/surface/init.h",
+        "src/core/lib/surface/lame_client.h",
+        "src/core/lib/surface/server.h",
+        "src/core/lib/transport/byte_stream.h",
+        "src/core/lib/transport/connectivity_state.h",
+        "src/core/lib/transport/mdstr_hash_table.h",
+        "src/core/lib/transport/metadata.h",
+        "src/core/lib/transport/metadata_batch.h",
+        "src/core/lib/transport/static_metadata.h",
+        "src/core/lib/transport/timeout_encoding.h",
+        "src/core/lib/transport/transport.h",
+        "src/core/lib/transport/transport_impl.h",
+    ],
+    external_deps = [
+        "zlib",
+    ],
+    language = "c",
+    public_hdrs = [
+        "include/grpc/byte_buffer.h",
+        "include/grpc/byte_buffer_reader.h",
+        "include/grpc/compression.h",
+        "include/grpc/grpc.h",
+        "include/grpc/grpc_posix.h",
+        "include/grpc/grpc_security_constants.h",
+        "include/grpc/status.h",
+    ],
+    deps = [
+        "gpr_base",
+        "grpc_codegen",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_client_config",
-  srcs = [
-    "src/core/ext/client_config/channel_connectivity.c",
-    "src/core/ext/client_config/client_channel.c",
-    "src/core/ext/client_config/client_channel_factory.c",
-    "src/core/ext/client_config/client_config_plugin.c",
-    "src/core/ext/client_config/connector.c",
-    "src/core/ext/client_config/default_initial_connect_string.c",
-    "src/core/ext/client_config/http_connect_handshaker.c",
-    "src/core/ext/client_config/initial_connect_string.c",
-    "src/core/ext/client_config/lb_policy.c",
-    "src/core/ext/client_config/lb_policy_factory.c",
-    "src/core/ext/client_config/lb_policy_registry.c",
-    "src/core/ext/client_config/message_size_filter.c",
-    "src/core/ext/client_config/method_config.c",
-    "src/core/ext/client_config/parse_address.c",
-    "src/core/ext/client_config/resolver.c",
-    "src/core/ext/client_config/resolver_factory.c",
-    "src/core/ext/client_config/resolver_registry.c",
-    "src/core/ext/client_config/resolver_result.c",
-    "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_index.c",
-    "src/core/ext/client_config/uri_parser.c",
-  ],
-  hdrs = [
-    "src/core/ext/client_config/client_channel.h",
-    "src/core/ext/client_config/client_channel_factory.h",
-    "src/core/ext/client_config/connector.h",
-    "src/core/ext/client_config/http_connect_handshaker.h",
-    "src/core/ext/client_config/initial_connect_string.h",
-    "src/core/ext/client_config/lb_policy.h",
-    "src/core/ext/client_config/lb_policy_factory.h",
-    "src/core/ext/client_config/lb_policy_registry.h",
-    "src/core/ext/client_config/message_size_filter.h",
-    "src/core/ext/client_config/method_config.h",
-    "src/core/ext/client_config/parse_address.h",
-    "src/core/ext/client_config/resolver.h",
-    "src/core/ext/client_config/resolver_factory.h",
-    "src/core/ext/client_config/resolver_registry.h",
-    "src/core/ext/client_config/resolver_result.h",
-    "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_index.h",
-    "src/core/ext/client_config/uri_parser.h",
-  ],
-  deps = [
-    "grpc_base",
-  ],
-  language = "c",
+    name = "grpc_client_config",
+    srcs = [
+        "src/core/ext/client_config/channel_connectivity.c",
+        "src/core/ext/client_config/client_channel.c",
+        "src/core/ext/client_config/client_channel_factory.c",
+        "src/core/ext/client_config/client_config_plugin.c",
+        "src/core/ext/client_config/connector.c",
+        "src/core/ext/client_config/default_initial_connect_string.c",
+        "src/core/ext/client_config/http_connect_handshaker.c",
+        "src/core/ext/client_config/initial_connect_string.c",
+        "src/core/ext/client_config/lb_policy.c",
+        "src/core/ext/client_config/lb_policy_factory.c",
+        "src/core/ext/client_config/lb_policy_registry.c",
+        "src/core/ext/client_config/message_size_filter.c",
+        "src/core/ext/client_config/method_config.c",
+        "src/core/ext/client_config/parse_address.c",
+        "src/core/ext/client_config/resolver.c",
+        "src/core/ext/client_config/resolver_factory.c",
+        "src/core/ext/client_config/resolver_registry.c",
+        "src/core/ext/client_config/resolver_result.c",
+        "src/core/ext/client_config/subchannel.c",
+        "src/core/ext/client_config/subchannel_index.c",
+        "src/core/ext/client_config/uri_parser.c",
+    ],
+    hdrs = [
+        "src/core/ext/client_config/client_channel.h",
+        "src/core/ext/client_config/client_channel_factory.h",
+        "src/core/ext/client_config/connector.h",
+        "src/core/ext/client_config/http_connect_handshaker.h",
+        "src/core/ext/client_config/initial_connect_string.h",
+        "src/core/ext/client_config/lb_policy.h",
+        "src/core/ext/client_config/lb_policy_factory.h",
+        "src/core/ext/client_config/lb_policy_registry.h",
+        "src/core/ext/client_config/message_size_filter.h",
+        "src/core/ext/client_config/method_config.h",
+        "src/core/ext/client_config/parse_address.h",
+        "src/core/ext/client_config/resolver.h",
+        "src/core/ext/client_config/resolver_factory.h",
+        "src/core/ext/client_config/resolver_registry.h",
+        "src/core/ext/client_config/resolver_result.h",
+        "src/core/ext/client_config/subchannel.h",
+        "src/core/ext/client_config/subchannel_index.h",
+        "src/core/ext/client_config/uri_parser.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_codegen",
-  public_hdrs = [
-    "include/grpc/impl/codegen/byte_buffer_reader.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-  ],
-  deps = [
-    "gpr_codegen",
-  ],
-  language = "c",
+    name = "grpc_codegen",
+    language = "c",
+    public_hdrs = [
+        "include/grpc/impl/codegen/byte_buffer_reader.h",
+        "include/grpc/impl/codegen/compression_types.h",
+        "include/grpc/impl/codegen/connectivity_state.h",
+        "include/grpc/impl/codegen/grpc_types.h",
+        "include/grpc/impl/codegen/propagation_bits.h",
+        "include/grpc/impl/codegen/status.h",
+    ],
+    deps = [
+        "gpr_codegen",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_lb_policy_grpclb",
-  srcs = [
-    "src/core/ext/lb_policy/grpclb/grpclb.c",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
-  ],
-  hdrs = [
-    "src/core/ext/lb_policy/grpclb/grpclb.h",
-    "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
-    "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
-  ],
-  external_deps = [
-    "nanopb",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_lb_policy_grpclb",
+    srcs = [
+        "src/core/ext/lb_policy/grpclb/grpclb.c",
+        "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
+        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
+    ],
+    hdrs = [
+        "src/core/ext/lb_policy/grpclb/grpclb.h",
+        "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
+        "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+    ],
+    external_deps = [
+        "nanopb",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_lb_policy_pick_first",
-  srcs = [
-    "src/core/ext/lb_policy/pick_first/pick_first.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_lb_policy_pick_first",
+    srcs = [
+        "src/core/ext/lb_policy/pick_first/pick_first.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_lb_policy_round_robin",
-  srcs = [
-    "src/core/ext/lb_policy/round_robin/round_robin.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_lb_policy_round_robin",
+    srcs = [
+        "src/core/ext/lb_policy/round_robin/round_robin.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_load_reporting",
-  srcs = [
-    "src/core/ext/load_reporting/load_reporting.c",
-    "src/core/ext/load_reporting/load_reporting_filter.c",
-  ],
-  hdrs = [
-    "src/core/ext/load_reporting/load_reporting.h",
-    "src/core/ext/load_reporting/load_reporting_filter.h",
-  ],
-  deps = [
-    "grpc_base",
-  ],
-  language = "c",
+    name = "grpc_load_reporting",
+    srcs = [
+        "src/core/ext/load_reporting/load_reporting.c",
+        "src/core/ext/load_reporting/load_reporting_filter.c",
+    ],
+    hdrs = [
+        "src/core/ext/load_reporting/load_reporting.h",
+        "src/core/ext/load_reporting/load_reporting_filter.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_resolver_dns_native",
-  srcs = [
-    "src/core/ext/resolver/dns/native/dns_resolver.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_resolver_dns_native",
+    srcs = [
+        "src/core/ext/resolver/dns/native/dns_resolver.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_resolver_sockaddr",
-  srcs = [
-    "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_resolver_sockaddr",
+    srcs = [
+        "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_secure",
-  srcs = [
-    "src/core/lib/http/httpcli_security_connector.c",
-    "src/core/lib/security/context/security_context.c",
-    "src/core/lib/security/credentials/composite/composite_credentials.c",
-    "src/core/lib/security/credentials/credentials.c",
-    "src/core/lib/security/credentials/credentials_metadata.c",
-    "src/core/lib/security/credentials/fake/fake_credentials.c",
-    "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_windows.c",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
-    "src/core/lib/security/credentials/iam/iam_credentials.c",
-    "src/core/lib/security/credentials/jwt/json_token.c",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
-    "src/core/lib/security/transport/client_auth_filter.c",
-    "src/core/lib/security/transport/handshake.c",
-    "src/core/lib/security/transport/secure_endpoint.c",
-    "src/core/lib/security/transport/security_connector.c",
-    "src/core/lib/security/transport/server_auth_filter.c",
-    "src/core/lib/security/transport/tsi_error.c",
-    "src/core/lib/security/util/b64.c",
-    "src/core/lib/security/util/json_util.c",
-    "src/core/lib/surface/init_secure.c",
-  ],
-  hdrs = [
-    "src/core/lib/security/context/security_context.h",
-    "src/core/lib/security/credentials/composite/composite_credentials.h",
-    "src/core/lib/security/credentials/credentials.h",
-    "src/core/lib/security/credentials/fake/fake_credentials.h",
-    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
-    "src/core/lib/security/credentials/iam/iam_credentials.h",
-    "src/core/lib/security/credentials/jwt/json_token.h",
-    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
-    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
-    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
-    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
-    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
-    "src/core/lib/security/transport/auth_filters.h",
-    "src/core/lib/security/transport/handshake.h",
-    "src/core/lib/security/transport/secure_endpoint.h",
-    "src/core/lib/security/transport/security_connector.h",
-    "src/core/lib/security/transport/tsi_error.h",
-    "src/core/lib/security/util/b64.h",
-    "src/core/lib/security/util/json_util.h",
-  ],
-  public_hdrs = [
-    "include/grpc/grpc_security.h",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_chttp2_alpn",
-    "tsi",
-  ],
-  language = "c",
+    name = "grpc_secure",
+    srcs = [
+        "src/core/lib/http/httpcli_security_connector.c",
+        "src/core/lib/security/context/security_context.c",
+        "src/core/lib/security/credentials/composite/composite_credentials.c",
+        "src/core/lib/security/credentials/credentials.c",
+        "src/core/lib/security/credentials/credentials_metadata.c",
+        "src/core/lib/security/credentials/fake/fake_credentials.c",
+        "src/core/lib/security/credentials/google_default/credentials_posix.c",
+        "src/core/lib/security/credentials/google_default/credentials_windows.c",
+        "src/core/lib/security/credentials/google_default/google_default_credentials.c",
+        "src/core/lib/security/credentials/iam/iam_credentials.c",
+        "src/core/lib/security/credentials/jwt/json_token.c",
+        "src/core/lib/security/credentials/jwt/jwt_credentials.c",
+        "src/core/lib/security/credentials/jwt/jwt_verifier.c",
+        "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
+        "src/core/lib/security/credentials/plugin/plugin_credentials.c",
+        "src/core/lib/security/credentials/ssl/ssl_credentials.c",
+        "src/core/lib/security/transport/client_auth_filter.c",
+        "src/core/lib/security/transport/handshake.c",
+        "src/core/lib/security/transport/secure_endpoint.c",
+        "src/core/lib/security/transport/security_connector.c",
+        "src/core/lib/security/transport/server_auth_filter.c",
+        "src/core/lib/security/transport/tsi_error.c",
+        "src/core/lib/security/util/b64.c",
+        "src/core/lib/security/util/json_util.c",
+        "src/core/lib/surface/init_secure.c",
+    ],
+    hdrs = [
+        "src/core/lib/security/context/security_context.h",
+        "src/core/lib/security/credentials/composite/composite_credentials.h",
+        "src/core/lib/security/credentials/credentials.h",
+        "src/core/lib/security/credentials/fake/fake_credentials.h",
+        "src/core/lib/security/credentials/google_default/google_default_credentials.h",
+        "src/core/lib/security/credentials/iam/iam_credentials.h",
+        "src/core/lib/security/credentials/jwt/json_token.h",
+        "src/core/lib/security/credentials/jwt/jwt_credentials.h",
+        "src/core/lib/security/credentials/jwt/jwt_verifier.h",
+        "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
+        "src/core/lib/security/credentials/plugin/plugin_credentials.h",
+        "src/core/lib/security/credentials/ssl/ssl_credentials.h",
+        "src/core/lib/security/transport/auth_filters.h",
+        "src/core/lib/security/transport/handshake.h",
+        "src/core/lib/security/transport/secure_endpoint.h",
+        "src/core/lib/security/transport/security_connector.h",
+        "src/core/lib/security/transport/tsi_error.h",
+        "src/core/lib/security/util/b64.h",
+        "src/core/lib/security/util/json_util.h",
+    ],
+    language = "c",
+    public_hdrs = [
+        "include/grpc/grpc_security.h",
+    ],
+    deps = [
+        "grpc_base",
+        "grpc_transport_chttp2_alpn",
+        "tsi",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2",
-  srcs = [
-    "src/core/ext/transport/chttp2/transport/bin_decoder.c",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
-    "src/core/ext/transport/chttp2/transport/frame_data.c",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
-    "src/core/ext/transport/chttp2/transport/frame_ping.c",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
-    "src/core/ext/transport/chttp2/transport/frame_settings.c",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
-    "src/core/ext/transport/chttp2/transport/hpack_table.c",
-    "src/core/ext/transport/chttp2/transport/huffsyms.c",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
-    "src/core/ext/transport/chttp2/transport/parsing.c",
-    "src/core/ext/transport/chttp2/transport/status_conversion.c",
-    "src/core/ext/transport/chttp2/transport/stream_lists.c",
-    "src/core/ext/transport/chttp2/transport/stream_map.c",
-    "src/core/ext/transport/chttp2/transport/varint.c",
-    "src/core/ext/transport/chttp2/transport/writing.c",
-  ],
-  hdrs = [
-    "src/core/ext/transport/chttp2/transport/bin_decoder.h",
-    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
-    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
-    "src/core/ext/transport/chttp2/transport/frame.h",
-    "src/core/ext/transport/chttp2/transport/frame_data.h",
-    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
-    "src/core/ext/transport/chttp2/transport/frame_ping.h",
-    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
-    "src/core/ext/transport/chttp2/transport/frame_settings.h",
-    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
-    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
-    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
-    "src/core/ext/transport/chttp2/transport/hpack_table.h",
-    "src/core/ext/transport/chttp2/transport/http2_errors.h",
-    "src/core/ext/transport/chttp2/transport/huffsyms.h",
-    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
-    "src/core/ext/transport/chttp2/transport/internal.h",
-    "src/core/ext/transport/chttp2/transport/status_conversion.h",
-    "src/core/ext/transport/chttp2/transport/stream_map.h",
-    "src/core/ext/transport/chttp2/transport/varint.h",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_chttp2_alpn",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2",
+    srcs = [
+        "src/core/ext/transport/chttp2/transport/bin_decoder.c",
+        "src/core/ext/transport/chttp2/transport/bin_encoder.c",
+        "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
+        "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
+        "src/core/ext/transport/chttp2/transport/frame_data.c",
+        "src/core/ext/transport/chttp2/transport/frame_goaway.c",
+        "src/core/ext/transport/chttp2/transport/frame_ping.c",
+        "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
+        "src/core/ext/transport/chttp2/transport/frame_settings.c",
+        "src/core/ext/transport/chttp2/transport/frame_window_update.c",
+        "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
+        "src/core/ext/transport/chttp2/transport/hpack_parser.c",
+        "src/core/ext/transport/chttp2/transport/hpack_table.c",
+        "src/core/ext/transport/chttp2/transport/huffsyms.c",
+        "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
+        "src/core/ext/transport/chttp2/transport/parsing.c",
+        "src/core/ext/transport/chttp2/transport/status_conversion.c",
+        "src/core/ext/transport/chttp2/transport/stream_lists.c",
+        "src/core/ext/transport/chttp2/transport/stream_map.c",
+        "src/core/ext/transport/chttp2/transport/varint.c",
+        "src/core/ext/transport/chttp2/transport/writing.c",
+    ],
+    hdrs = [
+        "src/core/ext/transport/chttp2/transport/bin_decoder.h",
+        "src/core/ext/transport/chttp2/transport/bin_encoder.h",
+        "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+        "src/core/ext/transport/chttp2/transport/frame.h",
+        "src/core/ext/transport/chttp2/transport/frame_data.h",
+        "src/core/ext/transport/chttp2/transport/frame_goaway.h",
+        "src/core/ext/transport/chttp2/transport/frame_ping.h",
+        "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
+        "src/core/ext/transport/chttp2/transport/frame_settings.h",
+        "src/core/ext/transport/chttp2/transport/frame_window_update.h",
+        "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+        "src/core/ext/transport/chttp2/transport/hpack_parser.h",
+        "src/core/ext/transport/chttp2/transport/hpack_table.h",
+        "src/core/ext/transport/chttp2/transport/http2_errors.h",
+        "src/core/ext/transport/chttp2/transport/huffsyms.h",
+        "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+        "src/core/ext/transport/chttp2/transport/internal.h",
+        "src/core/ext/transport/chttp2/transport/status_conversion.h",
+        "src/core/ext/transport/chttp2/transport/stream_map.h",
+        "src/core/ext/transport/chttp2/transport/varint.h",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_transport_chttp2_alpn",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2_alpn",
-  srcs = [
-    "src/core/ext/transport/chttp2/alpn/alpn.c",
-  ],
-  hdrs = [
-    "src/core/ext/transport/chttp2/alpn/alpn.h",
-  ],
-  deps = [
-    "gpr",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2_alpn",
+    srcs = [
+        "src/core/ext/transport/chttp2/alpn/alpn.c",
+    ],
+    hdrs = [
+        "src/core/ext/transport/chttp2/alpn/alpn.h",
+    ],
+    language = "c",
+    deps = [
+        "gpr",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2_client_insecure",
-  srcs = [
-    "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
-  ],
-  deps = [
-    "grpc_transport_chttp2",
-    "grpc_base",
-    "grpc_client_config",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2_client_insecure",
+    srcs = [
+        "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+        "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+        "grpc_transport_chttp2",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2_client_secure",
-  srcs = [
-    "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
-  ],
-  deps = [
-    "grpc_transport_chttp2",
-    "grpc_base",
-    "grpc_client_config",
-    "grpc_secure",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2_client_secure",
+    srcs = [
+        "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_client_config",
+        "grpc_secure",
+        "grpc_transport_chttp2",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2_server_insecure",
-  srcs = [
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
-    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
-  ],
-  deps = [
-    "grpc_transport_chttp2",
-    "grpc_base",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2_server_insecure",
+    srcs = [
+        "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
+        "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_transport_chttp2",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_chttp2_server_secure",
-  srcs = [
-    "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c",
-  ],
-  deps = [
-    "grpc_transport_chttp2",
-    "grpc_base",
-    "grpc_secure",
-  ],
-  language = "c",
+    name = "grpc_transport_chttp2_server_secure",
+    srcs = [
+        "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c",
+    ],
+    language = "c",
+    deps = [
+        "grpc_base",
+        "grpc_secure",
+        "grpc_transport_chttp2",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc_transport_cronet_client_secure",
-  srcs = [
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
-  ],
-  hdrs = [
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
-  ],
-  public_hdrs = [
-    "include/grpc/grpc_cronet.h",
-    "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
-  ],
-  deps = [
-    "grpc_base",
-    "grpc_transport_chttp2",
-  ],
-  language = "c",
+    name = "grpc_transport_cronet_client_secure",
+    srcs = [
+        "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+        "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+        "src/core/ext/transport/cronet/transport/cronet_transport.c",
+    ],
+    hdrs = [
+        "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
+    ],
+    language = "c",
+    public_hdrs = [
+        "include/grpc/grpc_cronet.h",
+        "include/grpc/grpc_security.h",
+        "include/grpc/grpc_security_constants.h",
+    ],
+    deps = [
+        "grpc_base",
+        "grpc_transport_chttp2",
+    ],
 )
 
 grpc_cc_library(
-  name = "tsi",
-  srcs = [
-    "src/core/lib/tsi/fake_transport_security.c",
-    "src/core/lib/tsi/ssl_transport_security.c",
-    "src/core/lib/tsi/transport_security.c",
-  ],
-  hdrs = [
-    "src/core/lib/tsi/fake_transport_security.h",
-    "src/core/lib/tsi/ssl_transport_security.h",
-    "src/core/lib/tsi/ssl_types.h",
-    "src/core/lib/tsi/transport_security.h",
-    "src/core/lib/tsi/transport_security_interface.h",
-  ],
-  external_deps = [
-    "libssl",
-  ],
-  deps = [
-    "gpr",
-  ],
-  language = "c",
+    name = "tsi",
+    srcs = [
+        "src/core/lib/tsi/fake_transport_security.c",
+        "src/core/lib/tsi/ssl_transport_security.c",
+        "src/core/lib/tsi/transport_security.c",
+    ],
+    hdrs = [
+        "src/core/lib/tsi/fake_transport_security.h",
+        "src/core/lib/tsi/ssl_transport_security.h",
+        "src/core/lib/tsi/ssl_types.h",
+        "src/core/lib/tsi/transport_security.h",
+        "src/core/lib/tsi/transport_security_interface.h",
+    ],
+    external_deps = [
+        "libssl",
+    ],
+    language = "c",
+    deps = [
+        "gpr",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_base",
-  srcs = [
-    "src/cpp/client/channel_cc.cc",
-    "src/cpp/client/client_context.cc",
-    "src/cpp/client/create_channel.cc",
-    "src/cpp/client/create_channel_internal.cc",
-    "src/cpp/client/create_channel_posix.cc",
-    "src/cpp/client/credentials_cc.cc",
-    "src/cpp/client/generic_stub.cc",
-    "src/cpp/common/channel_arguments.cc",
-    "src/cpp/common/channel_filter.cc",
-    "src/cpp/common/completion_queue_cc.cc",
-    "src/cpp/common/core_codegen.cc",
-    "src/cpp/common/rpc_method.cc",
-    "src/cpp/server/async_generic_service.cc",
-    "src/cpp/server/create_default_thread_pool.cc",
-    "src/cpp/server/dynamic_thread_pool.cc",
-    "src/cpp/server/server_builder.cc",
-    "src/cpp/server/server_cc.cc",
-    "src/cpp/server/server_context.cc",
-    "src/cpp/server/server_credentials.cc",
-    "src/cpp/server/server_posix.cc",
-    "src/cpp/util/byte_buffer_cc.cc",
-    "src/cpp/util/slice_cc.cc",
-    "src/cpp/util/status.cc",
-    "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time_cc.cc",
-  ],
-  hdrs = [
-    "src/cpp/client/create_channel_internal.h",
-    "src/cpp/common/channel_filter.h",
-    "src/cpp/server/dynamic_thread_pool.h",
-    "src/cpp/server/thread_pool_interface.h",
-  ],
-  public_hdrs = [
-    "include/grpc++/alarm.h",
-    "include/grpc++/channel.h",
-    "include/grpc++/client_context.h",
-    "include/grpc++/completion_queue.h",
-    "include/grpc++/create_channel.h",
-    "include/grpc++/create_channel_posix.h",
-    "include/grpc++/generic/async_generic_service.h",
-    "include/grpc++/generic/generic_stub.h",
-    "include/grpc++/grpc++.h",
-    "include/grpc++/impl/call.h",
-    "include/grpc++/impl/client_unary_call.h",
-    "include/grpc++/impl/codegen/core_codegen.h",
-    "include/grpc++/impl/grpc_library.h",
-    "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/rpc_method.h",
-    "include/grpc++/impl/rpc_service_method.h",
-    "include/grpc++/impl/serialization_traits.h",
-    "include/grpc++/impl/server_builder_option.h",
-    "include/grpc++/impl/server_builder_plugin.h",
-    "include/grpc++/impl/server_initializer.h",
-    "include/grpc++/impl/service_type.h",
-    "include/grpc++/impl/sync.h",
-    "include/grpc++/impl/sync_cxx11.h",
-    "include/grpc++/impl/sync_no_cxx11.h",
-    "include/grpc++/impl/thd.h",
-    "include/grpc++/impl/thd_cxx11.h",
-    "include/grpc++/impl/thd_no_cxx11.h",
-    "include/grpc++/security/auth_context.h",
-    "include/grpc++/security/auth_metadata_processor.h",
-    "include/grpc++/security/credentials.h",
-    "include/grpc++/security/server_credentials.h",
-    "include/grpc++/server.h",
-    "include/grpc++/server_builder.h",
-    "include/grpc++/server_context.h",
-    "include/grpc++/server_posix.h",
-    "include/grpc++/support/async_stream.h",
-    "include/grpc++/support/async_unary_call.h",
-    "include/grpc++/support/byte_buffer.h",
-    "include/grpc++/support/channel_arguments.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/slice.h",
-    "include/grpc++/support/status.h",
-    "include/grpc++/support/status_code_enum.h",
-    "include/grpc++/support/string_ref.h",
-    "include/grpc++/support/stub_options.h",
-    "include/grpc++/support/sync_stream.h",
-    "include/grpc++/support/time.h",
-  ],
-  deps = [
-    "grpc",
-    "grpc++_codegen_base",
-  ],
-  language = "c++",
+    name = "grpc++_base",
+    srcs = [
+        "src/cpp/client/channel_cc.cc",
+        "src/cpp/client/client_context.cc",
+        "src/cpp/client/create_channel.cc",
+        "src/cpp/client/create_channel_internal.cc",
+        "src/cpp/client/create_channel_posix.cc",
+        "src/cpp/client/credentials_cc.cc",
+        "src/cpp/client/generic_stub.cc",
+        "src/cpp/common/channel_arguments.cc",
+        "src/cpp/common/channel_filter.cc",
+        "src/cpp/common/completion_queue_cc.cc",
+        "src/cpp/common/core_codegen.cc",
+        "src/cpp/common/rpc_method.cc",
+        "src/cpp/server/async_generic_service.cc",
+        "src/cpp/server/create_default_thread_pool.cc",
+        "src/cpp/server/dynamic_thread_pool.cc",
+        "src/cpp/server/server_builder.cc",
+        "src/cpp/server/server_cc.cc",
+        "src/cpp/server/server_context.cc",
+        "src/cpp/server/server_credentials.cc",
+        "src/cpp/server/server_posix.cc",
+        "src/cpp/util/byte_buffer_cc.cc",
+        "src/cpp/util/slice_cc.cc",
+        "src/cpp/util/status.cc",
+        "src/cpp/util/string_ref.cc",
+        "src/cpp/util/time_cc.cc",
+    ],
+    hdrs = [
+        "src/cpp/client/create_channel_internal.h",
+        "src/cpp/common/channel_filter.h",
+        "src/cpp/server/dynamic_thread_pool.h",
+        "src/cpp/server/thread_pool_interface.h",
+    ],
+    language = "c++",
+    public_hdrs = [
+        "include/grpc++/alarm.h",
+        "include/grpc++/channel.h",
+        "include/grpc++/client_context.h",
+        "include/grpc++/completion_queue.h",
+        "include/grpc++/create_channel.h",
+        "include/grpc++/create_channel_posix.h",
+        "include/grpc++/generic/async_generic_service.h",
+        "include/grpc++/generic/generic_stub.h",
+        "include/grpc++/grpc++.h",
+        "include/grpc++/impl/call.h",
+        "include/grpc++/impl/client_unary_call.h",
+        "include/grpc++/impl/codegen/core_codegen.h",
+        "include/grpc++/impl/grpc_library.h",
+        "include/grpc++/impl/method_handler_impl.h",
+        "include/grpc++/impl/rpc_method.h",
+        "include/grpc++/impl/rpc_service_method.h",
+        "include/grpc++/impl/serialization_traits.h",
+        "include/grpc++/impl/server_builder_option.h",
+        "include/grpc++/impl/server_builder_plugin.h",
+        "include/grpc++/impl/server_initializer.h",
+        "include/grpc++/impl/service_type.h",
+        "include/grpc++/impl/sync.h",
+        "include/grpc++/impl/sync_cxx11.h",
+        "include/grpc++/impl/sync_no_cxx11.h",
+        "include/grpc++/impl/thd.h",
+        "include/grpc++/impl/thd_cxx11.h",
+        "include/grpc++/impl/thd_no_cxx11.h",
+        "include/grpc++/security/auth_context.h",
+        "include/grpc++/security/auth_metadata_processor.h",
+        "include/grpc++/security/credentials.h",
+        "include/grpc++/security/server_credentials.h",
+        "include/grpc++/server.h",
+        "include/grpc++/server_builder.h",
+        "include/grpc++/server_context.h",
+        "include/grpc++/server_posix.h",
+        "include/grpc++/support/async_stream.h",
+        "include/grpc++/support/async_unary_call.h",
+        "include/grpc++/support/byte_buffer.h",
+        "include/grpc++/support/channel_arguments.h",
+        "include/grpc++/support/config.h",
+        "include/grpc++/support/slice.h",
+        "include/grpc++/support/status.h",
+        "include/grpc++/support/status_code_enum.h",
+        "include/grpc++/support/string_ref.h",
+        "include/grpc++/support/stub_options.h",
+        "include/grpc++/support/sync_stream.h",
+        "include/grpc++/support/time.h",
+    ],
+    deps = [
+        "grpc",
+        "grpc++_codegen_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_codegen_base",
-  public_hdrs = [
-    "include/grpc++/impl/codegen/async_stream.h",
-    "include/grpc++/impl/codegen/async_unary_call.h",
-    "include/grpc++/impl/codegen/call.h",
-    "include/grpc++/impl/codegen/call_hook.h",
-    "include/grpc++/impl/codegen/channel_interface.h",
-    "include/grpc++/impl/codegen/client_context.h",
-    "include/grpc++/impl/codegen/client_unary_call.h",
-    "include/grpc++/impl/codegen/completion_queue.h",
-    "include/grpc++/impl/codegen/completion_queue_tag.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/core_codegen_interface.h",
-    "include/grpc++/impl/codegen/create_auth_context.h",
-    "include/grpc++/impl/codegen/grpc_library.h",
-    "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/rpc_method.h",
-    "include/grpc++/impl/codegen/rpc_service_method.h",
-    "include/grpc++/impl/codegen/security/auth_context.h",
-    "include/grpc++/impl/codegen/serialization_traits.h",
-    "include/grpc++/impl/codegen/server_context.h",
-    "include/grpc++/impl/codegen/server_interface.h",
-    "include/grpc++/impl/codegen/service_type.h",
-    "include/grpc++/impl/codegen/status.h",
-    "include/grpc++/impl/codegen/status_code_enum.h",
-    "include/grpc++/impl/codegen/status_helper.h",
-    "include/grpc++/impl/codegen/string_ref.h",
-    "include/grpc++/impl/codegen/stub_options.h",
-    "include/grpc++/impl/codegen/sync.h",
-    "include/grpc++/impl/codegen/sync_cxx11.h",
-    "include/grpc++/impl/codegen/sync_no_cxx11.h",
-    "include/grpc++/impl/codegen/sync_stream.h",
-    "include/grpc++/impl/codegen/time.h",
-  ],
-  deps = [
-    "grpc_codegen",
-  ],
-  language = "c++",
+    name = "grpc++_codegen_base",
+    language = "c++",
+    public_hdrs = [
+        "include/grpc++/impl/codegen/async_stream.h",
+        "include/grpc++/impl/codegen/async_unary_call.h",
+        "include/grpc++/impl/codegen/call.h",
+        "include/grpc++/impl/codegen/call_hook.h",
+        "include/grpc++/impl/codegen/channel_interface.h",
+        "include/grpc++/impl/codegen/client_context.h",
+        "include/grpc++/impl/codegen/client_unary_call.h",
+        "include/grpc++/impl/codegen/completion_queue.h",
+        "include/grpc++/impl/codegen/completion_queue_tag.h",
+        "include/grpc++/impl/codegen/config.h",
+        "include/grpc++/impl/codegen/core_codegen_interface.h",
+        "include/grpc++/impl/codegen/create_auth_context.h",
+        "include/grpc++/impl/codegen/grpc_library.h",
+        "include/grpc++/impl/codegen/method_handler_impl.h",
+        "include/grpc++/impl/codegen/rpc_method.h",
+        "include/grpc++/impl/codegen/rpc_service_method.h",
+        "include/grpc++/impl/codegen/security/auth_context.h",
+        "include/grpc++/impl/codegen/serialization_traits.h",
+        "include/grpc++/impl/codegen/server_context.h",
+        "include/grpc++/impl/codegen/server_interface.h",
+        "include/grpc++/impl/codegen/service_type.h",
+        "include/grpc++/impl/codegen/status.h",
+        "include/grpc++/impl/codegen/status_code_enum.h",
+        "include/grpc++/impl/codegen/status_helper.h",
+        "include/grpc++/impl/codegen/string_ref.h",
+        "include/grpc++/impl/codegen/stub_options.h",
+        "include/grpc++/impl/codegen/sync.h",
+        "include/grpc++/impl/codegen/sync_cxx11.h",
+        "include/grpc++/impl/codegen/sync_no_cxx11.h",
+        "include/grpc++/impl/codegen/sync_stream.h",
+        "include/grpc++/impl/codegen/time.h",
+    ],
+    deps = [
+        "grpc_codegen",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_codegen_base_src",
-  srcs = [
-    "src/cpp/codegen/codegen_init.cc",
-  ],
-  deps = [
-    "grpc++_codegen_base",
-  ],
-  language = "c++",
+    name = "grpc++_codegen_base_src",
+    srcs = [
+        "src/cpp/codegen/codegen_init.cc",
+    ],
+    language = "c++",
+    deps = [
+        "grpc++_codegen_base",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_codegen_proto",
-  public_hdrs = [
-    "include/grpc++/impl/codegen/proto_utils.h",
-  ],
-  deps = [
-    "grpc++_codegen_base",
-    "grpc++_config_proto",
-  ],
-  language = "c++",
+    name = "grpc++_codegen_proto",
+    language = "c++",
+    public_hdrs = [
+        "include/grpc++/impl/codegen/proto_utils.h",
+    ],
+    deps = [
+        "grpc++_codegen_base",
+        "grpc++_config_proto",
+    ],
 )
 
 grpc_cc_library(
-  name = "grpc++_config_proto",
-  public_hdrs = [
-    "include/grpc++/impl/codegen/config_protobuf.h",
-  ],
-  language = "c++",
+    name = "grpc++_config_proto",
+    language = "c++",
+    public_hdrs = [
+        "include/grpc++/impl/codegen/config_protobuf.h",
+    ],
 )
 
 grpc_cc_library(
-  name = "thrift_util",
-  public_hdrs = [
-    "include/grpc++/impl/codegen/thrift_serializer.h",
-    "include/grpc++/impl/codegen/thrift_utils.h",
-  ],
-  deps = [
-    "grpc++_codegen_base",
-  ],
-  language = "c++",
+    name = "thrift_util",
+    language = "c++",
+    public_hdrs = [
+        "include/grpc++/impl/codegen/thrift_serializer.h",
+        "include/grpc++/impl/codegen/thrift_utils.h",
+    ],
+    deps = [
+        "grpc++_codegen_base",
+    ],
 )
-
diff --git a/third_party/zlib.BUILD b/third_party/zlib.BUILD
index 323c2868a8..7879a81c68 100644
--- a/third_party/zlib.BUILD
+++ b/third_party/zlib.BUILD
@@ -1,37 +1,36 @@
 cc_library(
-  name = "z",
-  linkstatic = 1,
-  srcs = [
-    'adler32.c',
-    'compress.c',
-    'crc32.c',
-    'deflate.c',
-    'infback.c',
-    'inffast.c',
-    'inflate.c',
-    'inftrees.c',
-    'trees.c',
-    'uncompr.c',
-    'zutil.c',
-  ],
-  hdrs = [
-    'crc32.h',
-    'deflate.h',
-    'gzguts.h',
-    'inffast.h',
-    'inffixed.h',
-    'inflate.h',
-    'inftrees.h',
-    'trees.h',
-    'zconf.h',
-    'zlib.h',
-    'zutil.h',
-  ],
-  includes = [
-      'include',
-  ],
-  visibility = [
-    "//visibility:public",
-  ],
+    name = "z",
+    srcs = [
+        "adler32.c",
+        "compress.c",
+        "crc32.c",
+        "deflate.c",
+        "infback.c",
+        "inffast.c",
+        "inflate.c",
+        "inftrees.c",
+        "trees.c",
+        "uncompr.c",
+        "zutil.c",
+    ],
+    hdrs = [
+        "crc32.h",
+        "deflate.h",
+        "gzguts.h",
+        "inffast.h",
+        "inffixed.h",
+        "inflate.h",
+        "inftrees.h",
+        "trees.h",
+        "zconf.h",
+        "zlib.h",
+        "zutil.h",
+    ],
+    includes = [
+        "include",
+    ],
+    linkstatic = 1,
+    visibility = [
+        "//visibility:public",
+    ],
 )
-
-- 
GitLab


From 4dc64310bb4f4521fc025f1cb53bab309128c086 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 20 Oct 2016 23:07:37 +0200
Subject: [PATCH 017/344] Adding cc_grpc_library.

---
 BUILD                                         | 46 ++++++++++++++-
 WORKSPACE                                     | 17 +++++-
 bazel/cc_grpc_library.bzl                     | 35 +++++++++++
 bazel/generate_cc.bzl                         | 59 +++++++++++++++++++
 .../grpc_build_system.bzl                     |  7 +++
 5 files changed, 161 insertions(+), 3 deletions(-)
 create mode 100644 bazel/cc_grpc_library.bzl
 create mode 100644 bazel/generate_cc.bzl
 rename grpc-build-system.bzl => bazel/grpc_build_system.bzl (94%)

diff --git a/BUILD b/BUILD
index 7230183155..acf9acd3be 100644
--- a/BUILD
+++ b/BUILD
@@ -35,7 +35,7 @@ exports_files(["LICENSE"])
 
 package(default_visibility = ["//visibility:public"])
 
-load(":grpc-build-system.bzl", "grpc_cc_library")
+load("//:bazel/grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
 
 g_stands_for = "good"
 
@@ -190,7 +190,7 @@ grpc_cc_library(
         "src/compiler/ruby_generator_string-inl.h",
     ],
     external_deps = [
-        "protobuf_compiler",
+        "protobuf_clib",
     ],
     language = "c++",
     deps = [
@@ -198,6 +198,48 @@ grpc_cc_library(
     ],
 )
 
+grpc_proto_plugin(
+    name = "grpc_cpp_plugin",
+    srcs = ["src/compiler/cpp_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_csharp_plugin",
+    srcs = ["src/compiler/csharp_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_node_plugin",
+    srcs = ["src/compiler/node_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_objective_c_plugin",
+    srcs = ["src/compiler/objective_c_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_php_plugin",
+    srcs = ["src/compiler/php_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_python_plugin",
+    srcs = ["src/compiler/python_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
+grpc_proto_plugin(
+    name = "grpc_ruby_plugin",
+    srcs = ["src/compiler/ruby_plugin.cc"],
+    deps = [":grpc_plugin_support"],
+)
+
 grpc_cc_library(
     name = "grpc_csharp_ext",
     srcs = [
diff --git a/WORKSPACE b/WORKSPACE
index 6a1b70e152..1499a0a52f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,6 +3,16 @@ bind(
     actual = "//third_party/nanopb",
 )
 
+bind(
+    name = "grpc_cpp_plugin",
+    actual = "//:grpc_cpp_plugin",
+)
+
+bind(
+    name = "grpc++",
+    actual = "//:grpc++",
+)
+
 bind(
     name = "libssl",
     actual = "@submodule_boringssl//:ssl",
@@ -13,6 +23,11 @@ bind(
     actual = "@submodule_zlib//:z",
 )
 
+bind(
+    name = "protobuf",
+    actual = "@submodule_protobuf//:protobuf",
+)
+
 bind(
     name = "protobuf_clib",
     actual = "@submodule_protobuf//:protoc_lib",
@@ -20,7 +35,7 @@ bind(
 
 bind(
     name = "protobuf_compiler",
-    actual = "@submodule_protobuf//:protoc_lib",
+    actual = "@submodule_protobuf//:protoc",
 )
 
 new_local_repository(
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
new file mode 100644
index 0000000000..8e6f9ebb21
--- /dev/null
+++ b/bazel/cc_grpc_library.bzl
@@ -0,0 +1,35 @@
+"""Generates and compiles C++ grpc stubs from proto_library rules."""
+
+load("//:bazel/generate_cc.bzl", "generate_cc")
+
+def cc_grpc_library(name, srcs, deps, **kwargs):
+  """Generates C++ grpc classes from a .proto file.
+
+  Assumes the generated classes will be used in cc_api_version = 2.
+
+  Arguments:
+      name: name of rule.
+      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.
+      **kwargs: rest of arguments, e.g., compatible_with and visibility.
+  """
+  if len(srcs) > 1:
+    fail("Only one srcs value supported", "srcs")
+
+  codegen_target = "_" + name + "_codegen"
+
+  generate_cc(
+      name = codegen_target,
+      srcs = srcs,
+      plugin = "//external:grpc_cpp_plugin",
+      **kwargs
+  )
+
+  native.cc_library(
+      name = name,
+      srcs = [":" + codegen_target],
+      hdrs = [":" + codegen_target],
+      deps = deps + ["//external:grpc++"],
+      **kwargs
+  )
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
new file mode 100644
index 0000000000..a021742798
--- /dev/null
+++ b/bazel/generate_cc.bzl
@@ -0,0 +1,59 @@
+"""Generates C++ grpc stubs from proto_library rules.
+
+This is an internal rule used by cc_grpc_library, and shouldn't be used
+directly.
+"""
+
+def generate_cc_impl(ctx):
+  """Implementation of the gengrpccc rule."""
+  protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources]
+  includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports]
+  outs = []
+  outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos]
+  outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
+  out_files = [ctx.new_file(out) for out in outs]
+  # The following should be replaced with ctx.configuration.buildout
+  # whenever this is added to Skylark.
+  dir_out = out_files[0].dirname[:-len(protos[0].dirname)]
+
+  arguments = []
+  arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
+  arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+  arguments += ["-I{0}={0}".format(include.path) for include in includes]
+  arguments += [proto.path for proto in protos]
+
+  ctx.action(
+      inputs = protos + includes,
+      outputs = out_files,
+      executable = ctx.executable._protoc,
+      arguments = arguments,
+  )
+
+  return struct(files=set(out_files))
+
+generate_cc = rule(
+    attrs = {
+        "srcs": attr.label_list(
+            mandatory = True,
+            non_empty = True,
+            providers = ["proto"],
+        ),
+        "plugin": attr.label(
+            executable = True,
+            providers = ["files_to_run"],
+            cfg = HOST_CFG,
+        ),
+        "flags": attr.string_list(
+            mandatory = True,
+            allow_empty = False
+        ),
+        "_protoc": attr.label(
+            default = Label("//extern:protocol_compiler"),
+            executable = True,
+            cfg = HOST_CFG,
+        ),
+    },
+    # We generate .h files, so we need to output to genfiles.
+    output_to_genfiles = True,
+    implementation = generate_cc_impl,
+)
diff --git a/grpc-build-system.bzl b/bazel/grpc_build_system.bzl
similarity index 94%
rename from grpc-build-system.bzl
rename to bazel/grpc_build_system.bzl
index 187cc3e424..f2dde951fd 100644
--- a/grpc-build-system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -48,3 +48,10 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], external_deps
         "include"
     ]
   )
+
+def grpc_proto_plugin(name, srcs = [], deps = []):
+  native.cc_binary(
+    name = name,
+    srcs = srcs,
+    deps = deps,
+  )
-- 
GitLab


From 799bd5efb70b0abe076353dedd6a1983f1b01951 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Fri, 21 Oct 2016 01:54:32 +0200
Subject: [PATCH 018/344] Adding shim for generating C++ protos.

---
 BUILD                                  |  2 +-
 WORKSPACE                              | 12 +----
 bazel/BUILD                            |  9 ++++
 bazel/cc_grpc_library.bzl              | 45 +++++++++++++----
 bazel/generate_cc.bzl                  | 27 ++++++----
 bazel/grpc_build_system.bzl            | 11 ++++
 src/proto/grpc/testing/BUILD           | 69 ++++++++++++++++++++++++++
 src/proto/grpc/testing/duplicate/BUILD | 10 ++++
 8 files changed, 154 insertions(+), 31 deletions(-)
 create mode 100644 bazel/BUILD
 create mode 100644 src/proto/grpc/testing/BUILD
 create mode 100644 src/proto/grpc/testing/duplicate/BUILD

diff --git a/BUILD b/BUILD
index acf9acd3be..ec750bcef4 100644
--- a/BUILD
+++ b/BUILD
@@ -35,7 +35,7 @@ exports_files(["LICENSE"])
 
 package(default_visibility = ["//visibility:public"])
 
-load("//:bazel/grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
 
 g_stands_for = "good"
 
diff --git a/WORKSPACE b/WORKSPACE
index 1499a0a52f..98c3afa5bd 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,16 +3,6 @@ bind(
     actual = "//third_party/nanopb",
 )
 
-bind(
-    name = "grpc_cpp_plugin",
-    actual = "//:grpc_cpp_plugin",
-)
-
-bind(
-    name = "grpc++",
-    actual = "//:grpc++",
-)
-
 bind(
     name = "libssl",
     actual = "@submodule_boringssl//:ssl",
@@ -34,7 +24,7 @@ bind(
 )
 
 bind(
-    name = "protobuf_compiler",
+    name = "protocol_compiler",
     actual = "@submodule_protobuf//:protoc",
 )
 
diff --git a/bazel/BUILD b/bazel/BUILD
new file mode 100644
index 0000000000..940a379404
--- /dev/null
+++ b/bazel/BUILD
@@ -0,0 +1,9 @@
+package(default_visibility = ["//:__subpackages__"])
+
+load(":cc_grpc_library.bzl", "cc_grpc_library")
+
+cc_grpc_library(
+    name = "well_known_protos",
+    srcs = "@submodule_protobuf//:well_known_protos",
+    proto_only = True,
+)
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
index 8e6f9ebb21..e1dd27b0c3 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, **kwargs):
+def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
   """Generates C++ grpc classes from a .proto file.
 
   Assumes the generated classes will be used in cc_api_version = 2.
@@ -17,19 +17,46 @@ def cc_grpc_library(name, srcs, deps, **kwargs):
   if len(srcs) > 1:
     fail("Only one srcs value supported", "srcs")
 
+  proto_target = "_" + name + "_only"
   codegen_target = "_" + name + "_codegen"
+  codegen_grpc_target = "_" + name + "_grpc_codegen"
+  proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(':') == -1]
+  proto_deps += [dep.split(':')[0] + ':' + "_" + dep.split(':')[1] + "_only" for dep in deps if dep.find(':') != -1]
 
-  generate_cc(
-      name = codegen_target,
+  native.proto_library(
+      name = proto_target,
       srcs = srcs,
-      plugin = "//external:grpc_cpp_plugin",
+      deps = proto_deps,
       **kwargs
   )
 
-  native.cc_library(
-      name = name,
-      srcs = [":" + codegen_target],
-      hdrs = [":" + codegen_target],
-      deps = deps + ["//external:grpc++"],
+  generate_cc(
+      name = codegen_target,
+      srcs = [proto_target],
       **kwargs
   )
+
+  if not proto_only:
+    generate_cc(
+        name = codegen_grpc_target,
+        srcs = [proto_target],
+        plugin = "//:grpc_cpp_plugin",
+        **kwargs
+    )
+
+  if not proto_only:
+    native.cc_library(
+        name = name,
+        srcs = [":" + codegen_grpc_target, ":" + codegen_target],
+        hdrs = [":" + codegen_grpc_target, ":" + codegen_target],
+        deps = deps + ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"],
+        **kwargs
+    )
+  else:
+    native.cc_library(
+        name = name,
+        srcs = [":" + codegen_target],
+        hdrs = [":" + codegen_target],
+        deps = deps + ["//external:protobuf"],
+        **kwargs
+    )
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index a021742798..3665733681 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -5,20 +5,27 @@ directly.
 """
 
 def generate_cc_impl(ctx):
-  """Implementation of the gengrpccc rule."""
+  """Implementation of the generate_cc rule."""
   protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources]
   includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports]
   outs = []
-  outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos]
-  outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
+  if ctx.executable.plugin:
+    outs += [proto.basename[:-len(".proto")] + ".grpc.pb.h" for proto in protos]
+    outs += [proto.basename[:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
+  else:
+    outs += [proto.basename[:-len(".proto")] + ".pb.h" for proto in protos]
+    outs += [proto.basename[:-len(".proto")] + ".pb.cc" for proto in protos]
   out_files = [ctx.new_file(out) for out in outs]
   # The following should be replaced with ctx.configuration.buildout
   # whenever this is added to Skylark.
   dir_out = out_files[0].dirname[:-len(protos[0].dirname)]
 
   arguments = []
-  arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
-  arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+  if ctx.executable.plugin:
+    arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
+    arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+  else:
+    arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
   arguments += ["-I{0}={0}".format(include.path) for include in includes]
   arguments += [proto.path for proto in protos]
 
@@ -41,16 +48,16 @@ generate_cc = rule(
         "plugin": attr.label(
             executable = True,
             providers = ["files_to_run"],
-            cfg = HOST_CFG,
+            cfg = "host",
         ),
         "flags": attr.string_list(
-            mandatory = True,
-            allow_empty = False
+            mandatory = False,
+            allow_empty = True,
         ),
         "_protoc": attr.label(
-            default = Label("//extern:protocol_compiler"),
+            default = Label("//external:protocol_compiler"),
             executable = True,
-            cfg = HOST_CFG,
+            cfg = "host",
         ),
     },
     # We generate .h files, so we need to output to genfiles.
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index f2dde951fd..70a7001d75 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -55,3 +55,14 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
     srcs = srcs,
     deps = deps,
   )
+
+load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
+
+def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True):
+  cc_grpc_library(
+    name = name,
+    srcs = srcs,
+    deps = deps,
+    proto_only = not has_services,
+  )
+
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
new file mode 100644
index 0000000000..2c91006064
--- /dev/null
+++ b/src/proto/grpc/testing/BUILD
@@ -0,0 +1,69 @@
+
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "compiler_test_proto",
+    srcs = ["compiler_test.proto"],
+)
+
+grpc_proto_library(
+    name = "control_proto",
+    srcs = ["control.proto"],
+    deps = ["payloads_proto", "stats_proto"],
+)
+
+#grpc_proto_library(
+#    name = "echo_duplicate_proto",
+#    srcs = ["duplicate/echo_duplicate.proto"],
+#    deps = ["echo_messages_proto"],
+#)
+
+grpc_proto_library(
+    name = "echo_messages_proto",
+    srcs = ["echo_messages.proto"],
+)
+
+grpc_proto_library(
+    name = "echo_proto",
+    srcs = ["echo.proto"],
+    deps = ["echo_messages_proto"],
+)
+
+grpc_proto_library(
+    name = "empty_proto",
+    srcs = ["empty.proto"],
+)
+
+grpc_proto_library(
+    name = "messages_proto",
+    srcs = ["messages.proto"],
+)
+
+grpc_proto_library(
+    name = "metrics_proto",
+    srcs = ["metrics.proto"],
+)
+
+grpc_proto_library(
+    name = "payloads_proto",
+    srcs = ["payloads.proto"],
+)
+
+grpc_proto_library(
+    name = "services_proto",
+    srcs = ["services.proto"],
+    deps = ["control_proto", "messages_proto"],
+)
+
+grpc_proto_library(
+    name = "stats_proto",
+    srcs = ["stats.proto"],
+)
+
+grpc_proto_library(
+    name = "test_proto",
+    srcs = ["test.proto"],
+    deps = ["empty_proto", "messages_proto"],
+)
diff --git a/src/proto/grpc/testing/duplicate/BUILD b/src/proto/grpc/testing/duplicate/BUILD
new file mode 100644
index 0000000000..255e699bec
--- /dev/null
+++ b/src/proto/grpc/testing/duplicate/BUILD
@@ -0,0 +1,10 @@
+
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "echo_duplicate_proto",
+    srcs = ["echo_duplicate.proto"],
+    deps = ["//src/proto/grpc/testing:echo_messages_proto"],
+)
-- 
GitLab


From ba2d5a678da64109e6e0d79d5fdceecd3ae2b7d3 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 27 Sep 2016 14:33:06 -0700
Subject: [PATCH 019/344] Remove deprecated V8 function call in Node library

---
 src/node/ext/call.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 9f023b5883..b585282d32 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -613,8 +613,8 @@ NAN_METHOD(Call::New) {
         return Nan::ThrowTypeError("Call's fourth argument must be a string");
       }
       call = new Call(wrapped_call);
-      info.This()->SetHiddenValue(Nan::New("channel_").ToLocalChecked(),
-                                  channel_object);
+      Nan::Set(info.This(), Nan::New("channel_").ToLocalChecked(),
+               channel_object);
     }
     call->Wrap(info.This());
     info.GetReturnValue().Set(info.This());
-- 
GitLab


From dc23046b065493807f0ca0b09907d03d96baeb5c Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 25 Oct 2016 14:12:42 -0700
Subject: [PATCH 020/344] Add electron support and build electron artifacts

---
 binding.gyp                             | 132 ++++++++++++++----------
 templates/binding.gyp.template          | 117 +++++++++++++++------
 tools/run_tests/build_artifact_node.bat |  10 +-
 tools/run_tests/build_artifact_node.sh  |   8 ++
 4 files changed, 185 insertions(+), 82 deletions(-)

diff --git a/binding.gyp b/binding.gyp
index 8b23cc2e7d..023a67533a 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -37,15 +37,59 @@
 # Some of this file is built with the help of
 # https://n8.io/converting-a-c-library-to-gyp/
 {
+  'variables': {
+    'runtime%': 'node'
+  },
   'target_defaults': {
     'include_dirs': [
       '.',
       'include'
     ],
+    'defines': [
+      'GPR_BACKWARDS_COMPATIBILITY_MODE'
+    ],
     'conditions': [
+      # This is the condition for using boringssl
+      ['OS=="win" or runtime=="electron"', {
+        "include_dirs": [
+          "third_party/boringssl/include"
+        ],
+        "defines": [
+          'OPENSSL_NO_ASM',
+          'OPENSSL_NO_THREADS'
+        ]
+      }, {
+        # Based on logic above, we know that this must be a non-Windows system
+        'variables': {
+          # The output of "node --version" is "v[version]". We use cut to
+          # remove the first character.
+          'target%': '<!(node --version | cut -c2-)'
+        },
+        # Empirically, Node only exports ALPN symbols if its major version is >0.
+        # io.js always reports versions >0 and always exports ALPN symbols.
+        # Therefore, Node's major version will be truthy if and only if it
+        # supports ALPN. The target is "[major].[minor].[patch]". We split by
+        # periods and take the first field to get the major version.
+        'defines': [
+          'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)'
+        ],
+        'include_dirs': [
+          '<(node_root_dir)/deps/openssl/openssl/include',
+        ],
+        'conditions': [
+         ["target_arch=='ia32'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+         }],
+         ["target_arch=='x64'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+         }],
+         ["target_arch=='arm'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+         }]
+        ]
+      }],
       ['OS == "win"', {
         "include_dirs": [
-          "third_party/boringssl/include",
           "third_party/zlib"
         ],
         "defines": [
@@ -55,8 +99,6 @@
           'UNICODE',
           '_UNICODE',
           'NOMINMAX',
-          'OPENSSL_NO_ASM',
-          'GPR_BACKWARDS_COMPATIBILITY_MODE'
         ],
         "msvs_settings": {
           'VCCLCompilerTool': {
@@ -69,21 +111,8 @@
       }, { # OS != "win"
         'variables': {
           'config': '<!(echo $CONFIG)',
-          # The output of "node --version" is "v[version]". We use cut to
-          # remove the first character.
-          'target%': '<!(node --version | cut -c2-)'
         },
-          # Empirically, Node only exports ALPN symbols if its major version is >0.
-          # io.js always reports versions >0 and always exports ALPN symbols.
-          # Therefore, Node's major version will be truthy if and only if it
-          # supports ALPN. The target is "[major].[minor].[patch]". We split by
-          # periods and take the first field to get the major version.
-        'defines': [
-          'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)',
-          'GPR_BACKWARDS_COMPATIBILITY_MODE'
-        ],
         'include_dirs': [
-          '<(node_root_dir)/deps/openssl/openssl/include',
           '<(node_root_dir)/deps/zlib'
         ],
         'conditions': [
@@ -98,47 +127,14 @@
               '-fprofile-arcs'
             ]
           }
-         ],
-         ["target_arch=='ia32'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-         }],
-         ["target_arch=='x64'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-         }],
-         ["target_arch=='arm'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
-         }]
+         ]
         ]
       }]
     ]
   },
   'conditions': [
-    ['OS == "win"', {
+    ['OS=="win" or runtime=="electron"', {
       'targets': [
-        {
-          # IMPORTANT WINDOWS BUILD INFORMATION
-          # This library does not build on Windows without modifying the Node
-          # development packages that node-gyp downloads in order to build.
-          # Due to https://github.com/nodejs/node/issues/4932, the headers for
-          # BoringSSL conflict with the OpenSSL headers included by default
-          # when including the Node headers. The remedy for this is to remove
-          # the OpenSSL headers, from the downloaded Node development package,
-          # which is typically located in `.node-gyp` in your home directory.
-          'target_name': 'WINDOWS_BUILD_WARNING',
-          'actions': [
-            {
-              'action_name': 'WINDOWS_BUILD_WARNING',
-              'inputs': [
-                'package.json'
-              ],
-              'outputs': [
-                'ignore_this_part'
-              ],
-              'action': ['echo', 'IMPORTANT: Due to https://github.com/nodejs/node/issues/4932, to build this library on Windows, you must first remove <(node_root_dir)/include/node/openssl/']
-            }
-          ]
-        },
-        # Only want to compile BoringSSL and zlib under Windows
         {
           'cflags': [
             '-std=c99',
@@ -450,6 +446,34 @@
             'third_party/boringssl/ssl/tls_record.c',
           ]
         },
+      ]
+    }],
+    ['OS == "win"', {
+      'targets': [
+        {
+          # IMPORTANT WINDOWS BUILD INFORMATION
+          # This library does not build on Windows without modifying the Node
+          # development packages that node-gyp downloads in order to build.
+          # Due to https://github.com/nodejs/node/issues/4932, the headers for
+          # BoringSSL conflict with the OpenSSL headers included by default
+          # when including the Node headers. The remedy for this is to remove
+          # the OpenSSL headers, from the downloaded Node development package,
+          # which is typically located in `.node-gyp` in your home directory.
+          'target_name': 'WINDOWS_BUILD_WARNING',
+          'actions': [
+            {
+              'action_name': 'WINDOWS_BUILD_WARNING',
+              'inputs': [
+                'package.json'
+              ],
+              'outputs': [
+                'ignore_this_part'
+              ],
+              'action': ['echo', 'IMPORTANT: Due to https://github.com/nodejs/node/issues/4932, to build this library on Windows, you must first remove <(node_root_dir)/include/node/openssl/']
+            }
+          ]
+        },
+        # Only want to compile zlib under Windows
         {
           'cflags': [
             '-std=c99',
@@ -787,6 +811,11 @@
         '-g'
       ],
       "conditions": [
+        ['OS=="win" or runtime=="electron"', {
+          'dependencies': [
+            "boringssl",
+          ]
+        }],
         ['OS=="mac"', {
           'xcode_settings': {
             'MACOSX_DEPLOYMENT_TARGET': '10.9',
@@ -798,7 +827,6 @@
         }],
         ['OS=="win"', {
           'dependencies': [
-            "boringssl",
             "z",
           ]
         }],
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 40d430f792..525a8bfc3f 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -39,15 +39,59 @@
   # Some of this file is built with the help of
   # https://n8.io/converting-a-c-library-to-gyp/
   {
+    'variables': {
+      'runtime%': 'node'
+    },
     'target_defaults': {
       'include_dirs': [
         '.',
         'include'
       ],
+      'defines': [
+        'GPR_BACKWARDS_COMPATIBILITY_MODE'
+      ],
       'conditions': [
+        # This is the condition for using boringssl
+        ['OS=="win" or runtime=="electron"', {
+          "include_dirs": [
+            "third_party/boringssl/include"
+          ],
+          "defines": [
+            'OPENSSL_NO_ASM',
+            'OPENSSL_NO_THREADS'
+          ]
+        }, {
+          # Based on logic above, we know that this must be a non-Windows system
+          'variables': {
+            # The output of "node --version" is "v[version]". We use cut to
+            # remove the first character.
+            'target%': '<!(node --version | cut -c2-)'
+          },
+          # Empirically, Node only exports ALPN symbols if its major version is >0.
+          # io.js always reports versions >0 and always exports ALPN symbols.
+          # Therefore, Node's major version will be truthy if and only if it
+          # supports ALPN. The target is "[major].[minor].[patch]". We split by
+          # periods and take the first field to get the major version.
+          'defines': [
+            'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)'
+          ],
+          'include_dirs': [
+            '<(node_root_dir)/deps/openssl/openssl/include',
+          ],
+          'conditions': [
+           ["target_arch=='ia32'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+           }],
+           ["target_arch=='x64'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+           }],
+           ["target_arch=='arm'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+           }]
+          ]
+        }],
         ['OS == "win"', {
           "include_dirs": [
-            "third_party/boringssl/include",
             "third_party/zlib"
           ],
           "defines": [
@@ -57,8 +101,6 @@
             'UNICODE',
             '_UNICODE',
             'NOMINMAX',
-            'OPENSSL_NO_ASM',
-            'GPR_BACKWARDS_COMPATIBILITY_MODE'
           ],
           "msvs_settings": {
             'VCCLCompilerTool': {
@@ -71,21 +113,8 @@
         }, { # OS != "win"
           'variables': {
             'config': '<!(echo $CONFIG)',
-            # The output of "node --version" is "v[version]". We use cut to
-            # remove the first character.
-            'target%': '<!(node --version | cut -c2-)'
           },
-            # Empirically, Node only exports ALPN symbols if its major version is >0.
-            # io.js always reports versions >0 and always exports ALPN symbols.
-            # Therefore, Node's major version will be truthy if and only if it
-            # supports ALPN. The target is "[major].[minor].[patch]". We split by
-            # periods and take the first field to get the major version.
-          'defines': [
-            'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)',
-            'GPR_BACKWARDS_COMPATIBILITY_MODE'
-          ],
           'include_dirs': [
-            '<(node_root_dir)/deps/openssl/openssl/include',
             '<(node_root_dir)/deps/zlib'
           ],
           'conditions': [
@@ -100,21 +129,42 @@
                 '-fprofile-arcs'
               ]
             }
-           ],
-           ["target_arch=='ia32'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-           }],
-           ["target_arch=='x64'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-           }],
-           ["target_arch=='arm'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
-           }]
+           ]
           ]
         }]
       ]
     },
     'conditions': [
+      ['OS=="win" or runtime=="electron"', {
+        'targets': [
+          % for module in node_modules:
+          % for lib in libs:
+          % if lib.name in module.transitive_deps and lib.name == 'boringssl':
+          {
+            'cflags': [
+              '-std=c99',
+              '-Wall',
+              '-Werror'
+            ],
+            'target_name': '${lib.name}',
+            'product_prefix': 'lib',
+            'type': 'static_library',
+            'dependencies': [
+              % for dep in getattr(lib, 'deps', []):
+              '${dep}',
+              % endfor
+            ],
+            'sources': [
+              % for source in lib.src:
+              '${source}',
+              % endfor
+            ]
+          },
+          % endif
+          % endfor
+          % endfor
+        ]
+      }],
       ['OS == "win"', {
         'targets': [
           {
@@ -140,10 +190,10 @@
               }
             ]
           },
-          # Only want to compile BoringSSL and zlib under Windows
+          # Only want to compile zlib under Windows
           % for module in node_modules:
           % for lib in libs:
-          % if lib.name in module.transitive_deps and lib.name in ('boringssl', 'z'):
+          % if lib.name in module.transitive_deps and lib.name == 'z':
           {
             'cflags': [
               '-std=c99',
@@ -220,6 +270,15 @@
           '-g'
         ],
         "conditions": [
+          ['OS=="win" or runtime=="electron"', {
+            'dependencies': [
+              % for dep in getattr(module, 'deps', []):
+              % if dep == 'boringssl':
+              "${dep}",
+              % endif
+              % endfor
+            ]
+          }],
           ['OS=="mac"', {
             'xcode_settings': {
               'MACOSX_DEPLOYMENT_TARGET': '10.9',
@@ -232,7 +291,7 @@
           ['OS=="win"', {
             'dependencies': [
               % for dep in getattr(module, 'deps', []):
-              % if dep in ('boringssl', 'z'):
+              % if dep == 'z':
               "${dep}",
               % endif
               % endfor
diff --git a/tools/run_tests/build_artifact_node.bat b/tools/run_tests/build_artifact_node.bat
index c5bd726db7..9175aa5c64 100644
--- a/tools/run_tests/build_artifact_node.bat
+++ b/tools/run_tests/build_artifact_node.bat
@@ -29,6 +29,8 @@
 
 set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
 
+set electron_versions=1.0.0 1.1.0 1.2.0 1.3.0 1.4.0
+
 set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
 
 del /f /q BUILD || rmdir build /s /q
@@ -47,9 +49,15 @@ for %%v in (%node_versions%) do (
 
   xcopy /Y /I /S build\stage\* artifacts\ || goto :error
 )
+
+for %%v in (%electron_versions%) do (
+  call .\node_modules\.bin\node-pre-gyp.cmd configure rebuild package testpackage --runtime=electron --target=%%v --target_arch=%1 || goto :error
+
+  xcopy /Y /I /S build\stage\* artifacts\ || goto :error
+)
 if %errorlevel% neq 0 exit /b %errorlevel%
 
 goto :EOF
 
 :error
-exit /b 1
\ No newline at end of file
+exit /b 1
diff --git a/tools/run_tests/build_artifact_node.sh b/tools/run_tests/build_artifact_node.sh
index 9d06472aa4..c1ee71a4ce 100755
--- a/tools/run_tests/build_artifact_node.sh
+++ b/tools/run_tests/build_artifact_node.sh
@@ -44,8 +44,16 @@ npm update
 
 node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
 
+electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 )
+
 for version in ${node_versions[@]}
 do
   ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH
   cp -r build/stage/* artifacts/
 done
+
+for version in ${node_versions[@]}
+do
+  HOME=~/.electron-gyp ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --runtime=electron --target=$version --target_arch=$NODE_TARGET_ARCH
+  cp -r build/stage/* artifacts/
+done
-- 
GitLab


From 89e23643538cd632e3f0e78671795ab42bf3371c Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 26 Oct 2016 20:08:49 +0200
Subject: [PATCH 021/344] Removing useless message.

---
 src/proto/grpc/testing/BUILD | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 2c91006064..f9f9cbceaf 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -14,12 +14,6 @@ grpc_proto_library(
     deps = ["payloads_proto", "stats_proto"],
 )
 
-#grpc_proto_library(
-#    name = "echo_duplicate_proto",
-#    srcs = ["duplicate/echo_duplicate.proto"],
-#    deps = ["echo_messages_proto"],
-#)
-
 grpc_proto_library(
     name = "echo_messages_proto",
     srcs = ["echo_messages.proto"],
-- 
GitLab


From 19014deb841f25d14827147d4812b1ddcce2b693 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 27 Oct 2016 00:33:07 +0200
Subject: [PATCH 022/344] Updating BUILD file.

---
 BUILD | 51 +++++++++------------------------------------------
 1 file changed, 9 insertions(+), 42 deletions(-)

diff --git a/BUILD b/BUILD
index ec750bcef4..c030f24cd7 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,3 @@
-# gRPC Bazel BUILD file.
 #
 # Copyright 2016, Google Inc.
 # All rights reserved.
@@ -437,6 +436,7 @@ grpc_cc_library(
         "src/core/lib/iomgr/combiner.c",
         "src/core/lib/iomgr/endpoint.c",
         "src/core/lib/iomgr/endpoint_pair_posix.c",
+        "src/core/lib/iomgr/endpoint_pair_uv.c",
         "src/core/lib/iomgr/endpoint_pair_windows.c",
         "src/core/lib/iomgr/error.c",
         "src/core/lib/iomgr/ev_epoll_linux.c",
@@ -468,7 +468,6 @@ grpc_cc_library(
         "src/core/lib/iomgr/tcp_server_windows.c",
         "src/core/lib/iomgr/tcp_windows.c",
         "src/core/lib/iomgr/time_averaged_stats.c",
-        "src/core/lib/iomgr/timer.c",
         "src/core/lib/iomgr/timer_heap.c",
         "src/core/lib/iomgr/udp_server.c",
         "src/core/lib/iomgr/unix_sockets_posix.c",
@@ -549,27 +548,34 @@ grpc_cc_library(
         "src/core/lib/iomgr/pollset.h",
         "src/core/lib/iomgr/pollset_set.h",
         "src/core/lib/iomgr/pollset_set_windows.h",
+        "src/core/lib/iomgr/pollset_uv.h",
         "src/core/lib/iomgr/pollset_windows.h",
+        "src/core/lib/iomgr/port.h",
         "src/core/lib/iomgr/resolve_address.h",
         "src/core/lib/iomgr/sockaddr.h",
         "src/core/lib/iomgr/sockaddr_posix.h",
         "src/core/lib/iomgr/sockaddr_utils.h",
         "src/core/lib/iomgr/sockaddr_windows.h",
+        "src/core/lib/iomgr/socket_utils.h",
         "src/core/lib/iomgr/socket_utils_posix.h",
         "src/core/lib/iomgr/socket_windows.h",
         "src/core/lib/iomgr/tcp_client.h",
         "src/core/lib/iomgr/tcp_posix.h",
         "src/core/lib/iomgr/tcp_server.h",
+        "src/core/lib/iomgr/tcp_uv.h",
         "src/core/lib/iomgr/tcp_windows.h",
         "src/core/lib/iomgr/time_averaged_stats.h",
         "src/core/lib/iomgr/timer.h",
+        "src/core/lib/iomgr/timer_generic.h",
         "src/core/lib/iomgr/timer_heap.h",
+        "src/core/lib/iomgr/timer_uv.h",
         "src/core/lib/iomgr/udp_server.h",
         "src/core/lib/iomgr/unix_sockets_posix.h",
         "src/core/lib/iomgr/wakeup_fd_cv.h",
         "src/core/lib/iomgr/wakeup_fd_pipe.h",
         "src/core/lib/iomgr/wakeup_fd_posix.h",
         "src/core/lib/iomgr/workqueue.h",
+        "src/core/lib/iomgr/workqueue_uv.h",
         "src/core/lib/iomgr/workqueue_windows.h",
         "src/core/lib/json/json.h",
         "src/core/lib/json/json_common.h",
@@ -591,7 +597,7 @@ grpc_cc_library(
         "src/core/lib/transport/mdstr_hash_table.h",
         "src/core/lib/transport/metadata.h",
         "src/core/lib/transport/metadata_batch.h",
-        "src/core/lib/transport/static_metadata.h",
+        "src/core/lib/transport/method_config.h",
         "src/core/lib/transport/timeout_encoding.h",
         "src/core/lib/transport/transport.h",
         "src/core/lib/transport/transport_impl.h",
@@ -618,47 +624,10 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc_client_config",
     srcs = [
-        "src/core/ext/client_config/channel_connectivity.c",
-        "src/core/ext/client_config/client_channel.c",
-        "src/core/ext/client_config/client_channel_factory.c",
-        "src/core/ext/client_config/client_config_plugin.c",
-        "src/core/ext/client_config/connector.c",
-        "src/core/ext/client_config/default_initial_connect_string.c",
-        "src/core/ext/client_config/http_connect_handshaker.c",
-        "src/core/ext/client_config/initial_connect_string.c",
-        "src/core/ext/client_config/lb_policy.c",
-        "src/core/ext/client_config/lb_policy_factory.c",
-        "src/core/ext/client_config/lb_policy_registry.c",
         "src/core/ext/client_config/message_size_filter.c",
-        "src/core/ext/client_config/method_config.c",
-        "src/core/ext/client_config/parse_address.c",
-        "src/core/ext/client_config/resolver.c",
-        "src/core/ext/client_config/resolver_factory.c",
-        "src/core/ext/client_config/resolver_registry.c",
-        "src/core/ext/client_config/resolver_result.c",
-        "src/core/ext/client_config/subchannel.c",
-        "src/core/ext/client_config/subchannel_index.c",
-        "src/core/ext/client_config/uri_parser.c",
     ],
     hdrs = [
-        "src/core/ext/client_config/client_channel.h",
-        "src/core/ext/client_config/client_channel_factory.h",
-        "src/core/ext/client_config/connector.h",
-        "src/core/ext/client_config/http_connect_handshaker.h",
-        "src/core/ext/client_config/initial_connect_string.h",
-        "src/core/ext/client_config/lb_policy.h",
-        "src/core/ext/client_config/lb_policy_factory.h",
-        "src/core/ext/client_config/lb_policy_registry.h",
         "src/core/ext/client_config/message_size_filter.h",
-        "src/core/ext/client_config/method_config.h",
-        "src/core/ext/client_config/parse_address.h",
-        "src/core/ext/client_config/resolver.h",
-        "src/core/ext/client_config/resolver_factory.h",
-        "src/core/ext/client_config/resolver_registry.h",
-        "src/core/ext/client_config/resolver_result.h",
-        "src/core/ext/client_config/subchannel.h",
-        "src/core/ext/client_config/subchannel_index.h",
-        "src/core/ext/client_config/uri_parser.h",
     ],
     language = "c",
     deps = [
@@ -777,8 +746,6 @@ grpc_cc_library(
         "src/core/lib/security/credentials/credentials.c",
         "src/core/lib/security/credentials/credentials_metadata.c",
         "src/core/lib/security/credentials/fake/fake_credentials.c",
-        "src/core/lib/security/credentials/google_default/credentials_posix.c",
-        "src/core/lib/security/credentials/google_default/credentials_windows.c",
         "src/core/lib/security/credentials/google_default/google_default_credentials.c",
         "src/core/lib/security/credentials/iam/iam_credentials.c",
         "src/core/lib/security/credentials/jwt/json_token.c",
-- 
GitLab


From cb4b2b5d7dc1699a709ffce8b96a3920bd39f8eb Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Thu, 27 Oct 2016 11:30:50 -0700
Subject: [PATCH 023/344] libuv changes don't work with Electron

---
 binding.gyp                    | 8 ++++++--
 templates/binding.gyp.template | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/binding.gyp b/binding.gyp
index 92360a4363..141104ac7c 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -46,10 +46,14 @@
       'include'
     ],
     'defines': [
-      'GPR_BACKWARDS_COMPATIBILITY_MODE',
-      'GRPC_UV'
+      'GPR_BACKWARDS_COMPATIBILITY_MODE'
     ],
     'conditions': [
+      ['runtime=="node"', {
+        'defines': [
+          'GRPC_UV'
+        ]
+      }],
       # This is the condition for using boringssl
       ['OS=="win" or runtime=="electron"', {
         "include_dirs": [
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 2fc840daad..9b9e4e116d 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -48,10 +48,14 @@
         'include'
       ],
       'defines': [
-        'GPR_BACKWARDS_COMPATIBILITY_MODE',
-        'GRPC_UV'
+        'GPR_BACKWARDS_COMPATIBILITY_MODE'
       ],
       'conditions': [
+        ['runtime=="node"', {
+          'defines': [
+            'GRPC_UV'
+          ]
+        }],
         # This is the condition for using boringssl
         ['OS=="win" or runtime=="electron"', {
           "include_dirs": [
-- 
GitLab


From a59c16c184244383900107d56e10b548e26cc7c2 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 31 Oct 2016 07:25:01 -0700
Subject: [PATCH 024/344] Progress towards making grpc_slice_unref_internal
 take an exec_ctx

---
 include/grpc/impl/codegen/grpc_types.h        |   2 +-
 include/grpc/impl/codegen/slice.h             |   4 +-
 .../client_channel/http_connect_handshaker.c  |   6 +-
 .../ext/client_channel/resolver_factory.h     |   6 +-
 src/core/ext/client_channel/subchannel.c      |   3 +-
 src/core/ext/client_channel/uri_parser.c      |  35 +++---
 src/core/ext/lb_policy/grpclb/grpclb.c        |  12 +-
 .../ext/resolver/sockaddr/sockaddr_resolver.c |  13 +-
 .../server/insecure/server_chttp2_posix.c     |   2 +-
 .../server/secure/server_secure_chttp2.c      |   6 +-
 .../transport/chttp2/transport/bin_decoder.c  |  15 ++-
 .../transport/chttp2/transport/bin_decoder.h  |   5 +-
 .../transport/chttp2/transport/bin_encoder.h  |   2 +-
 .../chttp2/transport/chttp2_transport.c       |  32 ++---
 .../chttp2/transport/hpack_encoder.c          |  57 +++++----
 .../chttp2/transport/hpack_encoder.h          |   6 +-
 .../transport/chttp2/transport/hpack_parser.c |  58 ++++-----
 .../transport/chttp2/transport/hpack_table.c  |  35 +++---
 .../transport/chttp2/transport/hpack_table.h  |  13 +-
 .../ext/transport/chttp2/transport/writing.c  |   3 +-
 src/core/lib/channel/channel_args.c           |  10 +-
 src/core/lib/channel/channel_args.h           |   5 +-
 src/core/lib/channel/channel_stack.c          |   4 +-
 src/core/lib/channel/channel_stack_builder.c  |  12 +-
 src/core/lib/channel/channel_stack_builder.h  |   6 +-
 src/core/lib/channel/compress_filter.c        |  19 +--
 src/core/lib/channel/deadline_filter.c        |   3 +-
 src/core/lib/channel/http_client_filter.c     |  19 +--
 src/core/lib/channel/http_server_filter.c     |   8 +-
 src/core/lib/channel/message_size_filter.c    |  12 +-
 src/core/lib/compression/message_compress.c   |  46 ++++----
 src/core/lib/compression/message_compress.h   |   6 +-
 src/core/lib/http/httpcli.c                   |  13 +-
 src/core/lib/iomgr/resource_quota.c           |  45 +++----
 src/core/lib/iomgr/resource_quota.h           |   4 +-
 src/core/lib/iomgr/tcp_client_posix.c         |  10 +-
 src/core/lib/iomgr/tcp_client_windows.c       |   8 +-
 src/core/lib/iomgr/tcp_posix.c                |  24 ++--
 src/core/lib/iomgr/tcp_server_posix.c         |  10 +-
 src/core/lib/iomgr/tcp_server_windows.c       |   8 +-
 src/core/lib/iomgr/tcp_windows.c              |   6 +-
 .../credentials/credentials_metadata.c        |   8 +-
 .../google_default_credentials.c              |   4 +-
 .../security/credentials/jwt/jwt_verifier.c   |  16 +--
 .../credentials/oauth2/oauth2_credentials.c   |   4 +-
 .../credentials/plugin/plugin_credentials.c   |   4 +-
 .../security/transport/client_auth_filter.c   |   4 +-
 src/core/lib/security/transport/handshake.c   |  10 +-
 .../lib/security/transport/secure_endpoint.c  |  24 ++--
 src/core/lib/security/util/b64.c              |   2 +-
 src/core/lib/slice/percent_encoding.c         |   8 +-
 src/core/lib/slice/slice.c                    |  34 ++++--
 src/core/lib/slice/slice_buffer.c             |  25 +++-
 src/core/lib/slice/slice_internal.h           |  49 ++++++++
 src/core/lib/slice/slice_string_helpers.c     |   3 +-
 src/core/lib/surface/byte_buffer.c            |   8 +-
 src/core/lib/surface/byte_buffer_reader.c     |  16 ++-
 src/core/lib/surface/call.c                   | 111 ++++++++++--------
 src/core/lib/surface/call.h                   |   3 +-
 src/core/lib/surface/channel.c                |  76 +++++++-----
 src/core/lib/surface/channel.h                |  10 +-
 src/core/lib/surface/init.c                   |   4 +-
 src/core/lib/surface/lame_client.c            |  11 +-
 src/core/lib/surface/server.c                 |  18 +--
 src/core/lib/transport/byte_stream.c          |   5 +-
 src/core/lib/transport/mdstr_hash_table.c     |   7 +-
 src/core/lib/transport/mdstr_hash_table.h     |   5 +-
 src/core/lib/transport/metadata.c             |  66 ++++++-----
 src/core/lib/transport/metadata.h             |  36 +++---
 src/core/lib/transport/metadata_batch.c       |  17 +--
 src/core/lib/transport/metadata_batch.h       |   9 +-
 src/core/lib/transport/method_config.c        |  45 ++++---
 src/core/lib/transport/method_config.h        |  11 +-
 src/core/lib/transport/transport.c            |  16 +--
 src/core/lib/transport/transport.h            |   7 +-
 test/core/bad_client/bad_client.c             |   6 +-
 test/core/bad_client/tests/large_metadata.c   |   2 +-
 .../set_initial_connect_string_test.c         |   4 +-
 test/core/compression/message_compress_test.c |  34 +++---
 test/core/end2end/bad_server_response_test.c  |   4 +-
 test/core/end2end/dualstack_socket_test.c     |   2 +-
 test/core/end2end/fake_resolver.c             |   2 +-
 test/core/end2end/fixtures/http_proxy.c       |  12 +-
 test/core/end2end/fuzzers/client_fuzzer.c     |   2 +-
 test/core/end2end/fuzzers/server_fuzzer.c     |   2 +-
 test/core/http/httpcli_test.c                 |   4 +-
 test/core/http/httpscli_test.c                |   4 +-
 test/core/iomgr/endpoint_tests.c              |   6 +-
 test/core/iomgr/resource_quota_test.c         |   4 +-
 test/core/iomgr/tcp_posix_test.c              |  18 +--
 test/core/security/secure_endpoint_test.c     |   4 +-
 test/core/slice/slice_buffer_test.c           |   2 +-
 test/core/surface/byte_buffer_reader_test.c   |   4 +-
 .../transport/chttp2/hpack_encoder_test.c     |   4 +-
 test/core/util/mock_endpoint.c                |   2 +-
 test/core/util/passthru_endpoint.c            |   4 +-
 test/core/util/port_server_client.c           |   6 +-
 .../run_tests/sanity/core_banned_functions.py |  32 +++++
 98 files changed, 843 insertions(+), 590 deletions(-)
 create mode 100644 src/core/lib/slice/slice_internal.h
 create mode 100755 tools/run_tests/sanity/core_banned_functions.py

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 18678622c5..9d794a4267 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -93,7 +93,7 @@ typedef enum {
 
 typedef struct grpc_arg_pointer_vtable {
   void *(*copy)(void *p);
-  void (*destroy)(void *p);
+  void (*destroy)(grpc_exec_ctx *exec_ctx, void *p);
   int (*cmp)(void *p, void *q);
 } grpc_arg_pointer_vtable;
 
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 774ba0e95d..ef60ce1220 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,6 +37,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+typedef struct grpc_exec_ctx grpc_exec_ctx;
+
 /* Slice API
 
    A slice represents a contiguous reference counted array of bytes.
@@ -57,7 +59,7 @@
    grpc_slice_new, or grpc_slice_new_with_len instead. */
 typedef struct grpc_slice_refcount {
   void (*ref)(void *);
-  void (*unref)(void *);
+  void (*unref)(grpc_exec_ctx *exec_ctx, void *);
 } grpc_slice_refcount;
 
 #define GRPC_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 82042897b2..6ce1953209 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -76,7 +76,7 @@ static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
   if (gpr_unref(&handshaker->refcount)) {
     gpr_free(handshaker->proxy_server);
     gpr_free(handshaker->server_name);
-    grpc_slice_buffer_destroy(&handshaker->write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
     grpc_http_parser_destroy(&handshaker->http_parser);
     grpc_http_response_destroy(&handshaker->http_response);
     gpr_free(handshaker);
@@ -142,7 +142,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
                                &handshaker->read_buffer->slices[i + 1],
                                handshaker->read_buffer->count - i - 1);
         grpc_slice_buffer_swap(handshaker->read_buffer, &tmp_buffer);
-        grpc_slice_buffer_destroy(&tmp_buffer);
+        grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
         break;
       }
     }
@@ -159,7 +159,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
   // complete (e.g., handling chunked transfer encoding or looking
   // at the Content-Length: header).
   if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
-    grpc_slice_buffer_reset_and_unref(handshaker->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, handshaker->read_buffer);
     grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
                        &handshaker->response_read_closure);
     return;
diff --git a/src/core/ext/client_channel/resolver_factory.h b/src/core/ext/client_channel/resolver_factory.h
index 4da42e84d2..76b1f45d80 100644
--- a/src/core/ext/client_channel/resolver_factory.h
+++ b/src/core/ext/client_channel/resolver_factory.h
@@ -55,7 +55,8 @@ struct grpc_resolver_factory_vtable {
   void (*unref)(grpc_resolver_factory *factory);
 
   /** Implementation of grpc_resolver_factory_create_resolver */
-  grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory,
+  grpc_resolver *(*create_resolver)(grpc_exec_ctx *exec_ctx,
+                                    grpc_resolver_factory *factory,
                                     grpc_resolver_args *args);
 
   /** Implementation of grpc_resolver_factory_get_default_authority */
@@ -70,7 +71,8 @@ void grpc_resolver_factory_unref(grpc_resolver_factory *resolver);
 
 /** Create a resolver instance for a name */
 grpc_resolver *grpc_resolver_factory_create_resolver(
-    grpc_resolver_factory *factory, grpc_resolver_args *args);
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args);
 
 /** Return a (freshly allocated with gpr_malloc) string representing
     the default authority to use for this scheme. */
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index a5d7c0df45..2175d2094e 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -46,6 +46,7 @@
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/backoff.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel_init.h"
@@ -206,7 +207,7 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
   gpr_free((void *)c->filters);
   grpc_channel_args_destroy(c->args);
   gpr_free(c->addr);
-  grpc_slice_unref(c->initial_connect_string);
+  grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
   grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
   grpc_connector_unref(exec_ctx, c->connector);
   grpc_pollset_set_destroy(c->pollset_set);
diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c
index 0fbc542ef8..bcb6a1dee4 100644
--- a/src/core/ext/client_channel/uri_parser.c
+++ b/src/core/ext/client_channel/uri_parser.c
@@ -35,14 +35,13 @@
 
 #include <string.h>
 
-#include <grpc/slice.h>
-#include <grpc/slice_buffer.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
 /** a size_t default value... maps to all 1's */
@@ -149,38 +148,38 @@ static void parse_query_parts(grpc_uri *uri) {
     uri->num_query_parts = 0;
     return;
   }
-  grpc_slice query_slice =
-      grpc_slice_new(uri->query, strlen(uri->query), do_nothing);
-  grpc_slice_buffer query_parts; /* the &-separated elements of the query */
-  grpc_slice_buffer query_param_parts; /* the =-separated subelements */
+  gpr_slice query_slice =
+      gpr_slice_new(uri->query, strlen(uri->query), do_nothing);
+  gpr_slice_buffer query_parts; /* the &-separated elements of the query */
+  gpr_slice_buffer query_param_parts; /* the =-separated subelements */
 
-  grpc_slice_buffer_init(&query_parts);
-  grpc_slice_buffer_init(&query_param_parts);
+  gpr_slice_buffer_init(&query_parts);
+  gpr_slice_buffer_init(&query_param_parts);
 
-  grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
+  gpr_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
   uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
   uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
   uri->num_query_parts = query_parts.count;
   for (size_t i = 0; i < query_parts.count; i++) {
-    grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
-                     &query_param_parts);
+    gpr_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
+                    &query_param_parts);
     GPR_ASSERT(query_param_parts.count > 0);
     uri->query_parts[i] =
-        grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
+        gpr_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
     if (query_param_parts.count > 1) {
       /* TODO(dgq): only the first value after the separator is considered.
        * Perhaps all chars after the first separator for the query part should
        * be included, even if they include the separator. */
       uri->query_parts_values[i] =
-          grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
+          gpr_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
     } else {
       uri->query_parts_values[i] = NULL;
     }
-    grpc_slice_buffer_reset_and_unref(&query_param_parts);
+    gpr_slice_buffer_reset_and_unref(&query_param_parts);
   }
-  grpc_slice_buffer_destroy(&query_parts);
-  grpc_slice_buffer_destroy(&query_param_parts);
-  grpc_slice_unref(query_slice);
+  gpr_slice_buffer_destroy(&query_parts);
+  gpr_slice_buffer_destroy(&query_param_parts);
+  gpr_slice_unref(query_slice);
 }
 
 grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 2ae96c5e8d..00c7468326 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -121,6 +121,7 @@
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
@@ -970,7 +971,8 @@ static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg,
 static void srv_status_rcvd_cb(grpc_exec_ctx *exec_ctx, void *arg,
                                grpc_error *error);
 
-static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) {
+static lb_client_data *lb_client_data_create(grpc_exec_ctx *exec_ctx,
+                                             glb_lb_policy *glb_policy) {
   GPR_ASSERT(glb_policy->server_name != NULL);
   GPR_ASSERT(glb_policy->server_name[0] != '\0');
 
@@ -1004,7 +1006,7 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) {
   grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
   lb_client->request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  grpc_slice_unref(request_payload_slice);
+  grpc_slice_unref_internal(exec_ctx, request_payload_slice);
   grpc_grpclb_request_destroy(request);
 
   lb_client->status_details = NULL;
@@ -1035,7 +1037,7 @@ static void query_for_backends(grpc_exec_ctx *exec_ctx,
                                glb_lb_policy *glb_policy) {
   GPR_ASSERT(glb_policy->lb_channel != NULL);
 
-  glb_policy->lb_client = lb_client_data_create(glb_policy);
+  glb_policy->lb_client = lb_client_data_create(exec_ctx, glb_policy);
   grpc_call_error call_error;
   grpc_op ops[1];
   memset(ops, 0, sizeof(ops));
@@ -1126,7 +1128,7 @@ static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     grpc_grpclb_serverlist *serverlist =
         grpc_grpclb_response_parse_serverlist(response_slice);
     if (serverlist != NULL) {
-      grpc_slice_unref(response_slice);
+      grpc_slice_unref_internal(exec_ctx, response_slice);
       if (grpc_lb_glb_trace) {
         gpr_log(GPR_INFO, "Serverlist with %lu servers received",
                 (unsigned long)serverlist->num_servers);
@@ -1185,7 +1187,7 @@ static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     GPR_ASSERT(serverlist == NULL);
     gpr_log(GPR_ERROR, "Invalid LB response received: '%s'",
             grpc_dump_slice(response_slice, GPR_DUMP_ASCII));
-    grpc_slice_unref(response_slice);
+    grpc_slice_unref_internal(exec_ctx, response_slice);
 
     /* Disconnect from server returning invalid response. */
     op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 26a650aadd..a3f13cd61f 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -47,6 +47,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -161,7 +162,8 @@ char *unix_get_default_authority(grpc_resolver_factory *factory,
 
 static void do_nothing(void *ignored) {}
 
-static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
+static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx,
+                                      grpc_resolver_args *args,
                                       int parse(grpc_uri *uri,
                                                 grpc_resolved_address *dst)) {
   if (0 != strcmp(args->uri->authority, "")) {
@@ -188,8 +190,8 @@ static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
     gpr_free(part_str);
     if (errors_found) break;
   }
-  grpc_slice_buffer_destroy(&path_parts);
-  grpc_slice_unref(path_slice);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
+  grpc_slice_unref_internal(exec_ctx, path_slice);
   if (errors_found) {
     grpc_lb_addresses_destroy(addresses);
     return NULL;
@@ -219,8 +221,9 @@ static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
 
 #define DECL_FACTORY(name)                                                  \
   static grpc_resolver *name##_factory_create_resolver(                     \
-      grpc_resolver_factory *factory, grpc_resolver_args *args) {           \
-    return sockaddr_create(args, parse_##name);                             \
+      grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,              \
+      grpc_resolver_args *args) {                                           \
+    return sockaddr_create(exec_ctx, args, parse_##name);                   \
   }                                                                         \
   static const grpc_resolver_factory_vtable name##_factory_vtable = {       \
       sockaddr_factory_ref, sockaddr_factory_unref,                         \
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
index aa2ecf5743..f46e849932 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
@@ -62,7 +62,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
   grpc_endpoint *server_endpoint =
       grpc_tcp_create(grpc_fd_create(fd, name), resource_quota,
                       GRPC_TCP_DEFAULT_READ_SLICE_SIZE, name);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   gpr_free(name);
 
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index 942638ad7f..15ef778ebc 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -98,7 +98,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
         grpc_server_setup_transport(
             exec_ctx, connection_state->server_state->server, transport,
             connection_state->accepting_pollset, args_copy);
-        grpc_channel_args_destroy(args_copy);
+        grpc_channel_args_destroy(exec_ctx, args_copy);
         grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
       } else {
         /* We need to consume this here, because the server may already have
@@ -110,7 +110,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
   } else {
     gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
   }
-  grpc_channel_args_destroy(connection_state->args);
+  grpc_channel_args_destroy(exec_ctx, connection_state->args);
   grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
   gpr_free(connection_state);
 }
@@ -125,7 +125,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
     gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
     grpc_error_free_string(error_str);
     GRPC_ERROR_UNREF(error);
-    grpc_channel_args_destroy(args);
+    grpc_channel_args_destroy(exec_ctx, args);
     gpr_free(read_buffer);
     grpc_handshake_manager_shutdown(exec_ctx, connection_state->handshake_mgr);
     grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c
index 3eef80b557..8db36e4a7f 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c
@@ -34,6 +34,7 @@
 #include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -143,7 +144,8 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx) {
   return true;
 }
 
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
+                                     grpc_slice input) {
   size_t input_length = GRPC_SLICE_LENGTH(input);
   size_t output_length = input_length / 4 * 3;
   struct grpc_base64_decode_context ctx;
@@ -179,7 +181,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
     char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
     gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
     gpr_free(s);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
   GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
@@ -187,7 +189,8 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
   return output;
 }
 
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                                 grpc_slice input,
                                                  size_t output_length) {
   size_t input_length = GRPC_SLICE_LENGTH(input);
   grpc_slice output = grpc_slice_malloc(output_length);
@@ -200,7 +203,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
             "grpc_chttp2_base64_decode_with_length has a length of %d, which "
             "has a tail of 1 byte.\n",
             (int)input_length);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
 
@@ -210,7 +213,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
             "than the max possible output length %d.\n",
             (int)output_length,
             (int)(input_length / 4 * 3 + tail_xtra[input_length % 4]));
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
 
@@ -224,7 +227,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
     char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
     gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
     gpr_free(s);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
   GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h
index 83a90be519..48ffb2ae3b 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h
@@ -55,12 +55,13 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx);
 
 /* base64 decode a slice with pad chars. Returns a new slice, does not take
    ownership of the input. Returns an empty slice if decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input);
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, grpc_slice input);
 
 /* base64 decode a slice without pad chars, data length is needed. Returns a new
    slice, does not take ownership of the input. Returns an empty slice if
    decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                                 grpc_slice input,
                                                  size_t output_length);
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h
index 9e143b46e2..477559d0e2 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h
@@ -47,7 +47,7 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input);
 /* equivalent to:
    grpc_slice x = grpc_chttp2_base64_encode(input);
    grpc_slice y = grpc_chttp2_huffman_compress(x);
-   grpc_slice_unref(x);
+   grpc_slice_unref_internal(exec_ctx, x);
    return y; */
 grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
     grpc_slice input);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 1ffa9165b2..0c61159495 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -51,6 +51,7 @@
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/workqueue.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -144,12 +145,12 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
 
   grpc_endpoint_destroy(exec_ctx, t->ep);
 
-  grpc_slice_buffer_destroy(&t->qbuf);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->qbuf);
 
-  grpc_slice_buffer_destroy(&t->outbuf);
-  grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->outbuf);
+  grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor);
 
-  grpc_slice_buffer_destroy(&t->read_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer);
   grpc_chttp2_hpack_parser_destroy(&t->hpack_parser);
   grpc_chttp2_goaway_parser_destroy(&t->goaway_parser);
 
@@ -532,7 +533,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
   grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser);
   grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]);
   grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]);
-  grpc_slice_buffer_destroy(&s->flow_controlled_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
   GRPC_ERROR_UNREF(s->read_closed_error);
   GRPC_ERROR_UNREF(s->write_closed_error);
 
@@ -761,7 +762,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
   char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
   GRPC_CHTTP2_IF_TRACING(
       gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
-  grpc_slice_unref(goaway_text);
+  grpc_slice_unref_internal(exec_ctx, goaway_text);
   t->seen_goaway = 1;
   /* lie: use transient failure from the transport to indicate goaway has been
    * received */
@@ -1244,7 +1245,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
   if (op->send_goaway) {
     send_goaway(exec_ctx, t,
                 grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
-                grpc_slice_ref(*op->goaway_message));
+                grpc_slice_ref_internal(*op->goaway_message));
   }
 
   if (op->set_accept_stream) {
@@ -1474,21 +1475,22 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
     char status_string[GPR_LTOA_MIN_BUFSIZE];
     gpr_ltoa(status, status_string);
     grpc_chttp2_incoming_metadata_buffer_add(
-        &s->metadata_buffer[1],
-        grpc_mdelem_from_metadata_strings(
-            GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string)));
+        &s->metadata_buffer[1], grpc_mdelem_from_metadata_strings(
+                                    exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+                                    grpc_mdstr_from_string(status_string)));
     if (slice) {
       grpc_chttp2_incoming_metadata_buffer_add(
           &s->metadata_buffer[1],
           grpc_mdelem_from_metadata_strings(
-              GRPC_MDSTR_GRPC_MESSAGE,
-              grpc_mdstr_from_slice(grpc_slice_ref(*slice))));
+              exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+              grpc_mdstr_from_slice(exec_ctx,
+                                    grpc_slice_ref_internal(*slice))));
     }
     s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
     grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
   }
   if (slice) {
-    grpc_slice_unref(*slice);
+    grpc_slice_unref_internal(exec_ctx, *slice);
   }
 }
 
@@ -1862,7 +1864,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
     keep_reading = true;
     GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading");
   }
-  grpc_slice_buffer_reset_and_unref(&t->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->read_buffer);
 
   if (keep_reading) {
     grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin);
@@ -1916,7 +1918,7 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
                                        grpc_chttp2_incoming_byte_stream *bs) {
   if (gpr_unref(&bs->refs)) {
     GRPC_ERROR_UNREF(bs->error);
-    grpc_slice_buffer_destroy(&bs->slices);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
     gpr_mu_destroy(&bs->slice_mu);
     gpr_free(bs);
   }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index eb68fe3138..49a8326f62 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -48,6 +48,7 @@
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
 #include "src/core/ext/transport/chttp2/transport/hpack_table.h"
 #include "src/core/ext/transport/chttp2/transport/varint.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/transport/metadata.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/timeout_encoding.h"
@@ -183,7 +184,8 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) {
 }
 
 /* add an element to the decoder table */
-static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
+static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+                     grpc_mdelem *elem) {
   uint32_t key_hash = elem->key->hash;
   uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
   uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
@@ -227,12 +229,12 @@ static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
   } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
              c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
     /* not there: replace oldest */
-    GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
+    GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
     c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
     c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
   } else {
     /* not there: replace oldest */
-    GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
+    GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
     c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
     c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
   }
@@ -251,11 +253,11 @@ static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
     c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
   } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] <
              c->indices_keys[HASH_FRAGMENT_3(key_hash)]) {
-    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
+    GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
     c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
     c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
   } else {
-    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
+    GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
     c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
     c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
   }
@@ -294,7 +296,7 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c,
                            add_tiny_header_data(st, len_pfx), len_pfx);
   GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
@@ -311,7 +313,7 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
                            add_tiny_header_data(st, len_pfx), len_pfx);
   GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
@@ -327,10 +329,10 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
   *add_tiny_header_data(st, 1) = 0x40;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
-  add_header_data(st, grpc_slice_ref(elem->key->slice));
+  add_header_data(st, grpc_slice_ref_internal(elem->key->slice));
   GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
@@ -346,10 +348,10 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
   *add_tiny_header_data(st, 1) = 0x00;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
-  add_header_data(st, grpc_slice_ref(elem->key->slice));
+  add_header_data(st, grpc_slice_ref_internal(elem->key->slice));
   GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c,
@@ -366,8 +368,8 @@ static uint32_t dynidx(grpc_chttp2_hpack_compressor *c, uint32_t elem_index) {
 }
 
 /* encode an mdelem */
-static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
-                      framer_state *st) {
+static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+                      grpc_mdelem *elem, framer_state *st) {
   uint32_t key_hash = elem->key->hash;
   uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
   size_t decoder_space_usage;
@@ -417,7 +419,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
     /* HIT: key (first cuckoo hash) */
     if (should_add_elem) {
       emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
-      add_elem(c, elem);
+      add_elem(exec_ctx, c, elem);
       return;
     } else {
       emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -432,7 +434,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
     /* HIT: key (first cuckoo hash) */
     if (should_add_elem) {
       emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
-      add_elem(c, elem);
+      add_elem(exec_ctx, c, elem);
       return;
     } else {
       emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -445,7 +447,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
 
   if (should_add_elem) {
     emit_lithdr_incidx_v(c, elem, st);
-    add_elem(c, elem);
+    add_elem(exec_ctx, c, elem);
     return;
   } else {
     emit_lithdr_noidx_v(c, elem, st);
@@ -457,16 +459,17 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
 #define STRLEN_LIT(x) (sizeof(x) - 1)
 #define TIMEOUT_KEY "grpc-timeout"
 
-static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
+static void deadline_enc(grpc_exec_ctx *exec_ctx,
+                         grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
                          framer_state *st) {
   char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
   grpc_mdelem *mdelem;
   grpc_http2_encode_timeout(
       gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
   mdelem = grpc_mdelem_from_metadata_strings(
-      GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
-  hpack_enc(c, mdelem, st);
-  GRPC_MDELEM_UNREF(mdelem);
+      exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
+  hpack_enc(exec_ctx, c, mdelem, st);
+  GRPC_MDELEM_UNREF(exec_ctx, mdelem);
 }
 
 static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; }
@@ -483,11 +486,12 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) {
          sizeof(*c->table_elem_size) * c->cap_table_elems);
 }
 
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+                                          grpc_chttp2_hpack_compressor *c) {
   int i;
   for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
-    if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]);
-    if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
+    if (c->entries_keys[i]) GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[i]);
+    if (c->entries_elems[i]) GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]);
   }
   gpr_free(c->table_elem_size);
 }
@@ -542,7 +546,8 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
   }
 }
 
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hpack_compressor *c,
                                uint32_t stream_id,
                                grpc_metadata_batch *metadata, int is_eof,
                                size_t max_frame_size,
@@ -571,11 +576,11 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
   }
   grpc_metadata_batch_assert_ok(metadata);
   for (l = metadata->list.head; l; l = l->next) {
-    hpack_enc(c, l->md, &st);
+    hpack_enc(exec_ctx, c, l->md, &st);
   }
   deadline = metadata->deadline;
   if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) {
-    deadline_enc(c, deadline, &st);
+    deadline_enc(exec_ctx, c, deadline, &st);
   }
 
   finish_frame(&st, 1, is_eof);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index bcbd675ca2..3a35496ec8 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -83,13 +83,15 @@ typedef struct {
 } grpc_chttp2_hpack_compressor;
 
 void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c);
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+                                          grpc_chttp2_hpack_compressor *c);
 void grpc_chttp2_hpack_compressor_set_max_table_size(
     grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
 void grpc_chttp2_hpack_compressor_set_max_usable_size(
     grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
 
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hpack_compressor *c, uint32_t id,
                                grpc_metadata_batch *metadata, int is_eof,
                                size_t max_frame_size,
                                grpc_transport_one_way_stats *stats,
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 1046c31dda..e805aac8c4 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -669,11 +669,11 @@ static const uint8_t inverse_base64[256] = {
 static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
                           grpc_mdelem *md, int add_to_table) {
   if (add_to_table) {
-    grpc_error *err = grpc_chttp2_hptbl_add(&p->table, md);
+    grpc_error *err = grpc_chttp2_hptbl_add(exec_ctx, &p->table, md);
     if (err != GRPC_ERROR_NONE) return err;
   }
   if (p->on_header == NULL) {
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
     return GRPC_ERROR_CREATE("on_header callback not set");
   }
   p->on_header(exec_ctx, p->on_header_user_data, md);
@@ -814,10 +814,10 @@ static grpc_error *finish_lithdr_incidx(grpc_exec_ctx *exec_ctx,
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      1);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           1);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -827,10 +827,10 @@ static grpc_error *finish_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      1);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           1);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -882,10 +882,10 @@ static grpc_error *finish_lithdr_notidx(grpc_exec_ctx *exec_ctx,
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -895,10 +895,10 @@ static grpc_error *finish_lithdr_notidx_v(grpc_exec_ctx *exec_ctx,
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -950,10 +950,10 @@ static grpc_error *finish_lithdr_nvridx(grpc_exec_ctx *exec_ctx,
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -963,10 +963,10 @@ static grpc_error *finish_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx,
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -1019,7 +1019,7 @@ static grpc_error *finish_max_tbl_size(grpc_exec_ctx *exec_ctx,
     gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
   }
   grpc_error *err =
-      grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index);
+      grpc_chttp2_hptbl_set_current_table_size(exec_ctx, &p->table, p->index);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -1545,7 +1545,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
   p->value.length = 0;
   p->dynamic_table_update_allowed = 2;
   p->last_error = GRPC_ERROR_NONE;
-  grpc_chttp2_hptbl_init(&p->table);
+  grpc_chttp2_hptbl_init(exec_ctx, &p->table);
 }
 
 void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
@@ -1554,7 +1554,7 @@ void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
 }
 
 void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
-  grpc_chttp2_hptbl_destroy(&p->table);
+  grpc_chttp2_hptbl_destroy(exec_ctx, &p->table);
   GRPC_ERROR_UNREF(p->last_error);
   gpr_free(p->key.str);
   gpr_free(p->value.str);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 2dc793d304..26d4036d49 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -179,7 +179,7 @@ static uint32_t entries_for_bytes(uint32_t bytes) {
          GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
 }
 
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
   size_t i;
 
   memset(tbl, 0, sizeof(*tbl));
@@ -190,18 +190,20 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
   tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries);
   memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
   for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
-    tbl->static_ents[i - 1] =
-        grpc_mdelem_from_strings(static_table[i].key, static_table[i].value);
+    tbl->static_ents[i - 1] = grpc_mdelem_from_strings(
+        exec_ctx, static_table[i].key, static_table[i].value);
   }
 }
 
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hptbl *tbl) {
   size_t i;
   for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
-    GRPC_MDELEM_UNREF(tbl->static_ents[i]);
+    GRPC_MDELEM_UNREF(exec_ctx, tbl->static_ents[i]);
   }
   for (i = 0; i < tbl->num_ents; i++) {
-    GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
+    GRPC_MDELEM_UNREF(exec_ctx,
+                      tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
   }
   gpr_free(tbl->ents);
 }
@@ -224,7 +226,7 @@ grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
 }
 
 /* Evict one element from the table */
-static void evict1(grpc_chttp2_hptbl *tbl) {
+static void evict1(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
   grpc_mdelem *first_ent = tbl->ents[tbl->first_ent];
   size_t elem_bytes = GRPC_SLICE_LENGTH(first_ent->key->slice) +
                       GRPC_SLICE_LENGTH(first_ent->value->slice) +
@@ -233,7 +235,7 @@ static void evict1(grpc_chttp2_hptbl *tbl) {
   tbl->mem_used -= (uint32_t)elem_bytes;
   tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries);
   tbl->num_ents--;
-  GRPC_MDELEM_UNREF(first_ent);
+  GRPC_MDELEM_UNREF(exec_ctx, first_ent);
 }
 
 static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) {
@@ -249,7 +251,8 @@ static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) {
   tbl->first_ent = 0;
 }
 
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+                                     grpc_chttp2_hptbl *tbl,
                                      uint32_t max_bytes) {
   if (tbl->max_bytes == max_bytes) {
     return;
@@ -258,12 +261,13 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
     gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
   }
   while (tbl->mem_used > max_bytes) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
   tbl->max_bytes = max_bytes;
 }
 
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+                                                     grpc_chttp2_hptbl *tbl,
                                                      uint32_t bytes) {
   if (tbl->current_table_bytes == bytes) {
     return GRPC_ERROR_NONE;
@@ -281,7 +285,7 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
     gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
   }
   while (tbl->mem_used > bytes) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
   tbl->current_table_bytes = bytes;
   tbl->max_entries = entries_for_bytes(bytes);
@@ -296,7 +300,8 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
   return GRPC_ERROR_NONE;
 }
 
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+                                  grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
   /* determine how many bytes of buffer this entry represents */
   size_t elem_bytes = GRPC_SLICE_LENGTH(md->key->slice) +
                       GRPC_SLICE_LENGTH(md->value->slice) +
@@ -326,14 +331,14 @@ grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
      * empty table.
      */
     while (tbl->num_ents) {
-      evict1(tbl);
+      evict1(exec_ctx, tbl);
     }
     return GRPC_ERROR_NONE;
   }
 
   /* evict entries to ensure no overflow */
   while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
 
   /* copy the finalized entry in */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h
index 2ca130e64b..144574ef06 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.h
@@ -84,18 +84,21 @@ typedef struct {
 } grpc_chttp2_hptbl;
 
 /* initialize a hpack table */
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+                                     grpc_chttp2_hptbl *tbl,
                                      uint32_t max_bytes);
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+                                                     grpc_chttp2_hptbl *tbl,
                                                      uint32_t bytes);
 
 /* lookup a table entry based on its hpack index */
 grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
                                       uint32_t index);
 /* add a table entry to the index */
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+                                  grpc_chttp2_hptbl *tbl,
                                   grpc_mdelem *md) GRPC_MUST_USE_RESULT;
 /* Find a key/value pair in the table... returns the index in the table of the
    most similar entry, or 0 if the value was not found */
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 139e7387c4..d7f45b16ad 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -39,6 +39,7 @@
 
 #include "src/core/ext/transport/chttp2/transport/http2_errors.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 static void add_to_write_list(grpc_chttp2_write_cb **list,
                               grpc_chttp2_write_cb *cb) {
@@ -254,7 +255,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
     }
     GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end");
   }
-  grpc_slice_buffer_reset_and_unref(&t->outbuf);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->outbuf);
   GRPC_ERROR_UNREF(error);
   GPR_TIMER_END("grpc_chttp2_end_write", 0);
 }
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index cfc072c0b5..c956b0febc 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -184,7 +184,7 @@ grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) {
   return b;
 }
 
-void grpc_channel_args_destroy(grpc_channel_args *a) {
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a) {
   size_t i;
   if (!a) return;
   for (i = 0; i < a->num_args; i++) {
@@ -195,7 +195,8 @@ void grpc_channel_args_destroy(grpc_channel_args *a) {
       case GRPC_ARG_INTEGER:
         break;
       case GRPC_ARG_POINTER:
-        a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p);
+        a->args[i].value.pointer.vtable->destroy(exec_ctx,
+                                                 a->args[i].value.pointer.p);
         break;
     }
     gpr_free(a->args[i].key);
@@ -249,7 +250,8 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args *a,
 }
 
 grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
-    grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+    grpc_compression_algorithm algorithm, int state) {
   int *states_arg = NULL;
   grpc_channel_args *result = *a;
   const int states_arg_found =
@@ -282,7 +284,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
       GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
     }
     result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
-    grpc_channel_args_destroy(*a);
+    grpc_channel_args_destroy(exec_ctx, *a);
     *a = result;
   }
   return result;
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 1e05303471..5933133413 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -67,7 +67,7 @@ grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a,
                                            const grpc_channel_args *b);
 
 /** Destroy arguments created by \a grpc_channel_args_copy */
-void grpc_channel_args_destroy(grpc_channel_args *a);
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a);
 
 /** Returns the compression algorithm set in \a a. */
 grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
@@ -87,7 +87,8 @@ grpc_channel_args *grpc_channel_args_set_compression_algorithm(
  * modified to point to the returned instance (which may be different from the
  * input value of \a a). */
 grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
-    grpc_channel_args **a, grpc_compression_algorithm algorithm, int enabled);
+    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+    grpc_compression_algorithm algorithm, int enabled);
 
 /** Returns the bitset representing the support state (true for enabled, false
  * for disabled) for compression algorithms.
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 9da81959e7..c32e7e6277 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -292,7 +292,7 @@ void grpc_call_element_send_cancel_with_message(grpc_exec_ctx *exec_ctx,
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
   op->on_complete = grpc_closure_create(destroy_op, op);
-  grpc_transport_stream_op_add_cancellation_with_message(op, status,
+  grpc_transport_stream_op_add_cancellation_with_message(exec_ctx, op, status,
                                                          optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
@@ -304,6 +304,6 @@ void grpc_call_element_send_close_with_message(grpc_exec_ctx *exec_ctx,
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
   op->on_complete = grpc_closure_create(destroy_op, op);
-  grpc_transport_stream_op_add_close(op, status, optional_message);
+  grpc_transport_stream_op_add_close(exec_ctx, op, status, optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index eda4968f48..366bd0de29 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -138,9 +138,10 @@ void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder,
 }
 
 void grpc_channel_stack_builder_set_channel_arguments(
-    grpc_channel_stack_builder *builder, const grpc_channel_args *args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    const grpc_channel_args *args) {
   if (builder->args != NULL) {
-    grpc_channel_args_destroy(builder->args);
+    grpc_channel_args_destroy(exec_ctx, builder->args);
   }
   builder->args = grpc_channel_args_copy(args);
 }
@@ -213,7 +214,8 @@ bool grpc_channel_stack_builder_add_filter_after(
   return true;
 }
 
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder) {
   filter_node *p = builder->begin.next;
   while (p != &builder->end) {
     filter_node *next = p->next;
@@ -221,7 +223,7 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
     p = next;
   }
   if (builder->args != NULL) {
-    grpc_channel_args_destroy(builder->args);
+    grpc_channel_args_destroy(exec_ctx, builder->args);
   }
   gpr_free(builder->target);
   gpr_free(builder);
@@ -270,7 +272,7 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
     i++;
   }
 
-  grpc_channel_stack_builder_destroy(builder);
+  grpc_channel_stack_builder_destroy(exec_ctx, builder);
   gpr_free((grpc_channel_filter **)filters);
 
   return result;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 4a00f7bfdb..3532819a0c 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -73,7 +73,8 @@ grpc_transport *grpc_channel_stack_builder_get_transport(
 
 /// Set channel arguments: copies args
 void grpc_channel_stack_builder_set_channel_arguments(
-    grpc_channel_stack_builder *builder, const grpc_channel_args *args);
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    const grpc_channel_args *args);
 
 /// Return a borrowed pointer to the channel arguments
 const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments(
@@ -158,7 +159,8 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
                                         void *destroy_arg);
 
 /// Destroy the builder without creating a channel stack
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder);
 
 extern int grpc_trace_channel_stack_builder;
 
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index de71bcc22b..9cb52627ce 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/message_compress.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 
@@ -126,12 +127,14 @@ static int skip_compression(grpc_call_element *elem) {
 
 /** Filter initial metadata */
 static void process_send_initial_metadata(
-    grpc_call_element *elem, grpc_metadata_batch *initial_metadata) {
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_metadata_batch *initial_metadata) {
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
   /* Parse incoming request for compression. If any, it'll be available
    * at calld->compression_algorithm */
-  grpc_metadata_batch_filter(initial_metadata, compression_md_filter, elem);
+  grpc_metadata_batch_filter(exec_ctx, initial_metadata, compression_md_filter,
+                             elem);
   if (!calld->has_compression_algorithm) {
     /* If no algorithm was found in the metadata and we aren't
      * exceptionally skipping compression, fall back to the channel
@@ -157,7 +160,7 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
 static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_reset_and_unref(&calld->slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
   calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
 }
 
@@ -167,8 +170,8 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
   int did_compress;
   grpc_slice_buffer tmp;
   grpc_slice_buffer_init(&tmp);
-  did_compress =
-      grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp);
+  did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm,
+                                   &calld->slices, &tmp);
   if (did_compress) {
     if (grpc_compression_trace) {
       char *algo_name;
@@ -195,7 +198,7 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
     }
   }
 
-  grpc_slice_buffer_destroy(&tmp);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &tmp);
 
   grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
                                 calld->send_flags);
@@ -239,7 +242,7 @@ static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
   GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0);
 
   if (op->send_initial_metadata) {
-    process_send_initial_metadata(elem, op->send_initial_metadata);
+    process_send_initial_metadata(exec_ctx, elem, op->send_initial_metadata);
   }
   if (op->send_message != NULL && !skip_compression(elem) &&
       0 == (op->send_message->flags & GRPC_WRITE_NO_COMPRESS)) {
@@ -277,7 +280,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               void *ignored) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->slices);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
 }
 
 /* Constructor for channel_data */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 449eb7b8d6..3b24e52ff4 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 //
 // grpc_deadline_state
@@ -58,7 +59,7 @@ static void timer_callback(grpc_exec_ctx* exec_ctx, void* arg,
     grpc_slice msg = grpc_slice_from_static_string("Deadline Exceeded");
     grpc_call_element_send_cancel_with_message(
         exec_ctx, elem, GRPC_STATUS_DEADLINE_EXCEEDED, &msg);
-    grpc_slice_unref(msg);
+    grpc_slice_unref_internal(exec_ctx, msg);
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
 }
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 0714f31bdd..026e4d486e 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -36,6 +36,7 @@
 #include <grpc/support/string_util.h>
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/transport_impl.h"
@@ -136,8 +137,8 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
   client_recv_filter_args a;
   a.elem = elem;
   a.exec_ctx = exec_ctx;
-  grpc_metadata_batch_filter(calld->recv_initial_metadata, client_recv_filter,
-                             &a);
+  grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                             client_recv_filter, &a);
   calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
 }
 
@@ -155,7 +156,7 @@ static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
 static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_reset_and_unref(&calld->slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
   calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
 }
 
@@ -244,7 +245,7 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
         /* when all the send_message data is available, then create a MDELEM and
         append to headers */
         grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
-            GRPC_MDSTR_GRPC_PAYLOAD_BIN,
+            exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN,
             grpc_mdstr_from_buffer(calld->payload_bytes,
                                    op->send_message->length));
         grpc_metadata_batch_add_tail(op->send_initial_metadata,
@@ -261,8 +262,8 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
       }
     }
 
-    grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
-                               elem);
+    grpc_metadata_batch_filter(exec_ctx, op->send_initial_metadata,
+                               client_strip_filter, elem);
     /* Send : prefixed headers, which have to be before any application
        layer headers. */
     grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
@@ -324,7 +325,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->slices);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
 }
 
 static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
@@ -425,7 +426,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->max_payload_size_for_get =
       max_payload_size_from_args(args->channel_args);
   chand->user_agent = grpc_mdelem_from_metadata_strings(
-      GRPC_MDSTR_USER_AGENT,
+      exec_ctx, GRPC_MDSTR_USER_AGENT,
       user_agent_from_args(args->channel_args,
                            args->optional_transport->vtable->name));
 }
@@ -434,7 +435,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {
   channel_data *chand = elem->channel_data;
-  GRPC_MDELEM_UNREF(chand->user_agent);
+  GRPC_MDELEM_UNREF(exec_ctx, chand->user_agent);
 }
 
 const grpc_channel_filter grpc_http_client_filter = {
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index 10631850cd..d09a2b13ee 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -37,6 +37,7 @@
 #include <grpc/support/log.h>
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 #define EXPECTED_CONTENT_TYPE "application/grpc"
@@ -155,7 +156,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
     /* translate host to :authority since :authority may be
        omitted */
     grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
-        GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
+        a->exec_ctx, GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
     calld->seen_authority = 1;
     return authority;
   } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) {
@@ -164,7 +165,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
     calld->seen_payload_bin = 1;
     grpc_slice_buffer_init(&calld->read_slice_buffer);
     grpc_slice_buffer_add(&calld->read_slice_buffer,
-                          grpc_slice_ref(md->value->slice));
+                          grpc_slice_ref_internal(md->value->slice));
     grpc_slice_buffer_stream_init(&calld->read_stream,
                                   &calld->read_slice_buffer, 0);
     return NULL;
@@ -181,7 +182,8 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
     server_filter_args a;
     a.elem = elem;
     a.exec_ctx = exec_ctx;
-    grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a);
+    grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                               server_filter, &a);
     /* Have we seen the required http2 transport headers?
        (:method, :scheme, content-type, with :path and :authority covered
        at the channel level right now) */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 85c307702f..50118b52fd 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -66,8 +66,10 @@ static int message_size_limits_cmp(void* value1, void* value2) {
   return 0;
 }
 
+static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); }
+
 static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = {
-    gpr_free, message_size_limits_copy, message_size_limits_cmp};
+    free_mem, message_size_limits_copy, message_size_limits_cmp};
 
 static void* method_config_convert_value(
     const grpc_method_config* method_config) {
@@ -171,8 +173,8 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
   calld->max_send_size = chand->max_send_size;
   calld->max_recv_size = chand->max_recv_size;
   if (chand->method_limit_table != NULL) {
-    message_size_limits* limits =
-        grpc_method_config_table_get(chand->method_limit_table, args->path);
+    message_size_limits* limits = grpc_method_config_table_get(
+        exec_ctx, chand->method_limit_table, args->path);
     if (limits != NULL) {
       if (limits->max_send_size >= 0 &&
           (limits->max_send_size < calld->max_send_size ||
@@ -225,7 +227,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
   if (channel_arg != NULL) {
     GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
     chand->method_limit_table = grpc_method_config_table_convert(
-        (grpc_method_config_table*)channel_arg->value.pointer.p,
+        exec_ctx, (grpc_method_config_table*)channel_arg->value.pointer.p,
         method_config_convert_value, &message_size_limits_vtable);
   }
 }
@@ -234,7 +236,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
                                  grpc_channel_element* elem) {
   channel_data* chand = elem->channel_data;
-  grpc_mdstr_hash_table_unref(chand->method_limit_table);
+  grpc_mdstr_hash_table_unref(exec_ctx, chand->method_limit_table);
 }
 
 const grpc_channel_filter grpc_message_size_filter = {
diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c
index 6c245acf61..49beb953b0 100644
--- a/src/core/lib/compression/message_compress.c
+++ b/src/core/lib/compression/message_compress.c
@@ -40,10 +40,12 @@
 
 #include <zlib.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 #define OUTPUT_BLOCK_SIZE 1024
 
-static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
-                     grpc_slice_buffer* output,
+static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
+                     grpc_slice_buffer* input, grpc_slice_buffer* output,
                      int (*flate)(z_stream* zs, int flush)) {
   int r;
   int flush;
@@ -87,7 +89,7 @@ static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
   return 1;
 
 error:
-  grpc_slice_unref(outbuf);
+  grpc_slice_unref_internal(exec_ctx, outbuf);
   return 0;
 }
 
@@ -97,8 +99,8 @@ static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) {
 
 static void zfree_gpr(void* opaque, void* address) { gpr_free(address); }
 
-static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
-                         int gzip) {
+static int zlib_compress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+                         grpc_slice_buffer* output, int gzip) {
   z_stream zs;
   int r;
   size_t i;
@@ -110,10 +112,11 @@ static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
   r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
                    8, Z_DEFAULT_STRATEGY);
   GPR_ASSERT(r == Z_OK);
-  r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
+  r = zlib_body(exec_ctx, &zs, input, output, deflate) &&
+      output->length < input->length;
   if (!r) {
     for (i = count_before; i < output->count; i++) {
-      grpc_slice_unref(output->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, output->slices[i]);
     }
     output->count = count_before;
     output->length = length_before;
@@ -122,8 +125,8 @@ static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
   return r;
 }
 
-static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
-                           int gzip) {
+static int zlib_decompress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+                           grpc_slice_buffer* output, int gzip) {
   z_stream zs;
   int r;
   size_t i;
@@ -134,10 +137,10 @@ static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
   zs.zfree = zfree_gpr;
   r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
   GPR_ASSERT(r == Z_OK);
-  r = zlib_body(&zs, input, output, inflate);
+  r = zlib_body(exec_ctx, &zs, input, output, inflate);
   if (!r) {
     for (i = count_before; i < output->count; i++) {
-      grpc_slice_unref(output->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, output->slices[i]);
     }
     output->count = count_before;
     output->length = length_before;
@@ -149,12 +152,13 @@ static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
 static int copy(grpc_slice_buffer* input, grpc_slice_buffer* output) {
   size_t i;
   for (i = 0; i < input->count; i++) {
-    grpc_slice_buffer_add(output, grpc_slice_ref(input->slices[i]));
+    grpc_slice_buffer_add(output, grpc_slice_ref_internal(input->slices[i]));
   }
   return 1;
 }
 
-static int compress_inner(grpc_compression_algorithm algorithm,
+static int compress_inner(grpc_exec_ctx* exec_ctx,
+                          grpc_compression_algorithm algorithm,
                           grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
     case GRPC_COMPRESS_NONE:
@@ -162,9 +166,9 @@ static int compress_inner(grpc_compression_algorithm algorithm,
          rely on that here */
       return 0;
     case GRPC_COMPRESS_DEFLATE:
-      return zlib_compress(input, output, 0);
+      return zlib_compress(exec_ctx, input, output, 0);
     case GRPC_COMPRESS_GZIP:
-      return zlib_compress(input, output, 1);
+      return zlib_compress(exec_ctx, input, output, 1);
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
@@ -172,24 +176,26 @@ static int compress_inner(grpc_compression_algorithm algorithm,
   return 0;
 }
 
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+                      grpc_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output) {
-  if (!compress_inner(algorithm, input, output)) {
+  if (!compress_inner(exec_ctx, algorithm, input, output)) {
     copy(input, output);
     return 0;
   }
   return 1;
 }
 
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+                        grpc_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
     case GRPC_COMPRESS_NONE:
       return copy(input, output);
     case GRPC_COMPRESS_DEFLATE:
-      return zlib_decompress(input, output, 0);
+      return zlib_decompress(exec_ctx, input, output, 0);
     case GRPC_COMPRESS_GZIP:
-      return zlib_decompress(input, output, 1);
+      return zlib_decompress(exec_ctx, input, output, 1);
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h
index 448d36a863..7bd3d98607 100644
--- a/src/core/lib/compression/message_compress.h
+++ b/src/core/lib/compression/message_compress.h
@@ -40,13 +40,15 @@
 /* compress 'input' to 'output' using 'algorithm'.
    On success, appends compressed slices to output and returns 1.
    On failure, appends uncompressed slices to output and returns 0. */
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+                      grpc_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 /* decompress 'input' to 'output' using 'algorithm'.
    On success, appends slices to output and returns 1.
    On failure, output is unchanged, and returns 0. */
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+                        grpc_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 #endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index fdb8abaa2d..6bab7ef275 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -47,6 +47,7 @@
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 
 typedef struct {
@@ -111,14 +112,14 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
   if (req->ep != NULL) {
     grpc_endpoint_destroy(exec_ctx, req->ep);
   }
-  grpc_slice_unref(req->request_text);
+  grpc_slice_unref_internal(exec_ctx, req->request_text);
   gpr_free(req->host);
   gpr_free(req->ssl_host_override);
   grpc_iomgr_unregister_object(&req->iomgr_obj);
-  grpc_slice_buffer_destroy(&req->incoming);
-  grpc_slice_buffer_destroy(&req->outgoing);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &req->incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &req->outgoing);
   GRPC_ERROR_UNREF(req->overall_error);
-  grpc_resource_quota_internal_unref(exec_ctx, req->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, req->resource_quota);
   gpr_free(req);
 }
 
@@ -178,7 +179,7 @@ static void done_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 }
 
 static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) {
-  grpc_slice_ref(req->request_text);
+  grpc_slice_ref_internal(req->request_text);
   grpc_slice_buffer_add(&req->outgoing, req->request_text);
   grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write);
 }
@@ -265,7 +266,7 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
   req->context = context;
   req->pollent = pollent;
   req->overall_error = GRPC_ERROR_NONE;
-  req->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+  req->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure_init(&req->on_read, on_read, req);
   grpc_closure_init(&req->done_write, done_write, req);
   grpc_slice_buffer_init(&req->incoming);
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index ddc7a88c5b..eac7c52c51 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -169,14 +169,14 @@ static void rq_step(grpc_exec_ctx *exec_ctx, void *rq, grpc_error *error) {
   rq_reclaim(exec_ctx, resource_quota, false) ||
       rq_reclaim(exec_ctx, resource_quota, true);
 done:
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 static void rq_step_sched(grpc_exec_ctx *exec_ctx,
                           grpc_resource_quota *resource_quota) {
   if (resource_quota->step_scheduled) return;
   resource_quota->step_scheduled = true;
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
   grpc_combiner_execute_finally(exec_ctx, resource_quota->combiner,
                                 &resource_quota->rq_step_closure,
                                 GRPC_ERROR_NONE, false);
@@ -257,7 +257,7 @@ static bool rq_reclaim(grpc_exec_ctx *exec_ctx,
             destructive ? "destructive" : "benign");
   }
   resource_quota->reclaiming = true;
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure *c = resource_user->reclaimers[destructive];
   resource_user->reclaimers[destructive] = NULL;
   grpc_closure_run(exec_ctx, c, GRPC_ERROR_NONE);
@@ -280,21 +280,10 @@ static void ru_slice_ref(void *p) {
   gpr_ref(&rc->refs);
 }
 
-static void ru_slice_unref(void *p) {
+static void ru_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   ru_slice_refcount *rc = p;
   if (gpr_unref(&rc->refs)) {
-    /* TODO(ctiller): this is dangerous, but I think safe for now:
-       we have no guarantee here that we're at a safe point for creating an
-       execution context, but we have no way of writing this code otherwise.
-       In the future: consider lifting grpc_slice to grpc, and offering an
-       internal_{ref,unref} pair that is execution context aware.
-       Alternatively,
-       make exec_ctx be thread local and 'do the right thing' (whatever that
-       is)
-       if NULL */
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_resource_user_free(&exec_ctx, rc->resource_user, rc->size);
-    grpc_exec_ctx_finish(&exec_ctx);
+    grpc_resource_user_free(exec_ctx, rc->resource_user, rc->size);
     gpr_free(rc);
   }
 }
@@ -419,7 +408,7 @@ static void rq_resize(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
   a->resource_quota->size += delta;
   a->resource_quota->free_pool += delta;
   rq_step_sched(exec_ctx, a->resource_quota);
-  grpc_resource_quota_internal_unref(exec_ctx, a->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, a->resource_quota);
   gpr_free(a);
 }
 
@@ -428,7 +417,7 @@ static void rq_reclamation_done(grpc_exec_ctx *exec_ctx, void *rq,
   grpc_resource_quota *resource_quota = rq;
   resource_quota->reclaiming = false;
   rq_step_sched(exec_ctx, resource_quota);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 /*******************************************************************************
@@ -459,7 +448,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
   return resource_quota;
 }
 
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_resource_quota *resource_quota) {
   if (gpr_unref(&resource_quota->refs)) {
     grpc_combiner_destroy(exec_ctx, resource_quota->combiner);
@@ -471,11 +460,11 @@ void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
 /* Public API */
 void grpc_resource_quota_unref(grpc_resource_quota *resource_quota) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
     grpc_resource_quota *resource_quota) {
   gpr_ref(&resource_quota->refs);
   return resource_quota;
@@ -483,7 +472,7 @@ grpc_resource_quota *grpc_resource_quota_internal_ref(
 
 /* Public API */
 void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
 }
 
 /* Public API */
@@ -491,7 +480,7 @@ void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
                                 size_t size) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   rq_resize_args *a = gpr_malloc(sizeof(*a));
-  a->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+  a->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
   a->size = (int64_t)size;
   grpc_closure_init(&a->closure, rq_resize, a);
   grpc_combiner_execute(&exec_ctx, resource_quota->combiner, &a->closure,
@@ -508,7 +497,7 @@ grpc_resource_quota *grpc_resource_quota_from_channel_args(
   for (size_t i = 0; i < channel_args->num_args; i++) {
     if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
       if (channel_args->args[i].type == GRPC_ARG_POINTER) {
-        return grpc_resource_quota_internal_ref(
+        return grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       } else {
         gpr_log(GPR_DEBUG, GRPC_ARG_RESOURCE_QUOTA " should be a pointer");
@@ -523,7 +512,9 @@ static void *rq_copy(void *rq) {
   return rq;
 }
 
-static void rq_destroy(void *rq) { grpc_resource_quota_unref(rq); }
+static void rq_destroy(grpc_exec_ctx *exec_ctx, void *rq) {
+  grpc_resource_quota_unref_internal(exec_ctx, rq);
+}
 
 static int rq_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
 
@@ -540,7 +531,7 @@ void grpc_resource_user_init(grpc_resource_user *resource_user,
                              grpc_resource_quota *resource_quota,
                              const char *name) {
   resource_user->resource_quota =
-      grpc_resource_quota_internal_ref(resource_quota);
+      grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
                     resource_user);
   grpc_closure_init(&resource_user->add_to_free_pool_closure,
@@ -589,7 +580,7 @@ void grpc_resource_user_shutdown(grpc_exec_ctx *exec_ctx,
 
 void grpc_resource_user_destroy(grpc_exec_ctx *exec_ctx,
                                 grpc_resource_user *resource_user) {
-  grpc_resource_quota_internal_unref(exec_ctx, resource_user->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_user->resource_quota);
   gpr_mu_destroy(&resource_user->mu);
   gpr_free(resource_user->name);
 }
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index f7e5ca6494..f1da73933e 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -77,9 +77,9 @@
 
 extern int grpc_resource_quota_trace;
 
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
     grpc_resource_quota *resource_quota);
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_resource_quota *resource_quota);
 grpc_resource_quota *grpc_resource_quota_from_channel_args(
     const grpc_channel_args *channel_args);
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index bc08c94ee0..3b0fe3bc15 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -116,7 +116,7 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
   if (done) {
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_str);
-    grpc_channel_args_destroy(ac->channel_args);
+    grpc_channel_args_destroy(exec_ctx, ac->channel_args);
     gpr_free(ac);
   }
 }
@@ -136,8 +136,8 @@ grpc_endpoint *grpc_tcp_client_create_from_fd(
             &channel_args->args[i], options);
       } else if (0 ==
                  strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
@@ -145,7 +145,7 @@ grpc_endpoint *grpc_tcp_client_create_from_fd(
 
   grpc_endpoint *ep =
       grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   return ep;
 }
 
@@ -247,7 +247,7 @@ finish:
   if (done) {
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_str);
-    grpc_channel_args_destroy(ac->channel_args);
+    grpc_channel_args_destroy(exec_ctx, ac->channel_args);
     gpr_free(ac);
   }
   grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 4d1e809872..4ad417f77d 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -71,7 +71,7 @@ static void async_connect_unlock_and_cleanup(grpc_exec_ctx *exec_ctx,
   int done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
   if (done) {
-    grpc_resource_quota_internal_unref(exec_ctx, ac->resource_quota);
+    grpc_resource_quota_unref_internal(exec_ctx, ac->resource_quota);
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_name);
     gpr_free(ac);
@@ -153,8 +153,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
   if (channel_args != NULL) {
     for (size_t i = 0; i < channel_args->num_args; i++) {
       if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
@@ -242,7 +242,7 @@ failure:
   } else if (sock != INVALID_SOCKET) {
     closesocket(sock);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
 }
 
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 584fc2fe2e..4bf13bee27 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -56,6 +56,7 @@
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -131,7 +132,7 @@ static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
 static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
   grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
                  "tcp_unref_orphan");
-  grpc_slice_buffer_destroy(&tcp->last_read_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &tcp->last_read_buffer);
   grpc_resource_user_destroy(exec_ctx, &tcp->resource_user);
   gpr_free(tcp->peer_string);
   gpr_free(tcp);
@@ -178,7 +179,7 @@ static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
   grpc_network_status_unregister_endpoint(ep);
   grpc_tcp *tcp = (grpc_tcp *)ep;
   tcp_maybe_shutdown_resource_user(exec_ctx, tcp);
-  grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
   TCP_UNREF(exec_ctx, tcp, "destroy");
 }
 
@@ -245,13 +246,14 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
       /* We've consumed the edge, request a new one */
       grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
     } else {
-      grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                                 tcp->incoming_buffer);
       call_read_cb(exec_ctx, tcp, GRPC_OS_ERROR(errno, "recvmsg"));
       TCP_UNREF(exec_ctx, tcp, "read");
     }
   } else if (read_bytes == 0) {
     /* 0 read size ==> end of stream */
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_CREATE("Socket closed"));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
@@ -276,8 +278,9 @@ static void tcp_read_allocation_done(grpc_exec_ctx *exec_ctx, void *tcpp,
                                      grpc_error *error) {
   grpc_tcp *tcp = tcpp;
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
-    grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               &tcp->last_read_buffer);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
@@ -302,8 +305,9 @@ static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
   GPR_ASSERT(!tcp->finished_edge);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
-    grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               &tcp->last_read_buffer);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
@@ -317,7 +321,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   GPR_ASSERT(tcp->read_cb == NULL);
   tcp->read_cb = cb;
   tcp->incoming_buffer = incoming_buffer;
-  grpc_slice_buffer_reset_and_unref(incoming_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, incoming_buffer);
   grpc_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer);
   TCP_REF(tcp, "read");
   if (tcp->finished_edge) {
@@ -578,7 +582,7 @@ void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   tcp->release_fd = fd;
   tcp->release_fd_cb = done;
   tcp_maybe_shutdown_resource_user(exec_ctx, tcp);
-  grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
   TCP_UNREF(exec_ctx, tcp, "destroy");
 }
 
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index b6fc1e4ca2..1a753d1231 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -167,18 +167,18 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
         s->so_reuseport =
             has_so_reuseport && (args->args[i].value.integer != 0);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
                                  " must be an integer");
       }
     } else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -219,7 +219,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
     gpr_free(sp);
   }
 
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
 
   gpr_free(s);
 }
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index ae54c70d2d..c2a6d1736e 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -115,11 +115,11 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -155,7 +155,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
     grpc_winsocket_destroy(sp->socket);
     gpr_free(sp);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
   gpr_free(s);
 }
 
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index f825057c0e..a97b1b21fe 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -190,13 +190,13 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
       char *utf8_message = gpr_format_message(info->wsa_error);
       error = GRPC_ERROR_CREATE(utf8_message);
       gpr_free(utf8_message);
-      grpc_slice_unref(tcp->read_slice);
+      grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
     } else {
       if (info->bytes_transfered != 0 && !tcp->shutting_down) {
         sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
         grpc_slice_buffer_add(tcp->read_slices, sub);
       } else {
-        grpc_slice_unref(tcp->read_slice);
+        grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
         error = GRPC_ERROR_CREATE("End of TCP stream");
       }
     }
@@ -225,7 +225,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   tcp->read_cb = cb;
   tcp->read_slices = read_slices;
-  grpc_slice_buffer_reset_and_unref(read_slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
 
   tcp->read_slice = grpc_slice_malloc(8192);
 
diff --git a/src/core/lib/security/credentials/credentials_metadata.c b/src/core/lib/security/credentials/credentials_metadata.c
index e6cb567734..84e2b8991a 100644
--- a/src/core/lib/security/credentials/credentials_metadata.c
+++ b/src/core/lib/security/credentials/credentials_metadata.c
@@ -62,8 +62,8 @@ void grpc_credentials_md_store_add(grpc_credentials_md_store *store,
                                    grpc_slice key, grpc_slice value) {
   if (store == NULL) return;
   store_ensure_capacity(store);
-  store->entries[store->num_entries].key = grpc_slice_ref(key);
-  store->entries[store->num_entries].value = grpc_slice_ref(value);
+  store->entries[store->num_entries].key = grpc_slice_ref_internal(key);
+  store->entries[store->num_entries].value = grpc_slice_ref_internal(value);
   store->num_entries++;
 }
 
@@ -91,8 +91,8 @@ void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) {
     if (store->entries != NULL) {
       size_t i;
       for (i = 0; i < store->num_entries; i++) {
-        grpc_slice_unref(store->entries[i].key);
-        grpc_slice_unref(store->entries[i].value);
+        grpc_slice_unref_internal(exec_ctx, store->entries[i].key);
+        grpc_slice_unref_internal(exec_ctx, store->entries[i].value);
       }
       gpr_free(store->entries);
     }
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index afe0e3d357..5df97e1671 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -132,7 +132,7 @@ static int is_stack_running_on_compute_engine(void) {
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       grpc_closure_create(on_compute_engine_detection_http_response, &detector),
       &detector.response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   grpc_exec_ctx_flush(&exec_ctx);
 
@@ -225,7 +225,7 @@ static grpc_error *create_default_creds_from_path(
 end:
   GPR_ASSERT((result == NULL) + (error == GRPC_ERROR_NONE) == 1);
   if (creds_path != NULL) gpr_free(creds_path);
-  grpc_slice_unref(creds_data);
+  grpc_slice_unref_internal(exec_ctx, creds_data);
   if (json != NULL) grpc_json_destroy(json);
   *creds = result;
   return error;
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 42bd89dd0a..d551a7c51a 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -96,7 +96,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
   json = grpc_json_parse_string_with_len((char *)GRPC_SLICE_START_PTR(*buffer),
                                          GRPC_SLICE_LENGTH(*buffer));
   if (json == NULL) {
-    grpc_slice_unref(*buffer);
+    grpc_slice_unref_internal(exec_ctx, *buffer);
     gpr_log(GPR_ERROR, "JSON parsing error.");
   }
   return json;
@@ -133,7 +133,7 @@ typedef struct {
 } jose_header;
 
 static void jose_header_destroy(jose_header *h) {
-  grpc_slice_unref(h->buffer);
+  grpc_slice_unref_internal(exec_ctx, h->buffer);
   gpr_free(h);
 }
 
@@ -195,7 +195,7 @@ struct grpc_jwt_claims {
 
 void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) {
   grpc_json_destroy(claims->json);
-  grpc_slice_unref(claims->buffer);
+  grpc_slice_unref_internal(exec_ctx, claims->buffer);
   gpr_free(claims);
 }
 
@@ -365,8 +365,8 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
 void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
   if (ctx->audience != NULL) gpr_free(ctx->audience);
   if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims);
-  grpc_slice_unref(ctx->signature);
-  grpc_slice_unref(ctx->signed_data);
+  grpc_slice_unref_internal(exec_ctx, ctx->signature);
+  grpc_slice_unref_internal(exec_ctx, ctx->signed_data);
   jose_header_destroy(ctx->header);
   for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
     grpc_http_response_destroy(&ctx->responses[i]);
@@ -459,7 +459,7 @@ static BIGNUM *bignum_from_base64(const char *b64) {
   }
   result = BN_bin2bn(GRPC_SLICE_START_PTR(bin),
                      TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL);
-  grpc_slice_unref(bin);
+  grpc_slice_unref_internal(exec_ctx, bin);
   return result;
 }
 
@@ -667,7 +667,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       grpc_closure_create(on_keys_retrieved, ctx),
       &ctx->responses[HTTP_RESPONSE_KEYS]);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   grpc_json_destroy(json);
   gpr_free(req.host);
   return;
@@ -779,7 +779,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
       exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       http_cb, &ctx->responses[rsp_idx]);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   gpr_free(req.host);
   gpr_free(req.http.path);
   return;
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index d980577c46..09140bef57 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -315,7 +315,7 @@ static void compute_engine_fetch_oauth2(
   grpc_httpcli_get(exec_ctx, httpcli_context, pollent, resource_quota, &request,
                    deadline, grpc_closure_create(response_cb, metadata_req),
                    &metadata_req->response);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 grpc_call_credentials *grpc_google_compute_engine_credentials_create(
@@ -372,7 +372,7 @@ static void refresh_token_fetch_oauth2(
                     &request, body, strlen(body), deadline,
                     grpc_closure_create(response_cb, metadata_req),
                     &metadata_req->response);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   gpr_free(body);
 }
 
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.c
index 61c10862da..16cbb17f46 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.c
@@ -100,8 +100,8 @@ static void plugin_md_request_metadata_ready(void *request,
       r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK,
             NULL);
       for (i = 0; i < num_md; i++) {
-        grpc_slice_unref(md_array[i].key);
-        grpc_slice_unref(md_array[i].value);
+        grpc_slice_unref_internal(exec_ctx, md_array[i].key);
+        grpc_slice_unref_internal(exec_ctx, md_array[i].value);
       }
       gpr_free(md_array);
     }
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index cd4769ea10..22ca99eff8 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -121,8 +121,8 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
   for (i = 0; i < num_md; i++) {
     grpc_metadata_batch_add_tail(
         mdb, &calld->md_links[i],
-        grpc_mdelem_from_slices(grpc_slice_ref(md_elems[i].key),
-                                grpc_slice_ref(md_elems[i].value)));
+        grpc_mdelem_from_slices(grpc_slice_ref_internal(md_elems[i].key),
+                                grpc_slice_ref_internal(md_elems[i].value)));
   }
   grpc_call_next_op(exec_ctx, elem, op);
 }
diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c
index 01e7fab773..077c1f0aa7 100644
--- a/src/core/lib/security/transport/handshake.c
+++ b/src/core/lib/security/transport/handshake.c
@@ -104,9 +104,9 @@ static void unref_handshake(grpc_security_handshake *h) {
   if (gpr_unref(&h->refs)) {
     if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
     if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
-    grpc_slice_buffer_destroy(&h->left_overs);
-    grpc_slice_buffer_destroy(&h->outgoing);
-    grpc_slice_buffer_destroy(&h->incoming);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->left_overs);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->incoming);
     GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
     GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
     gpr_free(h);
@@ -213,7 +213,7 @@ static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx,
 
   to_send =
       grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
-  grpc_slice_buffer_reset_and_unref(&h->outgoing);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing);
   grpc_slice_buffer_add(&h->outgoing, to_send);
   /* TODO(klempner,jboeuf): This should probably use the client setup
      deadline */
@@ -280,7 +280,7 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
     grpc_slice_buffer_add(
         &h->left_overs,
         grpc_slice_split_tail(&h->incoming.slices[i], consumed_slice_size));
-    grpc_slice_unref(
+    grpc_slice_unref_internal(exec_ctx, 
         h->incoming.slices[i]); /* split_tail above increments refcount. */
   }
   grpc_slice_buffer_addn(
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index fba3314812..78037f8089 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -74,11 +74,11 @@ static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) {
   secure_endpoint *ep = secure_ep;
   grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep);
   tsi_frame_protector_destroy(ep->protector);
-  grpc_slice_buffer_destroy(&ep->leftover_bytes);
-  grpc_slice_unref(ep->read_staging_buffer);
-  grpc_slice_unref(ep->write_staging_buffer);
-  grpc_slice_buffer_destroy(&ep->output_buffer);
-  grpc_slice_buffer_destroy(&ep->source_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->leftover_bytes);
+  grpc_slice_unref_internal(exec_ctx, ep->read_staging_buffer);
+  grpc_slice_unref_internal(exec_ctx, ep->write_staging_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->output_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->source_buffer);
   gpr_mu_destroy(&ep->protector_mu);
   gpr_free(ep);
 }
@@ -154,7 +154,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
   uint8_t *end = GRPC_SLICE_END_PTR(ep->read_staging_buffer);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
     call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING(
                                    "Secure read failed", &error, 1));
     return;
@@ -209,10 +209,10 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
 
   /* TODO(yangg) experiment with moving this block after read_cb to see if it
      helps latency */
-  grpc_slice_buffer_reset_and_unref(&ep->source_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->source_buffer);
 
   if (result != TSI_OK) {
-    grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
     call_read_cb(exec_ctx, ep, grpc_set_tsi_error_result(
                                    GRPC_ERROR_CREATE("Unwrap failed"), result));
     return;
@@ -226,7 +226,7 @@ static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
   secure_endpoint *ep = (secure_endpoint *)secure_ep;
   ep->read_cb = cb;
   ep->read_buffer = slices;
-  grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
 
   SECURE_ENDPOINT_REF(ep, "read");
   if (ep->leftover_bytes.count) {
@@ -258,7 +258,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
   uint8_t *cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer);
   uint8_t *end = GRPC_SLICE_END_PTR(ep->write_staging_buffer);
 
-  grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
 
   if (grpc_trace_secure_endpoint) {
     for (i = 0; i < slices->count; i++) {
@@ -322,7 +322,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
 
   if (result != TSI_OK) {
     /* TODO(yangg) do different things according to the error type? */
-    grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
     grpc_exec_ctx_sched(
         exec_ctx, cb,
         grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result),
@@ -398,7 +398,7 @@ grpc_endpoint *grpc_secure_endpoint_create(
   grpc_slice_buffer_init(&ep->leftover_bytes);
   for (i = 0; i < leftover_nslices; i++) {
     grpc_slice_buffer_add(&ep->leftover_bytes,
-                          grpc_slice_ref(leftover_slices[i]));
+                          grpc_slice_ref_internal(leftover_slices[i]));
   }
   ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
   ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/security/util/b64.c
index 4892e8e621..c227889726 100644
--- a/src/core/lib/security/util/b64.c
+++ b/src/core/lib/security/util/b64.c
@@ -228,6 +228,6 @@ grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
   return result;
 
 fail:
-  grpc_slice_unref(result);
+  grpc_slice_unref_internal(exec_ctx, result);
   return gpr_empty_slice();
 }
diff --git a/src/core/lib/slice/percent_encoding.c b/src/core/lib/slice/percent_encoding.c
index b9e35f1c71..c76c58d371 100644
--- a/src/core/lib/slice/percent_encoding.c
+++ b/src/core/lib/slice/percent_encoding.c
@@ -35,6 +35,8 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 const uint8_t grpc_url_percent_encoding_unreserved_bytes[256 / 8] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff,
     0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -66,7 +68,7 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice,
   }
   // no unreserved bytes: return the string unmodified
   if (!any_reserved_bytes) {
-    return grpc_slice_ref(slice);
+    return grpc_slice_ref_internal(slice);
   }
   // second pass: actually encode
   grpc_slice out = grpc_slice_malloc(output_length);
@@ -119,7 +121,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in,
     }
   }
   if (!any_percent_encoded_stuff) {
-    *slice_out = grpc_slice_ref(slice_in);
+    *slice_out = grpc_slice_ref_internal(slice_in);
     return true;
   }
   p = GRPC_SLICE_START_PTR(slice_in);
@@ -158,7 +160,7 @@ grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) {
     }
   }
   if (!any_percent_encoded_stuff) {
-    return grpc_slice_ref(slice_in);
+    return grpc_slice_ref_internal(slice_in);
   }
   p = GRPC_SLICE_START_PTR(slice_in);
   grpc_slice out = grpc_slice_malloc(out_length);
diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c
index 3dac18df61..5b8f71a778 100644
--- a/src/core/lib/slice/slice.c
+++ b/src/core/lib/slice/slice.c
@@ -31,12 +31,16 @@
  *
  */
 
+#include "src/core/lib/slice/slice_internal.h"
+
 #include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
 #include <string.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
+
 grpc_slice gpr_empty_slice(void) {
   grpc_slice out;
   out.refcount = 0;
@@ -44,25 +48,37 @@ grpc_slice gpr_empty_slice(void) {
   return out;
 }
 
-grpc_slice grpc_slice_ref(grpc_slice slice) {
+grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
   if (slice.refcount) {
     slice.refcount->ref(slice.refcount);
   }
   return slice;
 }
 
-void grpc_slice_unref(grpc_slice slice) {
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
   if (slice.refcount) {
-    slice.refcount->unref(slice.refcount);
+    slice.refcount->unref(exec_ctx, slice.refcount);
   }
 }
 
+/* Public API */
+grpc_slice grpc_slice_ref(grpc_slice slice) {
+  return grpc_slice_ref_internal(slice);
+}
+
+/* Public API */
+void grpc_slice_unref(grpc_slice slice) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_unref_internal(&exec_ctx, slice);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 /* grpc_slice_from_static_string support structure - a refcount that does
    nothing */
-static void noop_ref_or_unref(void *unused) {}
+static void noop_ref(void *unused) {}
+static void noop_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
 
-static grpc_slice_refcount noop_refcount = {noop_ref_or_unref,
-                                            noop_ref_or_unref};
+static grpc_slice_refcount noop_refcount = {noop_ref, noop_unref};
 
 grpc_slice grpc_slice_from_static_string(const char *s) {
   grpc_slice slice;
@@ -86,7 +102,7 @@ static void new_slice_ref(void *p) {
   gpr_ref(&r->refs);
 }
 
-static void new_slice_unref(void *p) {
+static void new_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   new_slice_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     r->user_destroy(r->user_data);
@@ -131,7 +147,7 @@ static void new_with_len_ref(void *p) {
   gpr_ref(&r->refs);
 }
 
-static void new_with_len_unref(void *p) {
+static void new_with_len_unref(grpc_exec_ctx *exec_ctx, void *p) {
   new_with_len_slice_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     r->user_destroy(r->user_data, r->user_length);
@@ -177,7 +193,7 @@ static void malloc_ref(void *p) {
   gpr_ref(&r->refs);
 }
 
-static void malloc_unref(void *p) {
+static void malloc_unref(grpc_exec_ctx *exec_ctx, void *p) {
   malloc_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     gpr_free(r);
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 990ef128bd..872bd10a09 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -40,6 +40,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 /* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */
 #define GROW(x) (3 * (x) / 2)
 
@@ -63,11 +65,21 @@ void grpc_slice_buffer_init(grpc_slice_buffer *sb) {
   sb->slices = sb->inlined;
 }
 
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+                                        grpc_slice_buffer *sb) {
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, sb);
+  if (sb->slices != sb->inlined) {
+    gpr_free(sb->slices);
+  }
+}
+
 void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
-  grpc_slice_buffer_reset_and_unref(sb);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
   if (sb->slices != sb->inlined) {
     gpr_free(sb->slices);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 uint8_t *grpc_slice_buffer_tiny_add(grpc_slice_buffer *sb, size_t n) {
@@ -154,17 +166,24 @@ void grpc_slice_buffer_pop(grpc_slice_buffer *sb) {
   }
 }
 
-void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+                                                grpc_slice_buffer *sb) {
   size_t i;
 
   for (i = 0; i < sb->count; i++) {
-    grpc_slice_unref(sb->slices[i]);
+    grpc_slice_unref_internal(exec_ctx, sb->slices[i]);
   }
 
   sb->count = 0;
   sb->length = 0;
 }
 
+void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 void grpc_slice_buffer_swap(grpc_slice_buffer *a, grpc_slice_buffer *b) {
   GPR_SWAP(size_t, a->count, b->count);
   GPR_SWAP(size_t, a->capacity, b->capacity);
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
new file mode 100644
index 0000000000..72b0a590bb
--- /dev/null
+++ b/src/core/lib/slice/slice_internal.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
+#define GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
+
+#include <grpc/slice.h>
+#include <grpc/slice_buffer.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+grpc_slice grpc_slice_ref_internal(grpc_slice slice);
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice);
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+                                                grpc_slice_buffer *sb);
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+                                        grpc_slice_buffer *sb);
+
+#endif
diff --git a/src/core/lib/slice/slice_string_helpers.c b/src/core/lib/slice/slice_string_helpers.c
index 4731762ece..839c366b32 100644
--- a/src/core/lib/slice/slice_string_helpers.c
+++ b/src/core/lib/slice/slice_string_helpers.c
@@ -37,6 +37,7 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 
 char *grpc_dump_slice(grpc_slice s, uint32_t flags) {
@@ -84,6 +85,6 @@ void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
     grpc_slice_buffer_add_indexed(
         dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
   } else { /* no sep found, add whole input */
-    grpc_slice_buffer_add_indexed(dst, grpc_slice_ref(str));
+    grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
   }
 }
diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c
index d646591a65..c8e2fdfdad 100644
--- a/src/core/lib/surface/byte_buffer.c
+++ b/src/core/lib/surface/byte_buffer.c
@@ -35,6 +35,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices,
                                               size_t nslices) {
   return grpc_raw_compressed_byte_buffer_create(slices, nslices,
@@ -50,7 +52,7 @@ grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
   bb->data.raw.compression = compression;
   grpc_slice_buffer_init(&bb->data.raw.slice_buffer);
   for (i = 0; i < nslices; i++) {
-    grpc_slice_ref(slices[i]);
+    grpc_slice_ref_internal(slices[i]);
     grpc_slice_buffer_add(&bb->data.raw.slice_buffer, slices[i]);
   }
   return bb;
@@ -82,12 +84,14 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) {
 
 void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
   if (!bb) return;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   switch (bb->type) {
     case GRPC_BB_RAW:
-      grpc_slice_buffer_destroy(&bb->data.raw.slice_buffer);
+      grpc_slice_buffer_destroy_internal(&exec_ctx, &bb->data.raw.slice_buffer);
       break;
   }
   gpr_free(bb);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c
index 0089959fbb..1a6ccdaddb 100644
--- a/src/core/lib/surface/byte_buffer_reader.c
+++ b/src/core/lib/surface/byte_buffer_reader.c
@@ -42,6 +42,7 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 static int is_compressed(grpc_byte_buffer *buffer) {
   switch (buffer->type) {
@@ -56,13 +57,15 @@ static int is_compressed(grpc_byte_buffer *buffer) {
 
 int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
                                  grpc_byte_buffer *buffer) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_slice_buffer decompressed_slices_buffer;
   reader->buffer_in = buffer;
   switch (reader->buffer_in->type) {
     case GRPC_BB_RAW:
       grpc_slice_buffer_init(&decompressed_slices_buffer);
       if (is_compressed(reader->buffer_in)) {
-        if (grpc_msg_decompress(reader->buffer_in->data.raw.compression,
+        if (grpc_msg_decompress(&exec_ctx,
+                                reader->buffer_in->data.raw.compression,
                                 &reader->buffer_in->data.raw.slice_buffer,
                                 &decompressed_slices_buffer) == 0) {
           gpr_log(GPR_ERROR,
@@ -76,13 +79,15 @@ int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
               grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices,
                                           decompressed_slices_buffer.count);
         }
-        grpc_slice_buffer_destroy(&decompressed_slices_buffer);
+        grpc_slice_buffer_destroy_internal(&exec_ctx,
+                                           &decompressed_slices_buffer);
       } else { /* not compressed, use the input buffer as output */
         reader->buffer_out = reader->buffer_in;
       }
       reader->current.index = 0;
       break;
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return 1;
 }
 
@@ -104,7 +109,8 @@ int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
       grpc_slice_buffer *slice_buffer;
       slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
       if (reader->current.index < slice_buffer->count) {
-        *slice = grpc_slice_ref(slice_buffer->slices[reader->current.index]);
+        *slice = grpc_slice_ref_internal(
+            slice_buffer->slices[reader->current.index]);
         reader->current.index += 1;
         return 1;
       }
@@ -121,12 +127,14 @@ grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) {
   grpc_slice out_slice = grpc_slice_malloc(input_size);
   uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
     const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
     memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
     bytes_read += slice_length;
-    grpc_slice_unref(in_slice);
+    grpc_slice_unref_internal(&exec_ctx, in_slice);
     GPR_ASSERT(bytes_read <= input_size);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return out_slice;
 }
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 62c0ec83a1..be568feba1 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -49,6 +49,7 @@
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -225,12 +226,12 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
 static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                   grpc_error *error);
 
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+                             const grpc_call_create_args *args,
                              grpc_call **out_call) {
   size_t i, j;
   grpc_channel_stack *channel_stack =
       grpc_channel_get_channel_stack(args->channel);
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_call *call;
   GPR_TIMER_BEGIN("grpc_call_create", 0);
   call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
@@ -313,14 +314,14 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args,
   GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
   /* initial refcount dropped by grpc_call_destroy */
   grpc_error *error =
-      grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
+      grpc_call_stack_init(exec_ctx, channel_stack, 1, destroy_call, call,
                            call->context, args->server_transport_data, path,
                            send_deadline, CALL_STACK_FROM_CALL(call));
   if (error != GRPC_ERROR_NONE) {
     grpc_status_code status;
     const char *error_str;
     grpc_error_get_status(error, &status, &error_str);
-    close_with_status(&exec_ctx, call, status, error_str);
+    close_with_status(exec_ctx, call, status, error_str);
   }
   if (args->cq != NULL) {
     GPR_ASSERT(
@@ -336,12 +337,11 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args,
   }
   if (!grpc_polling_entity_is_empty(&call->pollent)) {
     grpc_call_stack_set_pollset_or_pollset_set(
-        &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
+        exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
   }
 
-  if (path != NULL) GRPC_MDSTR_UNREF(path);
+  if (path != NULL) GRPC_MDSTR_UNREF(exec_ctx, path);
 
-  grpc_exec_ctx_finish(&exec_ctx);
   GPR_TIMER_END("grpc_call_create", 0);
   return error;
 }
@@ -402,7 +402,7 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
   GPR_TIMER_BEGIN("destroy_call", 0);
   for (i = 0; i < 2; i++) {
     grpc_metadata_batch_destroy(
-        &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
+        exec_ctx, &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
   }
   if (c->receiving_stream != NULL) {
     grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
@@ -410,11 +410,11 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
   gpr_mu_destroy(&c->mu);
   for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
     if (c->status[i].details) {
-      GRPC_MDSTR_UNREF(c->status[i].details);
+      GRPC_MDSTR_UNREF(exec_ctx, c->status[i].details);
     }
   }
   for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
-    GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
+    GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
   }
   for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
     if (c->context[i].destroy) {
@@ -442,22 +442,22 @@ static void set_status_code(grpc_call *call, status_source source,
   call->status[source].code = (grpc_status_code)status;
 }
 
-static void set_status_details(grpc_call *call, status_source source,
-                               grpc_mdstr *status) {
+static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                               status_source source, grpc_mdstr *status) {
   if (call->status[source].details != NULL) {
-    GRPC_MDSTR_UNREF(status);
+    GRPC_MDSTR_UNREF(exec_ctx, status);
   } else {
     call->status[source].details = status;
   }
 }
 
-static void set_status_from_error(grpc_call *call, status_source source,
-                                  grpc_error *error) {
+static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                                  status_source source, grpc_error *error) {
   grpc_status_code status;
   const char *msg;
   grpc_error_get_status(error, &status, &msg);
   set_status_code(call, source, (uint32_t)status);
-  set_status_details(call, source, grpc_mdstr_from_string(msg));
+  set_status_details(exec_ctx, call, source, grpc_mdstr_from_string(msg));
 }
 
 static void set_incoming_compression_algorithm(
@@ -491,7 +491,8 @@ uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
 
 static void destroy_encodings_accepted_by_peer(void *p) { return; }
 
-static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
+static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
+                                           grpc_call *call, grpc_mdelem *mdel) {
   size_t i;
   grpc_compression_algorithm algorithm;
   grpc_slice_buffer accept_encoding_parts;
@@ -531,7 +532,7 @@ static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
     }
   }
 
-  grpc_slice_buffer_destroy(&accept_encoding_parts);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &accept_encoding_parts);
 
   grpc_mdelem_set_user_data(
       mdel, destroy_encodings_accepted_by_peer,
@@ -589,12 +590,10 @@ static grpc_metadata *get_md_elem(grpc_metadata *metadata,
   return res;
 }
 
-static int prepare_application_metadata(grpc_call *call, int count,
-                                        grpc_metadata *metadata,
-                                        int is_trailing,
-                                        int prepend_extra_metadata,
-                                        grpc_metadata *additional_metadata,
-                                        int additional_metadata_count) {
+static int prepare_application_metadata(
+    grpc_exec_ctx *exec_ctx, grpc_call *call, int count,
+    grpc_metadata *metadata, int is_trailing, int prepend_extra_metadata,
+    grpc_metadata *additional_metadata, int additional_metadata_count) {
   int total_count = count + additional_metadata_count;
   int i;
   grpc_metadata_batch *batch =
@@ -605,7 +604,7 @@ static int prepare_application_metadata(grpc_call *call, int count,
     grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
     l->md = grpc_mdelem_from_string_and_buffer(
-        md->key, (const uint8_t *)md->value, md->value_length);
+        exec_ctx, md->key, (const uint8_t *)md->value, md->value_length);
     if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
                                   GRPC_MDSTR_LENGTH(l->md->key))) {
       gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
@@ -625,7 +624,7 @@ static int prepare_application_metadata(grpc_call *call, int count,
       const grpc_metadata *md =
           get_md_elem(metadata, additional_metadata, j, count);
       grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
-      GRPC_MDELEM_UNREF(l->md);
+      GRPC_MDELEM_UNREF(exec_ctx, l->md);
     }
     return 0;
   }
@@ -808,7 +807,8 @@ static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
 
 static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
                                              termination_closure *tc) {
-  set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
+  set_status_from_error(exec_ctx, tc->call, STATUS_FROM_API_OVERRIDE,
+                        tc->error);
 
   if (tc->type == TC_CANCEL) {
     grpc_closure_init(&tc->closure, send_cancel, tc);
@@ -925,7 +925,8 @@ static grpc_compression_algorithm decode_compression(grpc_mdelem *md) {
   return algorithm;
 }
 
-static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
+static grpc_mdelem *recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                                       grpc_mdelem *elem) {
   if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
     GPR_TIMER_BEGIN("status", 0);
     set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
@@ -933,7 +934,8 @@ static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
     GPR_TIMER_BEGIN("status-details", 0);
-    set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
+    set_status_details(exec_ctx, call, STATUS_FROM_WIRE,
+                       GRPC_MDSTR_REF(elem->value));
     GPR_TIMER_END("status-details", 0);
     return NULL;
   }
@@ -959,33 +961,38 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
   return elem;
 }
 
-static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
-  grpc_call *call = callp;
-  elem = recv_common_filter(call, elem);
+typedef struct {
+  grpc_exec_ctx *exec_ctx;
+  grpc_call *call;
+} recv_filter_args;
+
+static grpc_mdelem *recv_initial_filter(void *args, grpc_mdelem *elem) {
+  recv_filter_args *a = args;
+  elem = recv_common_filter(a->exec_ctx, a->call, elem);
   if (elem == NULL) {
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
     GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
-    set_incoming_compression_algorithm(call, decode_compression(elem));
+    set_incoming_compression_algorithm(a->call, decode_compression(elem));
     GPR_TIMER_END("incoming_compression_algorithm", 0);
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
-    set_encodings_accepted_by_peer(call, elem);
+    set_encodings_accepted_by_peer(a->exec_ctx, a->call, elem);
     GPR_TIMER_END("encodings_accepted_by_peer", 0);
     return NULL;
   } else {
-    return publish_app_metadata(call, elem, 0);
+    return publish_app_metadata(a->call, elem, 0);
   }
 }
 
-static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) {
-  grpc_call *call = callp;
-  elem = recv_common_filter(call, elem);
+static grpc_mdelem *recv_trailing_filter(void *args, grpc_mdelem *elem) {
+  recv_filter_args *a = args;
+  elem = recv_common_filter(a->exec_ctx, a->call, elem);
   if (elem == NULL) {
     return NULL;
   } else {
-    return publish_app_metadata(call, elem, 1);
+    return publish_app_metadata(a->call, elem, 1);
   }
 }
 
@@ -1231,7 +1238,8 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
   if (error == GRPC_ERROR_NONE) {
     grpc_metadata_batch *md =
         &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
-    grpc_metadata_batch_filter(md, recv_initial_filter, call);
+    recv_filter_args args = {exec_ctx, call};
+    grpc_metadata_batch_filter(exec_ctx, md, recv_initial_filter, &args);
 
     GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
     validate_filtered_metadata(exec_ctx, bctl);
@@ -1275,14 +1283,15 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
   intptr_t status;
   if (error != GRPC_ERROR_NONE &&
       grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
-    set_status_from_error(call, STATUS_FROM_CORE, error);
+    set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
   }
 
   if (bctl->send_initial_metadata) {
     if (error != GRPC_ERROR_NONE) {
-      set_status_from_error(call, STATUS_FROM_CORE, error);
+      set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
     }
     grpc_metadata_batch_destroy(
+        exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
   }
   if (bctl->send_message) {
@@ -1290,12 +1299,14 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
   }
   if (bctl->send_final_op) {
     grpc_metadata_batch_destroy(
+        exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
   }
   if (bctl->recv_final_op) {
     grpc_metadata_batch *md =
         &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-    grpc_metadata_batch_filter(md, recv_trailing_filter, call);
+    recv_filter_args args = {exec_ctx, call};
+    grpc_metadata_batch_filter(exec_ctx, md, recv_trailing_filter, &args);
 
     call->received_final_op = true;
     /* propagate cancellation to any interested children */
@@ -1432,7 +1443,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         bctl->send_initial_metadata = 1;
         call->sent_initial_metadata = 1;
         if (!prepare_application_metadata(
-                call, (int)op->data.send_initial_metadata.count,
+                exec_ctx, call, (int)op->data.send_initial_metadata.count,
                 op->data.send_initial_metadata.metadata, 0, call->is_client,
                 &compression_md, (int)additional_metadata_count)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
@@ -1506,15 +1517,15 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         call->sent_final_op = 1;
         call->send_extra_metadata_count = 1;
         call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
-            call->channel, op->data.send_status_from_server.status);
+            exec_ctx, call->channel, op->data.send_status_from_server.status);
         if (op->data.send_status_from_server.status_details != NULL) {
           call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
-              GRPC_MDSTR_GRPC_MESSAGE,
+              exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
               grpc_mdstr_from_string(
                   op->data.send_status_from_server.status_details));
           call->send_extra_metadata_count++;
           set_status_details(
-              call, STATUS_FROM_API_OVERRIDE,
+              exec_ctx, call, STATUS_FROM_API_OVERRIDE,
               GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
         }
         if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
@@ -1522,7 +1533,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
                           (uint32_t)op->data.send_status_from_server.status);
         }
         if (!prepare_application_metadata(
-                call,
+                exec_ctx, call,
                 (int)op->data.send_status_from_server.trailing_metadata_count,
                 op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
                 0)) {
@@ -1647,7 +1658,7 @@ done_with_error:
   /* reverse any mutations that occured */
   if (bctl->send_initial_metadata) {
     call->sent_initial_metadata = 0;
-    grpc_metadata_batch_clear(&call->metadata_batch[0][0]);
+    grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][0]);
   }
   if (bctl->send_message) {
     call->sending_message = 0;
@@ -1655,7 +1666,7 @@ done_with_error:
   }
   if (bctl->send_final_op) {
     call->sent_final_op = 0;
-    grpc_metadata_batch_clear(&call->metadata_batch[0][1]);
+    grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][1]);
   }
   if (bctl->recv_initial_metadata) {
     call->received_initial_metadata = 0;
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 18af41b7fb..233340c329 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -70,7 +70,8 @@ typedef struct grpc_call_create_args {
 /* Create a new call based on \a args.
    Regardless of success or failure, always returns a valid new call into *call
    */
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+                             const grpc_call_create_args *args,
                              grpc_call **call);
 
 void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 92d783b78d..82617390bb 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -89,13 +89,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
   bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
 
   grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
-  grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
+  grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+                                                   input_args);
   grpc_channel_stack_builder_set_target(builder, target);
   grpc_channel_stack_builder_set_transport(builder, optional_transport);
   grpc_channel *channel;
   grpc_channel_args *args;
   if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
-    grpc_channel_stack_builder_destroy(builder);
+    grpc_channel_stack_builder_destroy(exec_ctx, builder);
     return NULL;
   } else {
     args = grpc_channel_args_copy(
@@ -120,10 +121,10 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
         } else {
           if (channel->default_authority) {
             /* setting this takes precedence over anything else */
-            GRPC_MDELEM_UNREF(channel->default_authority);
+            GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
           }
           channel->default_authority = grpc_mdelem_from_strings(
-              ":authority", args->args[i].value.string);
+              exec_ctx, ":authority", args->args[i].value.string);
         }
       } else if (0 ==
                  strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -138,7 +139,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                     GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
           } else {
             channel->default_authority = grpc_mdelem_from_strings(
-                ":authority", args->args[i].value.string);
+                exec_ctx, ":authority", args->args[i].value.string);
           }
         }
       } else if (0 == strcmp(args->args[i].key,
@@ -164,7 +165,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
             0x1; /* always support no compression */
       }
     }
-    grpc_channel_args_destroy(args);
+    grpc_channel_args_destroy(exec_ctx, args);
   }
 
   return channel;
@@ -176,10 +177,10 @@ char *grpc_channel_get_target(grpc_channel *channel) {
 }
 
 static grpc_call *grpc_channel_create_call_internal(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
-    grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
-    gpr_timespec deadline) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_completion_queue *cq,
+    grpc_pollset_set *pollset_set_alternative, grpc_mdelem *path_mdelem,
+    grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
   grpc_mdelem *send_metadata[2];
   size_t num_metadata = 0;
 
@@ -206,7 +207,7 @@ static grpc_call *grpc_channel_create_call_internal(
   args.send_deadline = deadline;
 
   grpc_call *call;
-  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call));
+  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(exec_ctx, &args, &call));
   return call;
 }
 
@@ -227,26 +228,30 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
       (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
        deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq, NULL,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
+      grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 grpc_call *grpc_channel_create_pollset_set_call(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_pollset_set *pollset_set, const char *method, const char *host,
-    gpr_timespec deadline, void *reserved) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_pollset_set *pollset_set,
+    const char *method, const char *host, gpr_timespec deadline,
+    void *reserved) {
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, NULL, pollset_set,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+      exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
+      grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
@@ -259,15 +264,18 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
       "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
       4, (channel, method, host, reserved));
   GPR_ASSERT(!reserved);
-  rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  rc->path = grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                                grpc_mdstr_from_string(method));
-  rc->authority = host ? grpc_mdelem_from_metadata_strings(
-                             GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host))
-                       : NULL;
+  rc->authority =
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
+                                               grpc_mdstr_from_string(host))
+           : NULL;
   gpr_mu_lock(&channel->registered_call_mu);
   rc->next = channel->registered_calls;
   channel->registered_calls = rc;
   gpr_mu_unlock(&channel->registered_call_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   return rc;
 }
 
@@ -287,10 +295,13 @@ grpc_call *grpc_channel_create_registered_call(
           registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
           (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, completion_queue, NULL,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, completion_queue, NULL,
       GRPC_MDELEM_REF(rc->path),
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -316,14 +327,14 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg,
   while (channel->registered_calls) {
     registered_call *rc = channel->registered_calls;
     channel->registered_calls = rc->next;
-    GRPC_MDELEM_UNREF(rc->path);
+    GRPC_MDELEM_UNREF(exec_ctx, rc->path);
     if (rc->authority) {
-      GRPC_MDELEM_UNREF(rc->authority);
+      GRPC_MDELEM_UNREF(exec_ctx, rc->authority);
     }
     gpr_free(rc);
   }
   if (channel->default_authority != NULL) {
-    GRPC_MDELEM_UNREF(channel->default_authority);
+    GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
   }
   gpr_mu_destroy(&channel->registered_call_mu);
   gpr_free(channel->target);
@@ -353,7 +364,8 @@ grpc_compression_options grpc_channel_compression_options(
   return channel->compression_options;
 }
 
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
+grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+                                                 grpc_channel *channel, int i) {
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   switch (i) {
     case 0:
@@ -364,6 +376,6 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
       return GRPC_MDELEM_GRPC_STATUS_2;
   }
   gpr_ltoa(i, tmp);
-  return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS,
+  return grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
                                            grpc_mdstr_from_string(tmp));
 }
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 23cc8656ca..2ebadb7a15 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -51,9 +51,10 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
     properties from the server call to this new client call, depending on the
     value of \a propagation_mask (see propagation_bits.h for possible values) */
 grpc_call *grpc_channel_create_pollset_set_call(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_pollset_set *pollset_set, const char *method, const char *host,
-    gpr_timespec deadline, void *reserved);
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_pollset_set *pollset_set,
+    const char *method, const char *host, gpr_timespec deadline,
+    void *reserved);
 
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
@@ -62,7 +63,8 @@ grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
     status_code.
 
     The returned elem is owned by the caller. */
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel,
+grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+                                                 grpc_channel *channel,
                                                  int status_code);
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 7903f57a68..8c82f38c77 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -221,6 +221,7 @@ void grpc_init(void) {
 void grpc_shutdown(void) {
   int i;
   GRPC_API_TRACE("grpc_shutdown(void)", 0, ());
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_mu_lock(&g_init_mu);
   if (--g_initializations == 0) {
     grpc_executor_shutdown();
@@ -233,9 +234,10 @@ void grpc_shutdown(void) {
         g_all_of_the_plugins[i].destroy();
       }
     }
-    grpc_mdctx_global_shutdown();
+    grpc_mdctx_global_shutdown(&exec_ctx);
   }
   gpr_mu_unlock(&g_init_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int grpc_is_initialized(void) {
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d32c884e8e..1b57c5cd01 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -55,14 +55,15 @@ typedef struct {
   const char *error_message;
 } channel_data;
 
-static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) {
+static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                          grpc_metadata_batch *mdb) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   gpr_ltoa(chand->error_code, tmp);
-  calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp);
+  calld->status.md = grpc_mdelem_from_strings(exec_ctx, "grpc-status", tmp);
   calld->details.md =
-      grpc_mdelem_from_strings("grpc-message", chand->error_message);
+      grpc_mdelem_from_strings(exec_ctx, "grpc-message", chand->error_message);
   calld->status.prev = calld->details.next = NULL;
   calld->status.next = &calld->details;
   calld->details.prev = &calld->status;
@@ -76,9 +77,9 @@ static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
                                            grpc_transport_stream_op *op) {
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   if (op->recv_initial_metadata != NULL) {
-    fill_metadata(elem, op->recv_initial_metadata);
+    fill_metadata(exec_ctx, elem, op->recv_initial_metadata);
   } else if (op->recv_trailing_metadata != NULL) {
-    fill_metadata(elem, op->recv_trailing_metadata);
+    fill_metadata(exec_ctx, elem, op->recv_trailing_metadata);
   }
   grpc_transport_stream_op_finish_with_failure(
       exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 798f582cad..6d9d3a92ab 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/stack_lockfree.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -270,7 +271,7 @@ struct shutdown_cleanup_args {
 static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
                              grpc_error *error) {
   struct shutdown_cleanup_args *a = arg;
-  grpc_slice_unref(a->slice);
+  grpc_slice_unref_internal(exec_ctx, a->slice);
   gpr_free(a);
 }
 
@@ -378,7 +379,7 @@ static void server_ref(grpc_server *server) {
 static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
   registered_method *rm;
   size_t i;
-  grpc_channel_args_destroy(server->channel_args);
+  grpc_channel_args_destroy(exec_ctx, server->channel_args);
   gpr_mu_destroy(&server->mu_global);
   gpr_mu_destroy(&server->mu_call);
   while ((rm = server->registered_methods) != NULL) {
@@ -763,7 +764,8 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
   gpr_timespec op_deadline;
 
   GRPC_ERROR_REF(error);
-  grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
+  grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                             server_filter, elem);
   op_deadline = calld->recv_initial_metadata->deadline;
   if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
     calld->deadline = op_deadline;
@@ -837,7 +839,7 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
   args.server_transport_data = transport_server_data;
   args.send_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   grpc_call *call;
-  grpc_error *error = grpc_call_create(&args, &call);
+  grpc_error *error = grpc_call_create(exec_ctx, &args, &call);
   grpc_call_element *elem =
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
   if (error != GRPC_ERROR_NONE) {
@@ -901,10 +903,10 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   GPR_ASSERT(calld->state != PENDING);
 
   if (calld->host) {
-    GRPC_MDSTR_UNREF(calld->host);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->host);
   }
   if (calld->path) {
-    GRPC_MDSTR_UNREF(calld->path);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->path);
   }
   grpc_metadata_array_destroy(&calld->initial_metadata);
 
@@ -935,10 +937,10 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   if (chand->registered_methods) {
     for (i = 0; i < chand->registered_method_slots; i++) {
       if (chand->registered_methods[i].method) {
-        GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
+        GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].method);
       }
       if (chand->registered_methods[i].host) {
-        GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
+        GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].host);
       }
     }
     gpr_free(chand->registered_methods);
diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c
index 2f1d7b7c60..4d4206189e 100644
--- a/src/core/lib/transport/byte_stream.c
+++ b/src/core/lib/transport/byte_stream.c
@@ -37,6 +37,8 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
                           grpc_byte_stream *byte_stream, grpc_slice *slice,
                           size_t max_size_hint, grpc_closure *on_complete) {
@@ -57,7 +59,8 @@ static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx,
                                     grpc_closure *on_complete) {
   grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream;
   GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
-  *slice = grpc_slice_ref(stream->backing_buffer->slices[stream->cursor]);
+  *slice =
+      grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]);
   stream->cursor++;
   return 1;
 }
diff --git a/src/core/lib/transport/mdstr_hash_table.c b/src/core/lib/transport/mdstr_hash_table.c
index 8e914c420b..a3f6bde516 100644
--- a/src/core/lib/transport/mdstr_hash_table.c
+++ b/src/core/lib/transport/mdstr_hash_table.c
@@ -96,13 +96,14 @@ grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table) {
   return table;
 }
 
-int grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) {
+int grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
+                                grpc_mdstr_hash_table* table) {
   if (table != NULL && gpr_unref(&table->refs)) {
     for (size_t i = 0; i < table->size; ++i) {
       grpc_mdstr_hash_table_entry* entry = &table->entries[i];
       if (entry->key != NULL) {
-        GRPC_MDSTR_UNREF(entry->key);
-        entry->vtable->destroy_value(entry->value);
+        GRPC_MDSTR_UNREF(exec_ctx, entry->key);
+        entry->vtable->destroy_value(exec_ctx, entry->value);
       }
     }
     gpr_free(table->entries);
diff --git a/src/core/lib/transport/mdstr_hash_table.h b/src/core/lib/transport/mdstr_hash_table.h
index bceb4df93d..45e5720063 100644
--- a/src/core/lib/transport/mdstr_hash_table.h
+++ b/src/core/lib/transport/mdstr_hash_table.h
@@ -49,7 +49,7 @@
 typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table;
 
 typedef struct grpc_mdstr_hash_table_vtable {
-  void (*destroy_value)(void* value);
+  void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
   void* (*copy_value)(void* value);
   int (*compare_value)(void* value1, void* value2);
 } grpc_mdstr_hash_table_vtable;
@@ -68,7 +68,8 @@ grpc_mdstr_hash_table* grpc_mdstr_hash_table_create(
 
 grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table);
 /** Returns 1 when \a table is destroyed. */
-int grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table);
+int grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
+                                grpc_mdstr_hash_table* table);
 
 /** Returns the number of entries in \a table. */
 size_t grpc_mdstr_hash_table_num_entries(const grpc_mdstr_hash_table* table);
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index a1748c033b..ef5fd32b52 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -47,6 +47,7 @@
 
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/murmur_hash.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -153,7 +154,7 @@ static size_t g_static_mdtab_maxprobe;
 static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT];
 static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT];
 
-static void gc_mdtab(mdtab_shard *shard);
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard);
 
 void grpc_test_only_set_metadata_hash_seed(uint32_t seed) {
   g_hash_seed = seed;
@@ -227,12 +228,12 @@ void grpc_mdctx_global_init(void) {
   }
 }
 
-void grpc_mdctx_global_shutdown(void) {
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
   size_t i;
   for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
     mdtab_shard *shard = &g_mdtab_shard[i];
     gpr_mu_destroy(&shard->mu);
-    gc_mdtab(shard);
+    gc_mdtab(exec_ctx, shard);
     /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
     if (shard->count != 0) {
       gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked",
@@ -316,12 +317,13 @@ static void grow_strtab(strtab_shard *shard) {
   GPR_TIMER_END("grow_strtab", 0);
 }
 
-static void internal_destroy_string(strtab_shard *shard, internal_string *is) {
+static void internal_destroy_string(grpc_exec_ctx *exec_ctx,
+                                    strtab_shard *shard, internal_string *is) {
   internal_string **prev_next;
   internal_string *cur;
   GPR_TIMER_BEGIN("internal_destroy_string", 0);
   if (is->has_base64_and_huffman_encoded) {
-    grpc_slice_unref(is->base64_and_huffman);
+    grpc_slice_unref_internal(exec_ctx, is->base64_and_huffman);
   }
   for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT,
                                           shard->capacity)],
@@ -340,20 +342,20 @@ static void slice_ref(void *p) {
   GRPC_MDSTR_REF((grpc_mdstr *)(is));
 }
 
-static void slice_unref(void *p) {
+static void slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   internal_string *is =
       (internal_string *)((char *)p - offsetof(internal_string, refcount));
-  GRPC_MDSTR_UNREF((grpc_mdstr *)(is));
+  GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)(is));
 }
 
 grpc_mdstr *grpc_mdstr_from_string(const char *str) {
   return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str));
 }
 
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice) {
+grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
   grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice),
                                               GRPC_SLICE_LENGTH(slice));
-  grpc_slice_unref(slice);
+  grpc_slice_unref_internal(exec_ctx, slice);
   return result;
 }
 
@@ -444,7 +446,7 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
   return (grpc_mdstr *)s;
 }
 
-static void gc_mdtab(mdtab_shard *shard) {
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
   size_t i;
   internal_metadata **prev_next;
   internal_metadata *md, *next;
@@ -457,8 +459,8 @@ static void gc_mdtab(mdtab_shard *shard) {
       void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
       next = md->bucket_next;
       if (gpr_atm_acq_load(&md->refcnt) == 0) {
-        GRPC_MDSTR_UNREF((grpc_mdstr *)md->key);
-        GRPC_MDSTR_UNREF((grpc_mdstr *)md->value);
+        GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->key);
+        GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->value);
         if (md->user_data) {
           ((destroy_user_data_func)gpr_atm_no_barrier_load(
               &md->destroy_user_data))(user_data);
@@ -506,16 +508,17 @@ static void grow_mdtab(mdtab_shard *shard) {
   GPR_TIMER_END("grow_mdtab", 0);
 }
 
-static void rehash_mdtab(mdtab_shard *shard) {
+static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
   if (gpr_atm_no_barrier_load(&shard->free_estimate) >
       (gpr_atm)(shard->capacity / 4)) {
-    gc_mdtab(shard);
+    gc_mdtab(exec_ctx, shard);
   } else {
     grow_mdtab(shard);
   }
 }
 
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
+                                               grpc_mdstr *mkey,
                                                grpc_mdstr *mvalue) {
   internal_string *key = (internal_string *)mkey;
   internal_string *value = (internal_string *)mvalue;
@@ -547,8 +550,8 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
   for (md = shard->elems[idx]; md; md = md->bucket_next) {
     if (md->key == key && md->value == value) {
       REF_MD_LOCKED(shard, md);
-      GRPC_MDSTR_UNREF((grpc_mdstr *)key);
-      GRPC_MDSTR_UNREF((grpc_mdstr *)value);
+      GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)key);
+      GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)value);
       gpr_mu_unlock(&shard->mu);
       GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
       return (grpc_mdelem *)md;
@@ -574,7 +577,7 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
   shard->count++;
 
   if (shard->count > shard->capacity * 2) {
-    rehash_mdtab(shard);
+    rehash_mdtab(exec_ctx, shard);
   }
 
   gpr_mu_unlock(&shard->mu);
@@ -584,21 +587,26 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
   return (grpc_mdelem *)md;
 }
 
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value) {
-  return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_string(key),
-                                           grpc_mdstr_from_string(value));
+grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const char *value) {
+  return grpc_mdelem_from_metadata_strings(
+      exec_ctx, grpc_mdstr_from_string(key), grpc_mdstr_from_string(value));
 }
 
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
-  return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key),
-                                           grpc_mdstr_from_slice(value));
+grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+                                     grpc_slice value) {
+  return grpc_mdelem_from_metadata_strings(
+      exec_ctx, grpc_mdstr_from_slice(exec_ctx, key),
+      grpc_mdstr_from_slice(exec_ctx, value));
 }
 
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
+                                                const char *key,
                                                 const uint8_t *value,
                                                 size_t value_length) {
   return grpc_mdelem_from_metadata_strings(
-      grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
+      exec_ctx, grpc_mdstr_from_string(key),
+      grpc_mdstr_from_buffer(value, value_length));
 }
 
 static size_t get_base64_encoded_size(size_t raw_length) {
@@ -654,7 +662,7 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
   return gmd;
 }
 
-void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *gmd DEBUG_ARGS) {
   internal_metadata *md = (internal_metadata *)gmd;
   if (!md) return;
   if (is_mdelem_static(gmd)) return;
@@ -691,7 +699,7 @@ grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) {
   return gs;
 }
 
-void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) {
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *gs DEBUG_ARGS) {
   internal_string *s = (internal_string *)gs;
   if (is_mdstr_static(gs)) return;
   if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
@@ -699,7 +707,7 @@ void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) {
         &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
     gpr_mu_lock(&shard->mu);
     GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
-    internal_destroy_string(shard, s);
+    internal_destroy_string(exec_ctx, shard, s);
     gpr_mu_unlock(&shard->mu);
   }
 }
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 8dcfbb98bb..cf77753692 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -96,7 +96,7 @@ void grpc_test_only_set_metadata_hash_seed(uint32_t seed);
    clients may have handy */
 grpc_mdstr *grpc_mdstr_from_string(const char *str);
 /* Unrefs the slice. */
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice);
+grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice);
 grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length);
 
 /* Returns a borrowed slice from the mdstr with its contents base64 encoded
@@ -105,12 +105,16 @@ grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str);
 
 /* Constructors for grpc_mdelem instances; take a variety of data types that
    clients may have handy */
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key,
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
+                                               grpc_mdstr *key,
                                                grpc_mdstr *value);
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value);
+grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const char *value);
 /* Unrefs the slices. */
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
+grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+                                     grpc_slice value);
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
+                                                const char *key,
                                                 const uint8_t *value,
                                                 size_t value_length);
 
@@ -127,22 +131,26 @@ void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
 //#define GRPC_METADATA_REFCOUNT_DEBUG
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__)
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__)
+#define GRPC_MDSTR_UNREF(exec_ctx, s) \
+  grpc_mdstr_unref((exec_ctx), (s), __FILE__, __LINE__)
 #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__)
+#define GRPC_MDELEM_UNREF(exec_ctx, s) \
+  grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
 grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line);
-void grpc_mdstr_unref(grpc_mdstr *s, const char *file, int line);
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s, const char *file,
+                      int line);
 grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line);
-void grpc_mdelem_unref(grpc_mdelem *md, const char *file, int line);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md,
+                       const char *file, int line);
 #else
 #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s))
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s))
+#define GRPC_MDSTR_UNREF(exec_ctx, s) grpc_mdstr_unref((exec_ctx), (s))
 #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s))
+#define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
 grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s);
-void grpc_mdstr_unref(grpc_mdstr *s);
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s);
 grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
-void grpc_mdelem_unref(grpc_mdelem *md);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md);
 #endif
 
 /* Recover a char* from a grpc_mdstr. The returned string is null terminated.
@@ -162,7 +170,7 @@ int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
 #define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
 
 void grpc_mdctx_global_init(void);
-void grpc_mdctx_global_shutdown(void);
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
 
 /* Implementation provided by chttp2_transport */
 extern grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index 84b5a74d51..4430224e70 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -72,10 +72,11 @@ void grpc_metadata_batch_init(grpc_metadata_batch *batch) {
   batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
 }
 
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_metadata_batch *batch) {
   grpc_linked_mdelem *l;
   for (l = batch->list.head; l; l = l->next) {
-    GRPC_MDELEM_UNREF(l->md);
+    GRPC_MDELEM_UNREF(exec_ctx, l->md);
   }
 }
 
@@ -140,7 +141,8 @@ void grpc_metadata_batch_move(grpc_metadata_batch *dst,
   memset(src, 0, sizeof(grpc_metadata_batch));
 }
 
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+                                grpc_metadata_batch *batch,
                                 grpc_mdelem *(*filter)(void *user_data,
                                                        grpc_mdelem *elem),
                                 void *user_data) {
@@ -168,9 +170,9 @@ void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
         batch->list.tail = l->prev;
       }
       assert_valid_list(&batch->list);
-      GRPC_MDELEM_UNREF(l->md);
+      GRPC_MDELEM_UNREF(exec_ctx, l->md);
     } else if (filt != orig) {
-      GRPC_MDELEM_UNREF(orig);
+      GRPC_MDELEM_UNREF(exec_ctx, orig);
       l->md = filt;
     }
   }
@@ -183,9 +185,10 @@ static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) {
   return NULL;
 }
 
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+                               grpc_metadata_batch *batch) {
   batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
-  grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL);
+  grpc_metadata_batch_filter(exec_ctx, batch, no_metadata_for_you, NULL);
 }
 
 bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 7a9ccb4bc8..862c21b45b 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -68,8 +68,10 @@ typedef struct grpc_metadata_batch {
 } grpc_metadata_batch;
 
 void grpc_metadata_batch_init(grpc_metadata_batch *batch);
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch);
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch);
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_metadata_batch *batch);
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+                               grpc_metadata_batch *batch);
 bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
 
 /* Returns the transport size of the batch. */
@@ -118,7 +120,8 @@ void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch,
     The return value from \a filter will be substituted for the
     grpc_mdelem passed to \a filter. If \a filter returns NULL,
     the element will be moved to the garbage list. */
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+                                grpc_metadata_batch *batch,
                                 grpc_mdelem *(*filter)(void *user_data,
                                                        grpc_mdelem *elem),
                                 void *user_data);
diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c
index 57d97700bf..25fb54b37d 100644
--- a/src/core/lib/transport/method_config.c
+++ b/src/core/lib/transport/method_config.c
@@ -63,7 +63,9 @@ static int bool_cmp(void* v1, void* v2) {
   return 0;
 }
 
-static grpc_mdstr_hash_table_vtable bool_vtable = {gpr_free, bool_copy,
+static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); }
+
+static grpc_mdstr_hash_table_vtable bool_vtable = {free_mem, bool_copy,
                                                    bool_cmp};
 
 // timespec vtable
@@ -79,7 +81,7 @@ static int timespec_cmp(void* v1, void* v2) {
   return gpr_time_cmp(*(gpr_timespec*)v1, *(gpr_timespec*)v2);
 }
 
-static grpc_mdstr_hash_table_vtable timespec_vtable = {gpr_free, timespec_copy,
+static grpc_mdstr_hash_table_vtable timespec_vtable = {free_mem, timespec_copy,
                                                        timespec_cmp};
 
 // int32 vtable
@@ -99,7 +101,7 @@ static int int32_cmp(void* v1, void* v2) {
   return 0;
 }
 
-static grpc_mdstr_hash_table_vtable int32_vtable = {gpr_free, int32_copy,
+static grpc_mdstr_hash_table_vtable int32_vtable = {free_mem, int32_copy,
                                                     int32_cmp};
 
 // Hash table keys.
@@ -166,12 +168,13 @@ grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) {
   return method_config;
 }
 
-void grpc_method_config_unref(grpc_method_config* method_config) {
-  if (grpc_mdstr_hash_table_unref(method_config->table)) {
-    GRPC_MDSTR_UNREF(method_config->wait_for_ready_key);
-    GRPC_MDSTR_UNREF(method_config->timeout_key);
-    GRPC_MDSTR_UNREF(method_config->max_request_message_bytes_key);
-    GRPC_MDSTR_UNREF(method_config->max_response_message_bytes_key);
+void grpc_method_config_unref(grpc_exec_ctx* exec_ctx,
+                              grpc_method_config* method_config) {
+  if (grpc_mdstr_hash_table_unref(exec_ctx, method_config->table)) {
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->wait_for_ready_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->timeout_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_request_message_bytes_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_response_message_bytes_key);
     gpr_free(method_config);
   }
 }
@@ -210,8 +213,8 @@ const int32_t* grpc_method_config_get_max_response_message_bytes(
 // grpc_method_config_table
 //
 
-static void method_config_unref(void* valuep) {
-  grpc_method_config_unref(valuep);
+static void method_config_unref(grpc_exec_ctx* exec_ctx, void* valuep) {
+  grpc_method_config_unref(exec_ctx, valuep);
 }
 
 static void* method_config_ref(void* valuep) {
@@ -245,8 +248,9 @@ grpc_method_config_table* grpc_method_config_table_ref(
   return grpc_mdstr_hash_table_ref(table);
 }
 
-void grpc_method_config_table_unref(grpc_method_config_table* table) {
-  grpc_mdstr_hash_table_unref(table);
+void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx,
+                                    grpc_method_config_table* table) {
+  grpc_mdstr_hash_table_unref(exec_ctx, table);
 }
 
 int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
@@ -254,7 +258,8 @@ int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
   return grpc_mdstr_hash_table_cmp(table1, table2);
 }
 
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
                                    const grpc_mdstr* path) {
   void* value = grpc_mdstr_hash_table_get(table, path);
   // If we didn't find a match for the path, try looking for a wildcard
@@ -270,14 +275,16 @@ void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
     grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
     gpr_free(buf);
     value = grpc_mdstr_hash_table_get(table, wildcard_path);
-    GRPC_MDSTR_UNREF(wildcard_path);
+    GRPC_MDSTR_UNREF(exec_ctx, wildcard_path);
   }
   return value;
 }
 
 static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); }
 
-static void destroy_arg(void* p) { grpc_method_config_table_unref(p); }
+static void destroy_arg(grpc_exec_ctx* exec_ctx, void* p) {
+  grpc_method_config_table_unref(exec_ctx, p);
+}
 
 static int cmp_arg(void* p1, void* p2) {
   return grpc_method_config_table_cmp(p1, p2);
@@ -315,7 +322,7 @@ static void convert_entry(const grpc_mdstr_hash_table_entry* entry,
 }
 
 grpc_mdstr_hash_table* grpc_method_config_table_convert(
-    const grpc_method_config_table* table,
+    grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table,
     void* (*convert_value)(const grpc_method_config* method_config),
     const grpc_mdstr_hash_table_vtable* vtable) {
   // Create an array of the entries in the table with converted values.
@@ -331,8 +338,8 @@ grpc_mdstr_hash_table* grpc_method_config_table_convert(
       grpc_mdstr_hash_table_create(state.num_entries, state.entries);
   // Clean up the array.
   for (size_t i = 0; i < state.num_entries; ++i) {
-    GRPC_MDSTR_UNREF(state.entries[i].key);
-    vtable->destroy_value(state.entries[i].value);
+    GRPC_MDSTR_UNREF(exec_ctx, state.entries[i].key);
+    vtable->destroy_value(exec_ctx, state.entries[i].value);
   }
   gpr_free(state.entries);
   // Return the new table.
diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h
index 58fedd9436..d17a493fd4 100644
--- a/src/core/lib/transport/method_config.h
+++ b/src/core/lib/transport/method_config.h
@@ -60,7 +60,8 @@ grpc_method_config* grpc_method_config_create(
     int32_t* max_request_message_bytes, int32_t* max_response_message_bytes);
 
 grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config);
-void grpc_method_config_unref(grpc_method_config* method_config);
+void grpc_method_config_unref(grpc_exec_ctx* exec_ctx,
+                              grpc_method_config* method_config);
 
 /// Compares two grpc_method_configs.
 /// The sort order is stable but undefined.
@@ -95,7 +96,8 @@ grpc_method_config_table* grpc_method_config_table_create(
 
 grpc_method_config_table* grpc_method_config_table_ref(
     grpc_method_config_table* table);
-void grpc_method_config_table_unref(grpc_method_config_table* table);
+void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx,
+                                    grpc_method_config_table* table);
 
 /// Compares two grpc_method_config_tables.
 /// The sort order is stable but undefined.
@@ -110,7 +112,8 @@ int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
 /// Note: This returns a void* instead of a grpc_method_config* so that
 /// it can also be used for tables constructed via
 /// grpc_method_config_table_convert().
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
                                    const grpc_mdstr* path);
 
 /// Returns a channel arg containing \a table.
@@ -129,7 +132,7 @@ grpc_arg grpc_method_config_table_create_channel_arg(
 /// the grpc_method_config, and \a vtable provides the methods for
 /// operating on the struct type.
 grpc_mdstr_hash_table* grpc_method_config_table_convert(
-    const grpc_method_config_table* table,
+    grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table,
     void* (*convert_value)(const grpc_method_config* method_config),
     const grpc_mdstr_hash_table_vtable* vtable);
 
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index 866cd9ea87..1b79520e68 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport_impl.h"
@@ -207,12 +208,12 @@ void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
 }
 
 void grpc_transport_stream_op_add_cancellation_with_message(
-    grpc_transport_stream_op *op, grpc_status_code status,
-    grpc_slice *optional_message) {
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+    grpc_status_code status, grpc_slice *optional_message) {
   GPR_ASSERT(status != GRPC_STATUS_OK);
   if (op->cancel_error != GRPC_ERROR_NONE) {
     if (optional_message) {
-      grpc_slice_unref(*optional_message);
+      grpc_slice_unref_internal(exec_ctx, *optional_message);
     }
     return;
   }
@@ -222,7 +223,7 @@ void grpc_transport_stream_op_add_cancellation_with_message(
     error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
                                GRPC_ERROR_STR_GRPC_MESSAGE, msg);
     gpr_free(msg);
-    grpc_slice_unref(*optional_message);
+    grpc_slice_unref_internal(exec_ctx, *optional_message);
   } else {
     error = GRPC_ERROR_CREATE("Call cancelled");
   }
@@ -230,14 +231,15 @@ void grpc_transport_stream_op_add_cancellation_with_message(
   add_error(op, &op->cancel_error, error);
 }
 
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+                                        grpc_transport_stream_op *op,
                                         grpc_status_code status,
                                         grpc_slice *optional_message) {
   GPR_ASSERT(status != GRPC_STATUS_OK);
   if (op->cancel_error != GRPC_ERROR_NONE ||
       op->close_error != GRPC_ERROR_NONE) {
     if (optional_message) {
-      grpc_slice_unref(*optional_message);
+      grpc_slice_unref_internal(exec_ctx, *optional_message);
     }
     return;
   }
@@ -247,7 +249,7 @@ void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
     error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
                                GRPC_ERROR_STR_GRPC_MESSAGE, msg);
     gpr_free(msg);
-    grpc_slice_unref(*optional_message);
+    grpc_slice_unref_internal(exec_ctx, *optional_message);
   } else {
     error = GRPC_ERROR_CREATE("Call force closed");
   }
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 8916b28b72..3e38d98f28 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -248,10 +248,11 @@ void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
                                                grpc_status_code status);
 
 void grpc_transport_stream_op_add_cancellation_with_message(
-    grpc_transport_stream_op *op, grpc_status_code status,
-    grpc_slice *optional_message);
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+    grpc_status_code status, grpc_slice *optional_message);
 
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+                                        grpc_transport_stream_op *op,
                                         grpc_status_code status,
                                         grpc_slice *optional_message);
 
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 07fcd995d7..126ea54b69 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -117,7 +117,7 @@ void grpc_run_bad_client_test(
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("bad_client_test");
   sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   /* Create server, completion events */
   a.server = grpc_server_create(NULL, NULL);
@@ -181,7 +181,7 @@ void grpc_run_bad_client_test(
       grpc_exec_ctx_finish(&exec_ctx);
       GPR_ASSERT(
           gpr_event_wait(&args.read_done, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
-      grpc_slice_buffer_destroy(&args.incoming);
+      grpc_slice_buffer_destroy_internal(exec_ctx, &args.incoming);
     }
     // Shutdown.
     grpc_endpoint_shutdown(&exec_ctx, sfd.client);
@@ -194,7 +194,7 @@ void grpc_run_bad_client_test(
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(a.server);
   grpc_completion_queue_destroy(a.cq);
-  grpc_slice_buffer_destroy(&outgoing);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &outgoing);
 
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index 9c804e78c1..809bbe4094 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -213,7 +213,7 @@ static void client_validator(grpc_slice_buffer *incoming) {
   *p++ = 11;
   // Compare actual and expected.
   GPR_ASSERT(grpc_slice_cmp(last_frame, expected) == 0);
-  grpc_slice_buffer_destroy(&last_frame_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &last_frame_buffer);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
index a10d28b30f..d8eca036ed 100644
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ b/test/core/client_channel/set_initial_connect_string_test.c
@@ -155,8 +155,8 @@ static void start_rpc(int use_creds, int target_port) {
 
 static void cleanup_rpc(void) {
   grpc_event ev;
-  grpc_slice_buffer_destroy(&state.incoming_buffer);
-  grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
   grpc_channel_credentials_unref(state.creds);
   grpc_call_destroy(state.call);
   grpc_completion_queue_shutdown(state.cq);
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index fc53cd9d36..ee4f0dbe40 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -105,10 +105,10 @@ static void assert_passthrough(grpc_slice value,
   final = grpc_slice_merge(output.slices, output.count);
   GPR_ASSERT(0 == grpc_slice_cmp(value, final));
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&compressed);
-  grpc_slice_buffer_destroy(&compressed_raw);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &compressed);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &compressed_raw);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
   grpc_slice_unref(final);
 }
 
@@ -164,8 +164,8 @@ static void test_tiny_data_compress(void) {
     GPR_ASSERT(1 == output.count);
   }
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 static void test_bad_decompression_data_crc(void) {
@@ -191,9 +191,9 @@ static void test_bad_decompression_data_crc(void) {
   /* try (and fail) to decompress the corrupted compresed buffer */
   GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output));
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&corrupted);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &corrupted);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 static void test_bad_decompression_data_trailing_garbage(void) {
@@ -210,8 +210,8 @@ static void test_bad_decompression_data_trailing_garbage(void) {
   /* try (and fail) to decompress the invalid compresed buffer */
   GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 static void test_bad_decompression_data_stream(void) {
@@ -226,8 +226,8 @@ static void test_bad_decompression_data_stream(void) {
   /* try (and fail) to decompress the invalid compresed buffer */
   GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 static void test_bad_compression_algorithm(void) {
@@ -247,8 +247,8 @@ static void test_bad_compression_algorithm(void) {
       grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_compressed);
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 static void test_bad_decompression_algorithm(void) {
@@ -269,8 +269,8 @@ static void test_bad_decompression_algorithm(void) {
                                          &input, &output);
   GPR_ASSERT(0 == was_decompressed);
 
-  grpc_slice_buffer_destroy(&input);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 1c4a17fda8..9dc70d79ec 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -228,8 +228,8 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
 
 static void cleanup_rpc(void) {
   grpc_event ev;
-  grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
-  grpc_slice_buffer_destroy(&state.outgoing_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing_buffer);
   grpc_call_destroy(state.call);
   grpc_completion_queue_shutdown(state.cq);
   do {
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 11e8604f56..dc03861f86 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -145,7 +145,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
       gpr_free(hosts_with_port[i]);
     }
     gpr_free(hosts_with_port);
-    grpc_slice_buffer_destroy(&uri_parts);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &uri_parts);
     grpc_slice_unref(uri_slice);
   } else {
     gpr_join_host_port(&client_hostport, client_host, port);
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 32856a5db9..e6cdaf7bfe 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -189,7 +189,7 @@ static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
     addresses->addresses[i].is_balancer = lb_enabled;
     if (errors_found) break;
   }
-  grpc_slice_buffer_destroy(&path_parts);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
   grpc_slice_unref(path_slice);
   if (errors_found) {
     grpc_lb_addresses_destroy(addresses);
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c
index 57fc4a38f8..9c808209e3 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy.c
@@ -110,12 +110,12 @@ static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
     if (conn->server_endpoint != NULL)
       grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
     grpc_pollset_set_destroy(conn->pollset_set);
-    grpc_slice_buffer_destroy(&conn->client_read_buffer);
-    grpc_slice_buffer_destroy(&conn->client_deferred_write_buffer);
-    grpc_slice_buffer_destroy(&conn->client_write_buffer);
-    grpc_slice_buffer_destroy(&conn->server_read_buffer);
-    grpc_slice_buffer_destroy(&conn->server_deferred_write_buffer);
-    grpc_slice_buffer_destroy(&conn->server_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_deferred_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_deferred_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_write_buffer);
     grpc_http_parser_destroy(&conn->http_parser);
     grpc_http_request_destroy(&conn->http_request);
     gpr_free(conn);
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index c5260cd287..26b520885b 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -62,7 +62,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
       grpc_resource_quota_create("client_fuzzer");
   grpc_endpoint *mock_endpoint =
       grpc_mock_endpoint_create(discard_write, resource_quota);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
   grpc_transport *transport =
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 164022ec79..115fb06925 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -60,7 +60,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
       grpc_resource_quota_create("server_fuzzer");
   grpc_endpoint *mock_endpoint =
       grpc_mock_endpoint_create(discard_write, resource_quota);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_mock_endpoint_put_read(
       &exec_ctx, mock_endpoint,
       grpc_slice_from_copied_buffer((const char *)data, size));
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index 3e312c1dde..57b779cccf 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -93,7 +93,7 @@ static void test_get(int port) {
   grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                    n_seconds_time(15),
                    grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
@@ -133,7 +133,7 @@ static void test_post(int port) {
   grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                     "hello", 5, n_seconds_time(15),
                     grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index d06035149e..765ae101c5 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -94,7 +94,7 @@ static void test_get(int port) {
   grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                    n_seconds_time(15),
                    grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
@@ -135,7 +135,7 @@ static void test_post(int port) {
   grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                     "hello", 5, n_seconds_time(15),
                     grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 8186ea7e85..09a1e611f4 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -249,8 +249,8 @@ static void read_and_write_test(grpc_endpoint_test_config config,
   grpc_exec_ctx_flush(&exec_ctx);
 
   end_test(config);
-  grpc_slice_buffer_destroy(&state.outgoing);
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, state.read_ep);
   grpc_endpoint_destroy(&exec_ctx, state.write_ep);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -304,7 +304,7 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) {
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
 
-  grpc_slice_buffer_destroy(&slice_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &slice_buffer);
 
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index 6dc9f8b76a..8ba8af26a8 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -672,7 +672,7 @@ static void test_one_slice(void) {
     GPR_ASSERT(num_allocs == start_allocs + 1);
   }
 
-  grpc_slice_buffer_destroy(&buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &buffer);
   destroy_user(&usr);
   grpc_resource_quota_unref(q);
 }
@@ -712,7 +712,7 @@ static void test_one_slice_deleted_late(void) {
   }
 
   grpc_resource_quota_unref(q);
-  grpc_slice_buffer_destroy(&buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &buffer);
   GPR_ASSERT(done);
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 5eafa570bb..81b9ef5dff 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -184,7 +184,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("read_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
                        slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -212,7 +212,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -235,7 +235,7 @@ static void large_read_test(size_t slice_size) {
       grpc_resource_quota_create("large_read_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), resource_quota,
                        slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket(sv[0]);
@@ -263,7 +263,7 @@ static void large_read_test(size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -374,7 +374,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
       grpc_resource_quota_create("write_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), resource_quota,
                        GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   state.ep = ep;
@@ -404,7 +404,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
   }
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&outgoing);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &outgoing);
   grpc_endpoint_destroy(&exec_ctx, ep);
   gpr_free(slices);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -442,7 +442,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
                        slice_size, "test");
   GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -472,7 +472,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
   grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
   grpc_exec_ctx_flush(&exec_ctx);
   gpr_mu_lock(g_mu);
@@ -534,7 +534,7 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair(
                                 resource_quota, slice_size, "test");
   f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
                                 resource_quota, slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
 
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index b5d95004fe..e49662d428 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -59,7 +59,7 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("secure_endpoint_test");
   tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
 
@@ -171,7 +171,7 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_slice_unref(s);
-  grpc_slice_buffer_destroy(&incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &incoming);
 
   clean_up();
 }
diff --git a/test/core/slice/slice_buffer_test.c b/test/core/slice/slice_buffer_test.c
index bf9ae197d2..e5ef3047e5 100644
--- a/test/core/slice/slice_buffer_test.c
+++ b/test/core/slice/slice_buffer_test.c
@@ -68,7 +68,7 @@ void test_slice_buffer_add() {
   }
   GPR_ASSERT(buf.count == 0);
   GPR_ASSERT(buf.length == 0);
-  grpc_slice_buffer_destroy(&buf);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &buf);
 }
 
 void test_slice_buffer_move_first() {
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index d8d7a52d15..0d1628821b 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -162,8 +162,8 @@ static void read_compressed_slice(grpc_compression_algorithm algorithm,
   GPR_ASSERT(read_count == input_size);
   grpc_byte_buffer_reader_destroy(&reader);
   grpc_byte_buffer_destroy(buffer);
-  grpc_slice_buffer_destroy(&sliceb_out);
-  grpc_slice_buffer_destroy(&sliceb_in);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &sliceb_out);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &sliceb_in);
 }
 
 static void test_read_gzip_compressed_slice(void) {
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 91421e18f4..6f1a1f7223 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -101,7 +101,7 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
   grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
                             &output);
   merged = grpc_slice_merge(output.slices, output.count);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
   grpc_metadata_batch_destroy(&b);
 
   if (0 != grpc_slice_cmp(merged, expect)) {
@@ -205,7 +205,7 @@ static void verify_table_size_change_match_elem_size(const char *key,
   memset(&stats, 0, sizeof(stats));
   grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats,
                             &output);
-  grpc_slice_buffer_destroy(&output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
   grpc_metadata_batch_destroy(&b);
 
   GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index 6e09427c2b..1d33566221 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -82,7 +82,7 @@ static void unref(grpc_exec_ctx *exec_ctx, grpc_mock_endpoint *m) {
   gpr_mu_lock(&m->mu);
   if (0 == --m->refs) {
     gpr_mu_unlock(&m->mu);
-    grpc_slice_buffer_destroy(&m->read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &m->read_buffer);
     grpc_resource_user_destroy(exec_ctx, &m->resource_user);
     gpr_free(m);
   } else {
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index a5bac8aaa8..db10de87d9 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -132,8 +132,8 @@ static void me_really_destroy(grpc_exec_ctx *exec_ctx, void *ep,
   if (0 == --p->halves) {
     gpr_mu_unlock(&p->mu);
     gpr_mu_destroy(&p->mu);
-    grpc_slice_buffer_destroy(&p->client.read_buffer);
-    grpc_slice_buffer_destroy(&p->server.read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &p->client.read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &p->server.read_buffer);
     gpr_free(p);
   } else {
     gpr_mu_unlock(&p->mu);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index b2342feeb4..384a158c47 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -104,7 +104,7 @@ void grpc_free_port_using_server(char *server, int port) {
   grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                    grpc_closure_create(freed_port_from_server, &pr), &rsp);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(pr.mu);
   while (!pr.done) {
     grpc_pollset_worker *worker = NULL;
@@ -176,7 +176,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                      grpc_closure_create(got_port_from_server, pr),
                      &pr->response);
-    grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+    grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
     return;
   }
   GPR_ASSERT(response);
@@ -223,7 +223,7 @@ int grpc_pick_port_using_server(char *server) {
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                    grpc_closure_create(got_port_from_server, &pr),
                    &pr.response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
new file mode 100755
index 0000000000..a3d4d6337e
--- /dev/null
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+# map of banned function signature to whitelist
+BANNED_EXCEPT = {
+    'grpc_resource_quota_ref(': ('src/core/lib/iomgr/resource_quota.c'),
+    'grpc_resource_quota_unref(': ('src/core/lib/iomgr/resource_quota.c'),
+    'grpc_slice_buffer_destroy(': ('src/core/lib/slice/slice_buffer.c'),
+    'grpc_slice_buffer_reset_and_unref(': ('src/core/lib/slice/slice_buffer.c'),
+    'grpc_slice_ref(': ('src/core/lib/slice/slice.c'),
+    'grpc_slice_unref(': ('src/core/lib/slice/slice.c'),
+}
+
+errors = 0
+for root, dirs, files in os.walk('src/core'):
+  for filename in files:
+    path = os.path.join(root, filename)
+    if os.path.splitext(path)[1] != '.c': continue
+    with open(path) as f:
+      text = f.read()
+    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)
+        errors += 1
+
+assert errors == 0
+
-- 
GitLab


From bd1795ca8af6ea15c83ee0556b7a24add9464f00 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 31 Oct 2016 15:30:00 -0700
Subject: [PATCH 025/344] Convert more users of grpc_slice_unref -->
 grpc_slice_unref_internal

---
 .../server/secure/server_secure_chttp2.c      |  9 +--
 .../chttp2/transport/chttp2_transport.c       | 10 +--
 .../transport/chttp2/transport/hpack_parser.c |  6 +-
 .../transport/chttp2/transport/hpack_parser.h |  6 +-
 .../chttp2/transport/incoming_metadata.c      |  4 +-
 .../chttp2/transport/incoming_metadata.h      |  2 +-
 .../ext/transport/chttp2/transport/parsing.c  | 10 +--
 .../ext/transport/chttp2/transport/writing.c  |  8 +--
 .../lib/http/httpcli_security_connector.c     | 14 ++--
 .../lib/security/context/security_context.c   | 10 ++-
 .../composite/composite_credentials.c         | 31 ++++----
 .../lib/security/credentials/credentials.c    | 55 +++++++++-----
 .../lib/security/credentials/credentials.h    | 39 +++++-----
 .../credentials/credentials_metadata.c        |  5 +-
 .../credentials/fake/fake_credentials.c       | 17 +++--
 .../google_default_credentials.c              | 37 +++++-----
 .../credentials/iam/iam_credentials.c         |  5 +-
 .../credentials/jwt/jwt_credentials.c         | 28 +++++---
 .../credentials/jwt/jwt_credentials.h         |  3 +-
 .../security/credentials/jwt/jwt_verifier.c   | 72 +++++++++++--------
 .../security/credentials/jwt/jwt_verifier.h   |  5 +-
 .../credentials/oauth2/oauth2_credentials.c   | 29 ++++----
 .../credentials/oauth2/oauth2_credentials.h   |  2 +-
 .../credentials/plugin/plugin_credentials.c   | 12 ++--
 .../credentials/ssl/ssl_credentials.c         | 20 +++---
 .../security/transport/client_auth_filter.c   | 19 ++---
 src/core/lib/security/transport/handshake.c   | 13 ++--
 .../lib/security/transport/secure_endpoint.c  |  1 +
 .../security/transport/security_connector.c   | 37 ++++++----
 .../security/transport/security_connector.h   | 20 +++---
 .../security/transport/server_auth_filter.c   |  8 +--
 31 files changed, 319 insertions(+), 218 deletions(-)

diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index 15ef778ebc..6293e06b69 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -199,8 +199,8 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *statep,
 
   /* Flush queued work before a synchronous unref. */
   grpc_exec_ctx_flush(exec_ctx);
-  GRPC_SECURITY_CONNECTOR_UNREF(&server_state->sc->base, "server");
-  grpc_server_credentials_unref(server_state->creds);
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &server_state->sc->base, "server");
+  grpc_server_credentials_unref(exec_ctx, server_state->creds);
 
   if (destroy_done != NULL) {
     destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
@@ -249,7 +249,8 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
         "No credentials specified for secure server port (creds==NULL)");
     goto error;
   }
-  status = grpc_server_credentials_create_security_connector(creds, &sc);
+  status =
+      grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc);
   if (status != GRPC_SECURITY_OK) {
     char *msg;
     gpr_asprintf(&msg,
@@ -349,7 +350,7 @@ error:
   } else {
     if (sc) {
       grpc_exec_ctx_flush(&exec_ctx);
-      GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
+      GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server");
     }
     if (server_state) {
       gpr_free(server_state);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 0c61159495..96d916e414 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -151,7 +151,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
   grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor);
 
   grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer);
-  grpc_chttp2_hpack_parser_destroy(&t->hpack_parser);
+  grpc_chttp2_hpack_parser_destroy(exec_ctx, &t->hpack_parser);
   grpc_chttp2_goaway_parser_destroy(&t->goaway_parser);
 
   for (i = 0; i < STREAM_LIST_COUNT; i++) {
@@ -264,7 +264,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                     destructive_reclaimer_locked, t);
 
   grpc_chttp2_goaway_parser_init(&t->goaway_parser);
-  grpc_chttp2_hpack_parser_init(&t->hpack_parser);
+  grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
 
   grpc_slice_buffer_init(&t->read_buffer);
 
@@ -531,8 +531,10 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
   GPR_ASSERT(s->recv_message_ready == NULL);
   GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
   grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser);
-  grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]);
-  grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]);
+  grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+                                               &s->metadata_buffer[0]);
+  grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+                                               &s->metadata_buffer[1]);
   grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
   GRPC_ERROR_UNREF(s->read_closed_error);
   GRPC_ERROR_UNREF(s->write_closed_error);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index e805aac8c4..f69fbd48a9 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -1533,7 +1533,8 @@ static grpc_error *parse_value_string_with_literal_key(
 
 /* PUBLIC INTERFACE */
 
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+                                   grpc_chttp2_hpack_parser *p) {
   p->on_header = NULL;
   p->on_header_user_data = NULL;
   p->state = parse_begin;
@@ -1553,7 +1554,8 @@ void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
   p->state = parse_stream_dep0;
 }
 
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+                                      grpc_chttp2_hpack_parser *p) {
   grpc_chttp2_hptbl_destroy(exec_ctx, &p->table);
   GRPC_ERROR_UNREF(p->last_error);
   gpr_free(p->key.str);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h
index a39bf466cd..52ccf1e7a7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h
@@ -99,8 +99,10 @@ struct grpc_chttp2_hpack_parser {
   grpc_chttp2_hptbl table;
 };
 
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p);
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+                                   grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+                                      grpc_chttp2_hpack_parser *p);
 
 void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p);
 
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.c b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
index 3e463a7995..5d1094999c 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.c
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
@@ -46,11 +46,11 @@ void grpc_chttp2_incoming_metadata_buffer_init(
 }
 
 void grpc_chttp2_incoming_metadata_buffer_destroy(
-    grpc_chttp2_incoming_metadata_buffer *buffer) {
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) {
   size_t i;
   if (!buffer->published) {
     for (i = 0; i < buffer->count; i++) {
-      GRPC_MDELEM_UNREF(buffer->elems[i].md);
+      GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
     }
   }
   gpr_free(buffer->elems);
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index df4343b93e..7a0c4da15f 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -49,7 +49,7 @@ typedef struct {
 void grpc_chttp2_incoming_metadata_buffer_init(
     grpc_chttp2_incoming_metadata_buffer *buffer);
 void grpc_chttp2_incoming_metadata_buffer_destroy(
-    grpc_chttp2_incoming_metadata_buffer *buffer);
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer);
 void grpc_chttp2_incoming_metadata_buffer_publish(
     grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch);
 
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index b9c405158f..e1202e2ca5 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -336,7 +336,7 @@ static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser,
 }
 
 static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) {
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 
 static grpc_error *init_skip_frame_parser(grpc_exec_ctx *exec_ctx,
@@ -476,7 +476,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
     grpc_chttp2_incoming_metadata_buffer_set_deadline(
         &s->metadata_buffer[0],
         gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
   } else {
     const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
     const size_t metadata_size_limit =
@@ -494,7 +494,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
       grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
       s->seen_error = true;
-      GRPC_MDELEM_UNREF(md);
+      GRPC_MDELEM_UNREF(exec_ctx, md);
     } else {
       grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
     }
@@ -537,7 +537,7 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
             GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
     s->seen_error = true;
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
   } else {
     grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md);
   }
@@ -711,7 +711,7 @@ static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx,
     memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS],
            GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
     grpc_chttp2_hptbl_set_max_bytes(
-        &t->hpack_parser.table,
+        exec_ctx, &t->hpack_parser.table,
         t->settings[GRPC_ACKED_SETTINGS]
                    [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
     t->sent_local_settings = 0;
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index d7f45b16ad..ef2010af7b 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -120,7 +120,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
     /* send initial metadata if it's available */
     if (!sent_initial_metadata && s->send_initial_metadata) {
       grpc_chttp2_encode_header(
-          &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
+          exec_ctx, &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
           t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
           &s->stats.outgoing, &t->outbuf);
       s->send_initial_metadata = NULL;
@@ -187,9 +187,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
                                   &s->stats.outgoing, &t->outbuf);
         } else {
           grpc_chttp2_encode_header(
-              &t->hpack_compressor, s->id, s->send_trailing_metadata, true,
-              t->settings[GRPC_ACKED_SETTINGS]
-                         [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
+              exec_ctx, &t->hpack_compressor, s->id, s->send_trailing_metadata,
+              true, t->settings[GRPC_ACKED_SETTINGS]
+                               [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
               &s->stats.outgoing, &t->outbuf);
         }
         s->send_trailing_metadata = NULL;
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 24d264c32a..e8575d4e6e 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -48,7 +48,8 @@ typedef struct {
   char *secure_peer_name;
 } grpc_httpcli_ssl_channel_security_connector;
 
-static void httpcli_ssl_destroy(grpc_security_connector *sc) {
+static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_httpcli_ssl_channel_security_connector *c =
       (grpc_httpcli_ssl_channel_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
@@ -111,8 +112,9 @@ static grpc_security_connector_vtable httpcli_ssl_vtable = {
     httpcli_ssl_destroy, httpcli_ssl_check_peer};
 
 static grpc_security_status httpcli_ssl_channel_security_connector_create(
-    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *secure_peer_name, grpc_channel_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
+    size_t pem_root_certs_size, const char *secure_peer_name,
+    grpc_channel_security_connector **sc) {
   tsi_result result = TSI_OK;
   grpc_httpcli_ssl_channel_security_connector *c;
 
@@ -136,7 +138,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    httpcli_ssl_destroy(&c->base.base);
+    httpcli_ssl_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     return GRPC_SECURITY_ERROR;
   }
@@ -184,11 +186,11 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
   c->func = on_done;
   c->arg = arg;
   GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
-                 pem_root_certs, pem_root_certs_size, host, &sc) ==
+                 exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
              GRPC_SECURITY_OK);
   grpc_channel_security_connector_do_handshake(
       exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c);
-  GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "httpcli");
 }
 
 const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake};
diff --git a/src/core/lib/security/context/security_context.c b/src/core/lib/security/context/security_context.c
index 2204fadf54..fe82fabc31 100644
--- a/src/core/lib/security/context/security_context.c
+++ b/src/core/lib/security/context/security_context.c
@@ -47,6 +47,7 @@
 
 grpc_call_error grpc_call_set_credentials(grpc_call *call,
                                           grpc_call_credentials *creds) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_client_security_context *ctx = NULL;
   GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2,
                  (call, creds));
@@ -62,9 +63,10 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call,
     grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
                           grpc_client_security_context_destroy);
   } else {
-    grpc_call_credentials_unref(ctx->creds);
+    grpc_call_credentials_unref(&exec_ctx, ctx->creds);
     ctx->creds = grpc_call_credentials_ref(creds);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return GRPC_CALL_OK;
 }
 
@@ -96,13 +98,15 @@ grpc_client_security_context *grpc_client_security_context_create(void) {
 }
 
 void grpc_client_security_context_destroy(void *ctx) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_client_security_context *c = (grpc_client_security_context *)ctx;
-  grpc_call_credentials_unref(c->creds);
+  grpc_call_credentials_unref(&exec_ctx, c->creds);
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
   if (c->extension.instance != NULL && c->extension.destroy != NULL) {
     c->extension.destroy(c->extension.instance);
   }
   gpr_free(ctx);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* --- grpc_server_security_context --- */
@@ -307,7 +311,7 @@ void grpc_auth_property_reset(grpc_auth_property *property) {
   memset(property, 0, sizeof(grpc_auth_property));
 }
 
-static void auth_context_pointer_arg_destroy(void *p) {
+static void auth_context_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
   GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
 }
 
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.c
index d55d00b7b6..be1588dd8b 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.c
@@ -54,18 +54,20 @@ typedef struct {
   grpc_credentials_metadata_cb cb;
 } grpc_composite_call_credentials_metadata_context;
 
-static void composite_call_destruct(grpc_call_credentials *creds) {
+static void composite_call_destruct(grpc_exec_ctx *exec_ctx,
+                                    grpc_call_credentials *creds) {
   grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   size_t i;
   for (i = 0; i < c->inner.num_creds; i++) {
-    grpc_call_credentials_unref(c->inner.creds_array[i]);
+    grpc_call_credentials_unref(exec_ctx, c->inner.creds_array[i]);
   }
   gpr_free(c->inner.creds_array);
 }
 
 static void composite_call_md_context_destroy(
+    grpc_exec_ctx *exec_ctx,
     grpc_composite_call_credentials_metadata_context *ctx) {
-  grpc_credentials_md_store_unref(ctx->md_elems);
+  grpc_credentials_md_store_unref(exec_ctx, ctx->md_elems);
   gpr_free(ctx);
 }
 
@@ -103,7 +105,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
   /* We're done!. */
   ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
           ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK, NULL);
-  composite_call_md_context_destroy(ctx);
+  composite_call_md_context_destroy(exec_ctx, ctx);
 }
 
 static void composite_call_get_request_metadata(
@@ -209,17 +211,19 @@ grpc_call_credentials *grpc_credentials_contains_type(
 
 /* -- Composite channel credentials. -- */
 
-static void composite_channel_destruct(grpc_channel_credentials *creds) {
+static void composite_channel_destruct(grpc_exec_ctx *exec_ctx,
+                                       grpc_channel_credentials *creds) {
   grpc_composite_channel_credentials *c =
       (grpc_composite_channel_credentials *)creds;
-  grpc_channel_credentials_unref(c->inner_creds);
-  grpc_call_credentials_unref(c->call_creds);
+  grpc_channel_credentials_unref(exec_ctx, c->inner_creds);
+  grpc_call_credentials_unref(exec_ctx, c->call_creds);
 }
 
 static grpc_security_status composite_channel_create_security_connector(
-    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   grpc_composite_channel_credentials *c =
       (grpc_composite_channel_credentials *)creds;
   grpc_security_status status = GRPC_SECURITY_ERROR;
@@ -233,11 +237,12 @@ static grpc_security_status composite_channel_create_security_connector(
     grpc_call_credentials *composite_call_creds =
         grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
     status = c->inner_creds->vtable->create_security_connector(
-        c->inner_creds, composite_call_creds, target, args, sc, new_args);
-    grpc_call_credentials_unref(composite_call_creds);
+        exec_ctx, c->inner_creds, composite_call_creds, target, args, sc,
+        new_args);
+    grpc_call_credentials_unref(exec_ctx, composite_call_creds);
   } else {
     status = c->inner_creds->vtable->create_security_connector(
-        c->inner_creds, c->call_creds, target, args, sc, new_args);
+        exec_ctx, c->inner_creds, c->call_creds, target, args, sc, new_args);
   }
   return status;
 }
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 1149e5c2ed..9781a22a86 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -66,8 +66,8 @@ grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
 }
 
 void grpc_credentials_metadata_request_destroy(
-    grpc_credentials_metadata_request *r) {
-  grpc_call_credentials_unref(r->creds);
+    grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r) {
+  grpc_call_credentials_unref(exec_ctx, r->creds);
   grpc_http_response_destroy(&r->response);
   gpr_free(r);
 }
@@ -79,17 +79,22 @@ grpc_channel_credentials *grpc_channel_credentials_ref(
   return creds;
 }
 
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     gpr_free(creds);
   }
 }
 
 void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
   GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
-  grpc_channel_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_channel_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
@@ -98,17 +103,22 @@ grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
   return creds;
 }
 
-void grpc_call_credentials_unref(grpc_call_credentials *creds) {
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                 grpc_call_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     gpr_free(creds);
   }
 }
 
 void grpc_call_credentials_release(grpc_call_credentials *creds) {
   GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
-  grpc_call_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void grpc_call_credentials_get_request_metadata(
@@ -126,16 +136,16 @@ void grpc_call_credentials_get_request_metadata(
 }
 
 grpc_security_status grpc_channel_credentials_create_security_connector(
-    grpc_channel_credentials *channel_creds, const char *target,
-    const grpc_channel_args *args, grpc_channel_security_connector **sc,
-    grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *channel_creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
   *new_args = NULL;
   if (channel_creds == NULL) {
     return GRPC_SECURITY_ERROR;
   }
   GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
   return channel_creds->vtable->create_security_connector(
-      channel_creds, NULL, target, args, sc, new_args);
+      exec_ctx, channel_creds, NULL, target, args, sc, new_args);
 }
 
 grpc_channel_credentials *
@@ -157,10 +167,13 @@ grpc_server_credentials *grpc_server_credentials_ref(
   return creds;
 }
 
-void grpc_server_credentials_unref(grpc_server_credentials *creds) {
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_server_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
       creds->processor.destroy(creds->processor.state);
     }
@@ -170,16 +183,19 @@ void grpc_server_credentials_unref(grpc_server_credentials *creds) {
 
 void grpc_server_credentials_release(grpc_server_credentials *creds) {
   GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
-  grpc_server_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_server_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc) {
   if (creds == NULL || creds->vtable->create_security_connector == NULL) {
     gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
     return GRPC_SECURITY_ERROR;
   }
-  return creds->vtable->create_security_connector(creds, sc);
+  return creds->vtable->create_security_connector(exec_ctx, creds, sc);
 }
 
 void grpc_server_credentials_set_auth_metadata_processor(
@@ -196,8 +212,9 @@ void grpc_server_credentials_set_auth_metadata_processor(
   creds->processor = processor;
 }
 
-static void server_credentials_pointer_arg_destroy(void *p) {
-  grpc_server_credentials_unref(p);
+static void server_credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx,
+                                                   void *p) {
+  grpc_server_credentials_unref(exec_ctx, p);
 }
 
 static void *server_credentials_pointer_arg_copy(void *p) {
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 85b3bc5350..3011df6b8a 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -101,12 +101,13 @@ void grpc_override_well_known_credentials_path_getter(
 /* --- grpc_channel_credentials. --- */
 
 typedef struct {
-  void (*destruct)(grpc_channel_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c);
 
   grpc_security_status (*create_security_connector)(
-      grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-      const char *target, const grpc_channel_args *args,
-      grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+      grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+      grpc_call_credentials *call_creds, const char *target,
+      const grpc_channel_args *args, grpc_channel_security_connector **sc,
+      grpc_channel_args **new_args);
 
   grpc_channel_credentials *(*duplicate_without_call_credentials)(
       grpc_channel_credentials *c);
@@ -120,16 +121,17 @@ struct grpc_channel_credentials {
 
 grpc_channel_credentials *grpc_channel_credentials_ref(
     grpc_channel_credentials *creds);
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds);
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_credentials *creds);
 
 /* Creates a security connector for the channel. May also create new channel
    args for the channel to be used in place of the passed in const args if
    returned non NULL. In that case the caller is responsible for destroying
    new_args after channel creation. */
 grpc_security_status grpc_channel_credentials_create_security_connector(
-    grpc_channel_credentials *creds, const char *target,
-    const grpc_channel_args *args, grpc_channel_security_connector **sc,
-    grpc_channel_args **new_args);
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args);
 
 /* Creates a version of the channel credentials without any attached call
    credentials. This can be used in order to open a channel to a non-trusted
@@ -162,7 +164,8 @@ void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store,
                                             const char *key, const char *value);
 grpc_credentials_md_store *grpc_credentials_md_store_ref(
     grpc_credentials_md_store *store);
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+                                     grpc_credentials_md_store *store);
 
 /* --- grpc_call_credentials. --- */
 
@@ -172,7 +175,7 @@ typedef void (*grpc_credentials_metadata_cb)(
     size_t num_md, grpc_credentials_status status, const char *error_details);
 
 typedef struct {
-  void (*destruct)(grpc_call_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_call_credentials *c);
   void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
                                grpc_call_credentials *c,
                                grpc_polling_entity *pollent,
@@ -188,7 +191,8 @@ struct grpc_call_credentials {
 };
 
 grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
-void grpc_call_credentials_unref(grpc_call_credentials *creds);
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                 grpc_call_credentials *creds);
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_polling_entity *pollent, grpc_auth_metadata_context context,
@@ -202,9 +206,10 @@ grpc_call_credentials *grpc_md_only_test_credentials_create(
 /* --- grpc_server_credentials. --- */
 
 typedef struct {
-  void (*destruct)(grpc_server_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_server_credentials *c);
   grpc_security_status (*create_security_connector)(
-      grpc_server_credentials *c, grpc_server_security_connector **sc);
+      grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+      grpc_server_security_connector **sc);
 } grpc_server_credentials_vtable;
 
 struct grpc_server_credentials {
@@ -215,12 +220,14 @@ struct grpc_server_credentials {
 };
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc);
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc);
 
 grpc_server_credentials *grpc_server_credentials_ref(
     grpc_server_credentials *creds);
 
-void grpc_server_credentials_unref(grpc_server_credentials *creds);
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_server_credentials *creds);
 
 #define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
 
@@ -243,6 +250,6 @@ grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
     void *user_data);
 
 void grpc_credentials_metadata_request_destroy(
-    grpc_credentials_metadata_request *r);
+    grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/credentials_metadata.c b/src/core/lib/security/credentials/credentials_metadata.c
index 84e2b8991a..68da5fb4a8 100644
--- a/src/core/lib/security/credentials/credentials_metadata.c
+++ b/src/core/lib/security/credentials/credentials_metadata.c
@@ -37,6 +37,8 @@
 
 #include <string.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 static void store_ensure_capacity(grpc_credentials_md_store *store) {
   if (store->num_entries == store->allocated) {
     store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2;
@@ -85,7 +87,8 @@ grpc_credentials_md_store *grpc_credentials_md_store_ref(
   return store;
 }
 
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) {
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+                                     grpc_credentials_md_store *store) {
   if (store == NULL) return;
   if (gpr_unref(&store->refcount)) {
     if (store->entries != NULL) {
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index ea4cb76fb9..f41184f9f9 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -45,16 +45,18 @@
 /* -- Fake transport security credentials. -- */
 
 static grpc_security_status fake_transport_security_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   *sc = grpc_fake_channel_security_connector_create(call_creds);
   return GRPC_SECURITY_OK;
 }
 
 static grpc_security_status
 fake_transport_security_server_create_security_connector(
-    grpc_server_credentials *c, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+    grpc_server_security_connector **sc) {
   *sc = grpc_fake_server_security_connector_create();
   return GRPC_SECURITY_OK;
 }
@@ -89,9 +91,10 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
 
 /* -- Metadata-only test credentials. -- */
 
-static void md_only_test_destruct(grpc_call_credentials *creds) {
+static void md_only_test_destruct(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_credentials *creds) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
-  grpc_credentials_md_store_unref(c->md_store);
+  grpc_credentials_md_store_unref(exec_ctx, c->md_store);
 }
 
 static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
@@ -101,7 +104,7 @@ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
   r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
         GRPC_CREDENTIALS_OK, NULL);
-  grpc_credentials_metadata_request_destroy(r);
+  grpc_credentials_metadata_request_destroy(exec_ctx, r);
 }
 
 static void md_only_test_get_request_metadata(
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index 5df97e1671..7bed78daf7 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
@@ -101,11 +102,10 @@ static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, grpc_error *e) {
   grpc_pollset_destroy(p);
 }
 
-static int is_stack_running_on_compute_engine(void) {
+static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
   compute_engine_detector detector;
   grpc_httpcli_request request;
   grpc_httpcli_context context;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure destroy_closure;
 
   /* The http call is local. If it takes more than one sec, it is for sure not
@@ -128,13 +128,13 @@ static int is_stack_running_on_compute_engine(void) {
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("google_default_credentials");
   grpc_httpcli_get(
-      &exec_ctx, &context, &detector.pollent, resource_quota, &request,
+      exec_ctx, &context, &detector.pollent, resource_quota, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       grpc_closure_create(on_compute_engine_detection_http_response, &detector),
       &detector.response);
-  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 
-  grpc_exec_ctx_flush(&exec_ctx);
+  grpc_exec_ctx_flush(exec_ctx);
 
   /* Block until we get the response. This is not ideal but this should only be
      called once for the lifetime of the process by the default credentials. */
@@ -143,7 +143,7 @@ static int is_stack_running_on_compute_engine(void) {
     grpc_pollset_worker *worker = NULL;
     if (!GRPC_LOG_IF_ERROR(
             "pollset_work",
-            grpc_pollset_work(&exec_ctx,
+            grpc_pollset_work(exec_ctx,
                               grpc_polling_entity_pollset(&detector.pollent),
                               &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                               gpr_inf_future(GPR_CLOCK_MONOTONIC)))) {
@@ -156,10 +156,9 @@ static int is_stack_running_on_compute_engine(void) {
   grpc_httpcli_context_destroy(&context);
   grpc_closure_init(&destroy_closure, destroy_pollset,
                     grpc_polling_entity_pollset(&detector.pollent));
-  grpc_pollset_shutdown(&exec_ctx,
+  grpc_pollset_shutdown(exec_ctx,
                         grpc_polling_entity_pollset(&detector.pollent),
                         &destroy_closure);
-  grpc_exec_ctx_finish(&exec_ctx);
   g_polling_mu = NULL;
 
   gpr_free(grpc_polling_entity_pollset(&detector.pollent));
@@ -170,7 +169,7 @@ static int is_stack_running_on_compute_engine(void) {
 
 /* Takes ownership of creds_path if not NULL. */
 static grpc_error *create_default_creds_from_path(
-    char *creds_path, grpc_call_credentials **creds) {
+    grpc_exec_ctx *exec_ctx, char *creds_path, grpc_call_credentials **creds) {
   grpc_json *json = NULL;
   grpc_auth_json_key key;
   grpc_auth_refresh_token token;
@@ -200,7 +199,7 @@ static grpc_error *create_default_creds_from_path(
   if (grpc_auth_json_key_is_valid(&key)) {
     result =
         grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-            key, grpc_max_auth_token_lifetime());
+            exec_ctx, key, grpc_max_auth_token_lifetime());
     if (result == NULL) {
       error = GRPC_ERROR_CREATE(
           "grpc_service_account_jwt_access_credentials_create_from_auth_json_"
@@ -236,6 +235,7 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
   grpc_call_credentials *call_creds = NULL;
   grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
   grpc_error *err;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
 
@@ -250,20 +250,22 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
 
   /* First, try the environment variable. */
   err = create_default_creds_from_path(
-      gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
+      &exec_ctx, gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
   if (err == GRPC_ERROR_NONE) goto end;
   error = grpc_error_add_child(error, err);
 
   /* Then the well-known file. */
   err = create_default_creds_from_path(
-      grpc_get_well_known_google_credentials_file_path(), &call_creds);
+      &exec_ctx, grpc_get_well_known_google_credentials_file_path(),
+      &call_creds);
   if (err == GRPC_ERROR_NONE) goto end;
   error = grpc_error_add_child(error, err);
 
   /* At last try to see if we're on compute engine (do the detection only once
      since it requires a network test). */
   if (!compute_engine_detection_done) {
-    int need_compute_engine_creds = is_stack_running_on_compute_engine();
+    int need_compute_engine_creds =
+        is_stack_running_on_compute_engine(&exec_ctx);
     compute_engine_detection_done = 1;
     if (need_compute_engine_creds) {
       call_creds = grpc_google_compute_engine_credentials_create(NULL);
@@ -286,8 +288,8 @@ end:
           grpc_composite_channel_credentials_create(ssl_creds, call_creds,
                                                     NULL));
       GPR_ASSERT(default_credentials != NULL);
-      grpc_channel_credentials_unref(ssl_creds);
-      grpc_call_credentials_unref(call_creds);
+      grpc_channel_credentials_unref(&exec_ctx, ssl_creds);
+      grpc_call_credentials_unref(&exec_ctx, call_creds);
       result = default_credentials;
     } else {
       gpr_log(GPR_ERROR, "Could not create google default credentials.");
@@ -299,18 +301,21 @@ end:
   } else {
     GRPC_ERROR_UNREF(error);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return result;
 }
 
 void grpc_flush_cached_google_default_credentials(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_once_init(&g_once, init_default_credentials);
   gpr_mu_lock(&g_state_mu);
   if (default_credentials != NULL) {
-    grpc_channel_credentials_unref(default_credentials);
+    grpc_channel_credentials_unref(&exec_ctx, default_credentials);
     default_credentials = NULL;
   }
   compute_engine_detection_done = 0;
   gpr_mu_unlock(&g_state_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* -- Well known credentials path. -- */
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.c b/src/core/lib/security/credentials/iam/iam_credentials.c
index 370a384d0e..abd69a9670 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.c
+++ b/src/core/lib/security/credentials/iam/iam_credentials.c
@@ -42,9 +42,10 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
-static void iam_destruct(grpc_call_credentials *creds) {
+static void iam_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_call_credentials *creds) {
   grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
-  grpc_credentials_md_store_unref(c->iam_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->iam_md);
 }
 
 static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.c b/src/core/lib/security/credentials/jwt/jwt_credentials.c
index f87ba0ce8d..4ce5675fba 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.c
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.c
@@ -42,9 +42,10 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
-static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
+static void jwt_reset_cache(grpc_exec_ctx *exec_ctx,
+                            grpc_service_account_jwt_access_credentials *c) {
   if (c->cached.jwt_md != NULL) {
-    grpc_credentials_md_store_unref(c->cached.jwt_md);
+    grpc_credentials_md_store_unref(exec_ctx, c->cached.jwt_md);
     c->cached.jwt_md = NULL;
   }
   if (c->cached.service_url != NULL) {
@@ -54,11 +55,12 @@ static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
   c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
 }
 
-static void jwt_destruct(grpc_call_credentials *creds) {
+static void jwt_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_call_credentials *creds) {
   grpc_service_account_jwt_access_credentials *c =
       (grpc_service_account_jwt_access_credentials *)creds;
   grpc_auth_json_key_destruct(&c->key);
-  jwt_reset_cache(c);
+  jwt_reset_cache(exec_ctx, c);
   gpr_mu_destroy(&c->cache_mu);
 }
 
@@ -92,7 +94,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
     char *jwt = NULL;
     /* Generate a new jwt. */
     gpr_mu_lock(&c->cache_mu);
-    jwt_reset_cache(c);
+    jwt_reset_cache(exec_ctx, c);
     jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
                                    c->jwt_lifetime, NULL);
     if (jwt != NULL) {
@@ -114,7 +116,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
   if (jwt_md != NULL) {
     cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
        GRPC_CREDENTIALS_OK, NULL);
-    grpc_credentials_md_store_unref(jwt_md);
+    grpc_credentials_md_store_unref(exec_ctx, jwt_md);
   } else {
     cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
        "Could not generate JWT.");
@@ -126,7 +128,8 @@ static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct,
 
 grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-    grpc_auth_json_key key, gpr_timespec token_lifetime) {
+    grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+    gpr_timespec token_lifetime) {
   grpc_service_account_jwt_access_credentials *c;
   if (!grpc_auth_json_key_is_valid(&key)) {
     gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
@@ -140,7 +143,7 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
   c->key = key;
   c->jwt_lifetime = token_lifetime;
   gpr_mu_init(&c->cache_mu);
-  jwt_reset_cache(c);
+  jwt_reset_cache(exec_ctx, c);
   return &c->base;
 }
 
@@ -156,6 +159,11 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
       5, (json_key, token_lifetime.tv_sec, token_lifetime.tv_nsec,
           (int)token_lifetime.clock_type, reserved));
   GPR_ASSERT(reserved == NULL);
-  return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-      grpc_auth_json_key_create_from_string(json_key), token_lifetime);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call_credentials *creds =
+      grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+          &exec_ctx, grpc_auth_json_key_create_from_string(json_key),
+          token_lifetime);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return creds;
 }
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index d572606179..39b7aeafe8 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -57,6 +57,7 @@ typedef struct {
 // Takes ownership of the key.
 grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-    grpc_auth_json_key key, gpr_timespec token_lifetime);
+    grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+    gpr_timespec token_lifetime);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index d551a7c51a..05c4f4cd77 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -36,11 +36,6 @@
 #include <limits.h>
 #include <string.h>
 
-#include "src/core/lib/http/httpcli.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/security/util/b64.h"
-#include "src/core/lib/tsi/ssl_types.h"
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
@@ -48,6 +43,12 @@
 #include <grpc/support/useful.h>
 #include <openssl/pem.h>
 
+#include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/tsi/ssl_types.h"
+
 /* --- Utils. --- */
 
 const char *grpc_jwt_verifier_status_to_string(
@@ -84,7 +85,8 @@ static const EVP_MD *evp_md_from_alg(const char *alg) {
   }
 }
 
-static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
+static grpc_json *parse_json_part_from_jwt(grpc_exec_ctx *exec_ctx,
+                                           const char *str, size_t len,
                                            grpc_slice *buffer) {
   grpc_json *json;
 
@@ -132,13 +134,14 @@ typedef struct {
   grpc_slice buffer;
 } jose_header;
 
-static void jose_header_destroy(jose_header *h) {
+static void jose_header_destroy(grpc_exec_ctx *exec_ctx, jose_header *h) {
   grpc_slice_unref_internal(exec_ctx, h->buffer);
   gpr_free(h);
 }
 
 /* Takes ownership of json and buffer. */
-static jose_header *jose_header_from_json(grpc_json *json, grpc_slice buffer) {
+static jose_header *jose_header_from_json(grpc_exec_ctx *exec_ctx,
+                                          grpc_json *json, grpc_slice buffer) {
   grpc_json *cur;
   jose_header *h = gpr_malloc(sizeof(jose_header));
   memset(h, 0, sizeof(jose_header));
@@ -173,7 +176,7 @@ static jose_header *jose_header_from_json(grpc_json *json, grpc_slice buffer) {
 
 error:
   grpc_json_destroy(json);
-  jose_header_destroy(h);
+  jose_header_destroy(exec_ctx, h);
   return NULL;
 }
 
@@ -193,7 +196,7 @@ struct grpc_jwt_claims {
   grpc_slice buffer;
 };
 
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) {
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims) {
   grpc_json_destroy(claims->json);
   grpc_slice_unref_internal(exec_ctx, claims->buffer);
   gpr_free(claims);
@@ -240,7 +243,8 @@ gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims) {
 }
 
 /* Takes ownership of json and buffer even in case of failure. */
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) {
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+                                           grpc_json *json, grpc_slice buffer) {
   grpc_json *cur;
   grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims));
   memset(claims, 0, sizeof(grpc_jwt_claims));
@@ -281,7 +285,7 @@ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) {
   return claims;
 
 error:
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(exec_ctx, claims);
   return NULL;
 }
 
@@ -362,12 +366,12 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
   return ctx;
 }
 
-void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
+void verifier_cb_ctx_destroy(grpc_exec_ctx *exec_ctx, verifier_cb_ctx *ctx) {
   if (ctx->audience != NULL) gpr_free(ctx->audience);
-  if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims);
+  if (ctx->claims != NULL) grpc_jwt_claims_destroy(exec_ctx, ctx->claims);
   grpc_slice_unref_internal(exec_ctx, ctx->signature);
   grpc_slice_unref_internal(exec_ctx, ctx->signed_data);
-  jose_header_destroy(ctx->header);
+  jose_header_destroy(exec_ctx, ctx->header);
   for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
     grpc_http_response_destroy(&ctx->responses[i]);
   }
@@ -447,7 +451,7 @@ end:
   return result;
 }
 
-static BIGNUM *bignum_from_base64(const char *b64) {
+static BIGNUM *bignum_from_base64(grpc_exec_ctx *exec_ctx, const char *b64) {
   BIGNUM *result = NULL;
   grpc_slice bin;
 
@@ -463,7 +467,8 @@ static BIGNUM *bignum_from_base64(const char *b64) {
   return result;
 }
 
-static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) {
+static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
+                               const char *kty) {
   const grpc_json *key_prop;
   RSA *rsa = NULL;
   EVP_PKEY *result = NULL;
@@ -480,10 +485,12 @@ static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) {
   }
   for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) {
     if (strcmp(key_prop->key, "n") == 0) {
-      rsa->n = bignum_from_base64(validate_string_field(key_prop, "n"));
+      rsa->n =
+          bignum_from_base64(exec_ctx, validate_string_field(key_prop, "n"));
       if (rsa->n == NULL) goto end;
     } else if (strcmp(key_prop->key, "e") == 0) {
-      rsa->e = bignum_from_base64(validate_string_field(key_prop, "e"));
+      rsa->e =
+          bignum_from_base64(exec_ctx, validate_string_field(key_prop, "e"));
       if (rsa->e == NULL) goto end;
     }
   }
@@ -499,7 +506,8 @@ end:
   return result;
 }
 
-static EVP_PKEY *find_verification_key(const grpc_json *json,
+static EVP_PKEY *find_verification_key(grpc_exec_ctx *exec_ctx,
+                                       const grpc_json *json,
                                        const char *header_alg,
                                        const char *header_kid) {
   const grpc_json *jkey;
@@ -543,7 +551,7 @@ static EVP_PKEY *find_verification_key(const grpc_json *json,
     }
     if (alg != NULL && kid != NULL && kty != NULL &&
         strcmp(kid, header_kid) == 0 && strcmp(alg, header_alg) == 0) {
-      return pkey_from_jwk(jkey, kty);
+      return pkey_from_jwk(exec_ctx, jkey, kty);
     }
   }
   gpr_log(GPR_ERROR,
@@ -597,7 +605,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
     goto end;
   }
   verification_key =
-      find_verification_key(json, ctx->header->alg, ctx->header->kid);
+      find_verification_key(exec_ctx, json, ctx->header->alg, ctx->header->kid);
   if (verification_key == NULL) {
     gpr_log(GPR_ERROR, "Could not find verification key with kid %s.",
             ctx->header->kid);
@@ -622,7 +630,7 @@ end:
   if (json != NULL) grpc_json_destroy(json);
   if (verification_key != NULL) EVP_PKEY_free(verification_key);
   ctx->user_cb(ctx->user_data, status, claims);
-  verifier_cb_ctx_destroy(ctx);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -675,7 +683,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
 error:
   if (json != NULL) grpc_json_destroy(json);
   ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
-  verifier_cb_ctx_destroy(ctx);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v,
@@ -786,7 +794,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
 
 error:
   ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
-  verifier_cb_ctx_destroy(ctx);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
@@ -808,17 +816,19 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL);
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
-  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer);
+  json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+                                  &header_buffer);
   if (json == NULL) goto error;
-  header = jose_header_from_json(json, header_buffer);
+  header = jose_header_from_json(exec_ctx, json, header_buffer);
   if (header == NULL) goto error;
 
   cur = dot + 1;
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
-  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer);
+  json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+                                  &claims_buffer);
   if (json == NULL) goto error;
-  claims = grpc_jwt_claims_from_json(json, claims_buffer);
+  claims = grpc_jwt_claims_from_json(exec_ctx, json, claims_buffer);
   if (claims == NULL) goto error;
 
   signed_jwt_len = (size_t)(dot - jwt);
@@ -832,8 +842,8 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
   return;
 
 error:
-  if (header != NULL) jose_header_destroy(header);
-  if (claims != NULL) grpc_jwt_claims_destroy(claims);
+  if (header != NULL) jose_header_destroy(exec_ctx, header);
+  if (claims != NULL) grpc_jwt_claims_destroy(exec_ctx, claims);
   cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
 }
 
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index f09f9d5d47..c084575bcf 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -66,7 +66,7 @@ const char *grpc_jwt_verifier_status_to_string(grpc_jwt_verifier_status status);
 
 typedef struct grpc_jwt_claims grpc_jwt_claims;
 
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims);
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims);
 
 /* Returns the whole JSON tree of the claims. */
 const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims);
@@ -129,7 +129,8 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
 
 /* --- TESTING ONLY exposed functions. --- */
 
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer);
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+                                           grpc_json *json, grpc_slice buffer);
 grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
                                                const char *audience);
 
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index 09140bef57..b7bdc53a35 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -118,18 +118,19 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
 // Oauth2 Token Fetcher credentials.
 //
 
-static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
+static void oauth2_token_fetcher_destruct(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_credentials *creds) {
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
-  grpc_credentials_md_store_unref(c->access_token_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
   gpr_mu_destroy(&c->mu);
   grpc_httpcli_context_destroy(&c->httpcli_context);
 }
 
 grpc_credentials_status
 grpc_oauth2_token_fetcher_credentials_parse_server_response(
-    const grpc_http_response *response, grpc_credentials_md_store **token_md,
-    gpr_timespec *token_lifetime) {
+    grpc_exec_ctx *exec_ctx, const grpc_http_response *response,
+    grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime) {
   char *null_terminated_body = NULL;
   char *new_access_token = NULL;
   grpc_credentials_status status = GRPC_CREDENTIALS_OK;
@@ -198,7 +199,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
     token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
     token_lifetime->tv_nsec = 0;
     token_lifetime->clock_type = GPR_TIMESPAN;
-    if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
+    if (*token_md != NULL) grpc_credentials_md_store_unref(exec_ctx, *token_md);
     *token_md = grpc_credentials_md_store_create(1);
     grpc_credentials_md_store_add_cstrings(
         *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
@@ -207,7 +208,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
 
 end:
   if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
-    grpc_credentials_md_store_unref(*token_md);
+    grpc_credentials_md_store_unref(exec_ctx, *token_md);
     *token_md = NULL;
   }
   if (null_terminated_body != NULL) gpr_free(null_terminated_body);
@@ -230,7 +231,7 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
 
   gpr_mu_lock(&c->mu);
   status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
-      &r->response, &c->access_token_md, &token_lifetime);
+      exec_ctx, &r->response, &c->access_token_md, &token_lifetime);
   if (status == GRPC_CREDENTIALS_OK) {
     c->token_expiration =
         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
@@ -242,7 +243,7 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
           "Error occured when fetching oauth2 token.");
   }
   gpr_mu_unlock(&c->mu);
-  grpc_credentials_metadata_request_destroy(r);
+  grpc_credentials_metadata_request_destroy(exec_ctx, r);
 }
 
 static void oauth2_token_fetcher_get_request_metadata(
@@ -268,7 +269,7 @@ static void oauth2_token_fetcher_get_request_metadata(
   if (cached_access_token_md != NULL) {
     cb(exec_ctx, user_data, cached_access_token_md->entries,
        cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
-    grpc_credentials_md_store_unref(cached_access_token_md);
+    grpc_credentials_md_store_unref(exec_ctx, cached_access_token_md);
   } else {
     c->fetch_func(
         exec_ctx,
@@ -334,11 +335,12 @@ grpc_call_credentials *grpc_google_compute_engine_credentials_create(
 // Google Refresh Token credentials.
 //
 
-static void refresh_token_destruct(grpc_call_credentials *creds) {
+static void refresh_token_destruct(grpc_exec_ctx *exec_ctx,
+                                   grpc_call_credentials *creds) {
   grpc_google_refresh_token_credentials *c =
       (grpc_google_refresh_token_credentials *)creds;
   grpc_auth_refresh_token_destruct(&c->refresh_token);
-  oauth2_token_fetcher_destruct(&c->base.base);
+  oauth2_token_fetcher_destruct(exec_ctx, &c->base.base);
 }
 
 static grpc_call_credentials_vtable refresh_token_vtable = {
@@ -407,9 +409,10 @@ grpc_call_credentials *grpc_google_refresh_token_credentials_create(
 // Oauth2 Access Token credentials.
 //
 
-static void access_token_destruct(grpc_call_credentials *creds) {
+static void access_token_destruct(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_credentials *creds) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
-  grpc_credentials_md_store_unref(c->access_token_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
 }
 
 static void access_token_get_request_metadata(
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index 7f6f205c22..2d7c02ccf5 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -103,7 +103,7 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
 // Exposed for testing only.
 grpc_credentials_status
 grpc_oauth2_token_fetcher_credentials_parse_server_response(
-    const struct grpc_http_response *response,
+    grpc_exec_ctx *exec_ctx, const struct grpc_http_response *response,
     grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.c
index 16cbb17f46..29f28024f6 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.c
@@ -35,20 +35,22 @@
 
 #include <string.h>
 
-#include "src/core/lib/surface/api_trace.h"
-
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/surface/api_trace.h"
+
 typedef struct {
   void *user_data;
   grpc_credentials_metadata_cb cb;
 } grpc_metadata_plugin_request;
 
-static void plugin_destruct(grpc_call_credentials *creds) {
+static void plugin_destruct(grpc_exec_ctx *exec_ctx,
+                            grpc_call_credentials *creds) {
   grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
   if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
     c->plugin.destroy(c->plugin.state);
@@ -100,8 +102,8 @@ static void plugin_md_request_metadata_ready(void *request,
       r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK,
             NULL);
       for (i = 0; i < num_md; i++) {
-        grpc_slice_unref_internal(exec_ctx, md_array[i].key);
-        grpc_slice_unref_internal(exec_ctx, md_array[i].value);
+        grpc_slice_unref_internal(&exec_ctx, md_array[i].key);
+        grpc_slice_unref_internal(&exec_ctx, md_array[i].value);
       }
       gpr_free(md_array);
     }
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index 0dc1fccec4..4eebb7d613 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -57,7 +57,8 @@ static void ssl_copy_key_material(const char *input, unsigned char **output,
 // SSL Channel Credentials.
 //
 
-static void ssl_destruct(grpc_channel_credentials *creds) {
+static void ssl_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_channel_credentials *creds) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
   if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
@@ -65,9 +66,10 @@ static void ssl_destruct(grpc_channel_credentials *creds) {
 }
 
 static grpc_security_status ssl_create_security_connector(
-    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   grpc_security_status status = GRPC_SECURITY_OK;
   size_t i = 0;
@@ -83,7 +85,7 @@ static grpc_security_status ssl_create_security_connector(
     }
   }
   status = grpc_ssl_channel_security_connector_create(
-      call_creds, &c->config, target, overridden_target_name, sc);
+      exec_ctx, call_creds, &c->config, target, overridden_target_name, sc);
   if (status != GRPC_SECURITY_OK) {
     return status;
   }
@@ -138,7 +140,8 @@ grpc_channel_credentials *grpc_ssl_credentials_create(
 // SSL Server Credentials.
 //
 
-static void ssl_server_destruct(grpc_server_credentials *creds) {
+static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
+                                grpc_server_credentials *creds) {
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
   size_t i;
   for (i = 0; i < c->config.num_key_cert_pairs; i++) {
@@ -161,9 +164,10 @@ static void ssl_server_destruct(grpc_server_credentials *creds) {
 }
 
 static grpc_security_status ssl_server_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc) {
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
-  return grpc_ssl_server_security_connector_create(&c->config, sc);
+  return grpc_ssl_server_security_connector_create(exec_ctx, &c->config, sc);
 }
 
 static grpc_server_credentials_vtable ssl_server_vtable = {
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 22ca99eff8..285f96aa9e 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -93,7 +94,8 @@ static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   call_data *calld = elem->call_data;
   gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
   grpc_slice error_slice = grpc_slice_from_copied_string(error_msg);
-  grpc_transport_stream_op_add_close(&calld->op, status, &error_slice);
+  grpc_transport_stream_op_add_close(exec_ctx, &calld->op, status,
+                                     &error_slice);
   grpc_call_next_op(exec_ctx, elem, &calld->op);
 }
 
@@ -121,7 +123,8 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
   for (i = 0; i < num_md; i++) {
     grpc_metadata_batch_add_tail(
         mdb, &calld->md_links[i],
-        grpc_mdelem_from_slices(grpc_slice_ref_internal(md_elems[i].key),
+        grpc_mdelem_from_slices(exec_ctx,
+                                grpc_slice_ref_internal(md_elems[i].key),
                                 grpc_slice_ref_internal(md_elems[i].value)));
   }
   grpc_call_next_op(exec_ctx, elem, op);
@@ -248,10 +251,10 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
       /* Pointer comparison is OK for md_elems created from the same context.
        */
       if (md->key == GRPC_MDSTR_AUTHORITY) {
-        if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
+        if (calld->host != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->host);
         calld->host = GRPC_MDSTR_REF(md->value);
       } else if (md->key == GRPC_MDSTR_PATH) {
-        if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
+        if (calld->method != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->method);
         calld->method = GRPC_MDSTR_REF(md->value);
       }
     }
@@ -292,12 +295,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_call_credentials_unref(calld->creds);
+  grpc_call_credentials_unref(exec_ctx, calld->creds);
   if (calld->host != NULL) {
-    GRPC_MDSTR_UNREF(calld->host);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->host);
   }
   if (calld->method != NULL) {
-    GRPC_MDSTR_UNREF(calld->method);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->method);
   }
   reset_auth_metadata_context(&calld->auth_md_context);
 }
@@ -336,7 +339,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   channel_data *chand = elem->channel_data;
   grpc_channel_security_connector *sc = chand->security_connector;
   if (sc != NULL) {
-    GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter");
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "client_auth_filter");
   }
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
 }
diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c
index 077c1f0aa7..1f42153378 100644
--- a/src/core/lib/security/transport/handshake.c
+++ b/src/core/lib/security/transport/handshake.c
@@ -43,6 +43,7 @@
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
 
@@ -100,7 +101,8 @@ static void security_connector_remove_handshake(grpc_security_handshake *h) {
   gpr_mu_unlock(&sc->mu);
 }
 
-static void unref_handshake(grpc_security_handshake *h) {
+static void unref_handshake(grpc_exec_ctx *exec_ctx,
+                            grpc_security_handshake *h) {
   if (gpr_unref(&h->refs)) {
     if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
     if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
@@ -108,7 +110,7 @@ static void unref_handshake(grpc_security_handshake *h) {
     grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing);
     grpc_slice_buffer_destroy_internal(exec_ctx, &h->incoming);
     GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
-    GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, h->connector, "handshake");
     gpr_free(h);
   }
 }
@@ -136,7 +138,7 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx,
     }
     h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL);
   }
-  unref_handshake(h);
+  unref_handshake(exec_ctx, h);
   GRPC_ERROR_UNREF(error);
 }
 
@@ -280,7 +282,8 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
     grpc_slice_buffer_add(
         &h->left_overs,
         grpc_slice_split_tail(&h->incoming.slices[i], consumed_slice_size));
-    grpc_slice_unref_internal(exec_ctx, 
+    grpc_slice_unref_internal(
+        exec_ctx,
         h->incoming.slices[i]); /* split_tail above increments refcount. */
   }
   grpc_slice_buffer_addn(
@@ -319,7 +322,7 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   if (error == GRPC_ERROR_NONE) {
     grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint);
   }
-  unref_handshake(h);
+  unref_handshake(exec_ctx, h);
 }
 
 void grpc_do_security_handshake(
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 78037f8089..594aa6161d 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -40,6 +40,7 @@
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/tsi/transport_security_interface.h"
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index f7e3264bda..6b2569f646 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -195,7 +195,8 @@ grpc_security_connector *grpc_security_connector_ref(
 }
 
 #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
-void grpc_security_connector_unref(grpc_security_connector *sc,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc,
                                    const char *file, int line,
                                    const char *reason) {
   if (sc == NULL) return;
@@ -203,14 +204,15 @@ void grpc_security_connector_unref(grpc_security_connector *sc,
           "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
           (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
 #else
-void grpc_security_connector_unref(grpc_security_connector *sc) {
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc) {
   if (sc == NULL) return;
 #endif
-  if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
+  if (gpr_unref(&sc->refcount)) sc->vtable->destroy(exec_ctx, sc);
 }
 
-static void connector_pointer_arg_destroy(void *p) {
-  GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg");
+static void connector_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, "connector_pointer_arg");
 }
 
 static void *connector_pointer_arg_copy(void *p) {
@@ -256,13 +258,15 @@ grpc_security_connector *grpc_find_security_connector_in_args(
 
 /* -- Fake implementation. -- */
 
-static void fake_channel_destroy(grpc_security_connector *sc) {
+static void fake_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_security_connector *sc) {
   grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
-  grpc_call_credentials_unref(c->request_metadata_creds);
+  grpc_call_credentials_unref(exec_ctx, c->request_metadata_creds);
   gpr_free(sc);
 }
 
-static void fake_server_destroy(grpc_security_connector *sc) {
+static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
   gpr_mu_destroy(&c->mu);
   gpr_free(sc);
@@ -381,10 +385,11 @@ typedef struct {
   tsi_ssl_handshaker_factory *handshaker_factory;
 } grpc_ssl_server_security_connector;
 
-static void ssl_channel_destroy(grpc_security_connector *sc) {
+static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_ssl_channel_security_connector *c =
       (grpc_ssl_channel_security_connector *)sc;
-  grpc_call_credentials_unref(c->base.request_metadata_creds);
+  grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
@@ -393,7 +398,8 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
   gpr_free(sc);
 }
 
-static void ssl_server_destroy(grpc_security_connector *sc) {
+static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_security_connector *sc) {
   grpc_ssl_server_security_connector *c =
       (grpc_ssl_server_security_connector *)sc;
 
@@ -719,7 +725,7 @@ size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
 }
 
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_call_credentials *request_metadata_creds,
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
@@ -780,7 +786,7 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    ssl_channel_destroy(&c->base.base);
+    ssl_channel_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     goto error;
   }
@@ -796,7 +802,8 @@ error:
 }
 
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+    grpc_server_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -836,7 +843,7 @@ grpc_security_status grpc_ssl_server_security_connector_create(
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    ssl_server_destroy(&c->base.base);
+    ssl_server_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     goto error;
   }
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index dc02692b01..6e89bfd779 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -68,7 +68,7 @@ typedef void (*grpc_security_handshake_done_cb)(
     grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context);
 
 typedef struct {
-  void (*destroy)(grpc_security_connector *sc);
+  void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc);
   void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
                      tsi_peer peer, grpc_security_peer_check_cb cb,
                      void *user_data);
@@ -89,20 +89,23 @@ struct grpc_security_connector {
 #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
 #define GRPC_SECURITY_CONNECTOR_REF(p, r) \
   grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
-  grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+  grpc_security_connector_unref((exec_ctx), (p), __FILE__, __LINE__, (r))
 grpc_security_connector *grpc_security_connector_ref(
     grpc_security_connector *policy, const char *file, int line,
     const char *reason);
-void grpc_security_connector_unref(grpc_security_connector *policy,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *policy,
                                    const char *file, int line,
                                    const char *reason);
 #else
 #define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+  grpc_security_connector_unref((exec_ctx), (p))
 grpc_security_connector *grpc_security_connector_ref(
     grpc_security_connector *policy);
-void grpc_security_connector_unref(grpc_security_connector *policy);
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *policy);
 #endif
 
 /* Check the peer. Callee takes ownership of the peer object.
@@ -225,7 +228,7 @@ typedef struct {
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_call_credentials *request_metadata_creds,
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc);
 
@@ -254,7 +257,8 @@ typedef struct {
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
+    grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+    grpc_server_security_connector **sc);
 
 /* Util. */
 const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index dd465be6f5..d5fb48b38f 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -129,8 +129,8 @@ static void on_md_processing_done(
   if (status == GRPC_STATUS_OK) {
     calld->consumed_md = consumed_md;
     calld->num_consumed_md = num_consumed_md;
-    grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md,
-                               elem);
+    grpc_metadata_batch_filter(&exec_ctx, calld->recv_initial_metadata,
+                               remove_consumed_md, elem);
     grpc_metadata_array_destroy(&calld->md);
     grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE, NULL);
   } else {
@@ -149,7 +149,7 @@ static void on_md_processing_done(
     }
     calld->transport_op->send_trailing_metadata = NULL;
     close_op->on_complete = grpc_closure_create(destroy_op, close_op);
-    grpc_transport_stream_op_add_close(close_op, status, &message);
+    grpc_transport_stream_op_add_close(&exec_ctx, close_op, status, &message);
     grpc_call_next_op(&exec_ctx, elem, close_op);
     grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv,
                         grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
@@ -264,7 +264,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   /* grab pointers to our data from the channel element */
   channel_data *chand = elem->channel_data;
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
-  grpc_server_credentials_unref(chand->creds);
+  grpc_server_credentials_unref(exec_ctx, chand->creds);
 }
 
 const grpc_channel_filter grpc_server_auth_filter = {
-- 
GitLab


From eaf796400169786c33a438c56c41a46d8ed45b02 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 1 Nov 2016 11:05:02 -0700
Subject: [PATCH 026/344] Add test scripts for electron

---
 package.json                               |  2 +
 src/node/test/surface_test.js              |  2 +
 templates/package.json.template            |  2 +
 tools/run_tests/build_node_electron.sh     | 45 ++++++++++++++++++++++
 tools/run_tests/pre_build_node_electron.sh | 37 ++++++++++++++++++
 tools/run_tests/run_node_electron.sh       | 44 +++++++++++++++++++++
 tools/run_tests/run_tests.py               | 34 +++++++++++++---
 7 files changed, 160 insertions(+), 6 deletions(-)
 create mode 100755 tools/run_tests/build_node_electron.sh
 create mode 100755 tools/run_tests/pre_build_node_electron.sh
 create mode 100755 tools/run_tests/run_node_electron.sh

diff --git a/package.json b/package.json
index 9afba31816..a6081ba485 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
   "scripts": {
     "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/interop src/node/index.js --exclude-path=src/node/.jshintignore",
     "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
+    "electron-build": "./node_modules/.bin/node-pre-gyp configure build --runtime=electron --disturl=https://atom.io/download/atom-shell",
     "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
     "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
     "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
@@ -34,6 +35,7 @@
   },
   "devDependencies": {
     "async": "^1.5.0",
+    "electron-mocha": "^3.1.1",
     "google-auth-library": "^0.9.2",
     "google-protobuf": "^3.0.0",
     "istanbul": "^0.3.21",
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index d8b36dc55c..17c62d5635 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -183,6 +183,7 @@ describe('Server.prototype.addProtoService', function() {
         assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED);
         done();
       });
+      call.on('error', function(status) { /* Do nothing */ });
     });
     it('should respond to a bidi call with UNIMPLEMENTED', function(done) {
       var call = client.divMany();
@@ -193,6 +194,7 @@ describe('Server.prototype.addProtoService', function() {
         assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED);
         done();
       });
+      call.on('error', function(status) { /* Do nothing */ });
       call.end();
     });
   });
diff --git a/templates/package.json.template b/templates/package.json.template
index e9596d4d4c..b8ce92eb7a 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -23,6 +23,7 @@
     "scripts": {
       "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/interop src/node/index.js --exclude-path=src/node/.jshintignore",
       "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
+      "electron-build": "./node_modules/.bin/node-pre-gyp configure build --runtime=electron --disturl=https://atom.io/download/atom-shell",
       "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
       "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
       "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
@@ -36,6 +37,7 @@
     },
     "devDependencies": {
       "async": "^1.5.0",
+      "electron-mocha": "^3.1.1",
       "google-auth-library": "^0.9.2",
       "google-protobuf": "^3.0.0",
       "istanbul": "^0.3.21",
diff --git a/tools/run_tests/build_node_electron.sh b/tools/run_tests/build_node_electron.sh
new file mode 100755
index 0000000000..4e7c3e4789
--- /dev/null
+++ b/tools/run_tests/build_node_electron.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Copyright 2016, 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.
+
+ELECTRON_VERSION=$1
+source ~/.nvm/nvm.sh
+
+nvm use 6
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../..
+
+export npm_config_target=$ELECTRON_VERSION
+export npm_config_disturl=https://atom.io/download/atom-shell
+export npm_config_runtime=electron
+export npm_config_build_from_source=true
+HOME=~/.electron-gyp npm install --unsafe-perm
diff --git a/tools/run_tests/pre_build_node_electron.sh b/tools/run_tests/pre_build_node_electron.sh
new file mode 100755
index 0000000000..d8d9df4ddb
--- /dev/null
+++ b/tools/run_tests/pre_build_node_electron.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Copyright 2016, 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.
+
+ELECTRON_VERSION=$1
+
+nvm install 6
+set -ex
+
+npm install electron@$ELECTRON_VERSION
diff --git a/tools/run_tests/run_node_electron.sh b/tools/run_tests/run_node_electron.sh
new file mode 100755
index 0000000000..7f8a824df2
--- /dev/null
+++ b/tools/run_tests/run_node_electron.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# 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.
+
+source ~/.nvm/nvm.sh
+
+nvm use 6
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../..
+
+test_directory='src/node/test'
+timeout=8000
+
+JUNIT_REPORT_PATH=src/node/report.xml JUNIT_REPORT_STACK=1 \
+  ./node_modules/.bin/electron-mocha --timeout $timeout \
+  --reporter mocha-jenkins-reporter $test_directory
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index db261d98c2..70da0cc0e3 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -362,19 +362,31 @@ class NodeLanguage(object):
   def configure(self, config, args):
     self.config = config
     self.args = args
+    # Note: electron ABI only depends on major and minor version, so that's all
+    # we should specify in the compiler argument
     _check_compiler(self.args.compiler, ['default', 'node0.12',
-                                         'node4', 'node5', 'node6'])
+                                         'node4', 'node5', 'node6',
+                                         'electron1.3'])
     if self.args.compiler == 'default':
       self.node_version = '4'
     else:
-      # Take off the word "node"
-      self.node_version = self.args.compiler[4:]
+      if self.args.compiler.startswith('electron'):
+        self.runtime = 'electron'
+        self.node_version = self.args.compiler[8:]
+      else:
+        self.runtime = 'node'
+        # Take off the word "node"
+        self.node_version = self.args.compiler[4:]
 
   def test_specs(self):
     if self.platform == 'windows':
       return [self.config.job_spec(['tools\\run_tests\\run_node.bat'], None)]
     else:
-      return [self.config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
+      run_script = 'run_node'
+      if self.runtime == 'electron':
+        run_script += '_electron'
+      return [self.config.job_spec(['tools/run_tests/{}.sh'.format(run_script),
+                                    self.node_version],
                                    None,
                                    environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
@@ -382,7 +394,10 @@ class NodeLanguage(object):
     if self.platform == 'windows':
       return [['tools\\run_tests\\pre_build_node.bat']]
     else:
-      return [['tools/run_tests/pre_build_node.sh', self.node_version]]
+      build_script = 'pre_build_node'
+      if self.runtime == 'electron':
+        build_script += '_electron'
+      return [['tools/run_tests/{}.sh'.format(build_script), self.node_version]]
 
   def make_targets(self):
     return []
@@ -394,7 +409,12 @@ class NodeLanguage(object):
     if self.platform == 'windows':
       return [['tools\\run_tests\\build_node.bat']]
     else:
-      return [['tools/run_tests/build_node.sh', self.node_version]]
+      build_script = 'build_node'
+      if self.runtime == 'electron':
+        build_script += '_electron'
+        # building for electron requires a patch version
+        self.node_version += '.0'
+      return [['tools/run_tests/{}.sh'.format(build_script), self.node_version]]
 
   def post_tests_steps(self):
     return []
@@ -1016,6 +1036,8 @@ argp.add_argument('--compiler',
                            'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
                            'vs2010', 'vs2013', 'vs2015',
                            'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3',
+                           'node0.12', 'node4', 'node5', 'node6',
+                           'electron1.3',
                            'coreclr'],
                   default='default',
                   help='Selects compiler to use. Allowed values depend on the platform and language.')
-- 
GitLab


From 013d203d5d53a1c8b6119c2c6bc535863e7b22e6 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 1 Nov 2016 13:05:24 -0700
Subject: [PATCH 027/344] Refactor uv/non-uv code in Node extension

---
 binding.gyp                                   |  4 +-
 build.yaml                                    |  5 +-
 src/node/ext/completion_queue.h               |  1 +
 ...rker.cc => completion_queue_threadpool.cc} | 63 ++++++++++++++++++-
 ...letion_queue.cc => completion_queue_uv.cc} | 17 ++---
 5 files changed, 71 insertions(+), 19 deletions(-)
 rename src/node/ext/{completion_queue_async_worker.cc => completion_queue_threadpool.cc} (72%)
 rename src/node/ext/{completion_queue.cc => completion_queue_uv.cc} (93%)

diff --git a/binding.gyp b/binding.gyp
index 7dd32546d9..5455becae1 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -859,8 +859,8 @@
         "src/node/ext/call_credentials.cc",
         "src/node/ext/channel.cc",
         "src/node/ext/channel_credentials.cc",
-        "src/node/ext/completion_queue.cc",
-        "src/node/ext/completion_queue_async_worker.cc",
+        "src/node/ext/completion_queue_threadpool.cc",
+        "src/node/ext/completion_queue_uv.cc",
         "src/node/ext/node_grpc.cc",
         "src/node/ext/server.cc",
         "src/node/ext/server_credentials.cc",
diff --git a/build.yaml b/build.yaml
index f86d896f6e..d552a290b2 100644
--- a/build.yaml
+++ b/build.yaml
@@ -3710,7 +3710,6 @@ node_modules:
   - src/node/ext/channel.h
   - src/node/ext/channel_credentials.h
   - src/node/ext/completion_queue.h
-  - src/node/ext/completion_queue_async_worker.h
   - src/node/ext/server.h
   - src/node/ext/server_credentials.h
   - src/node/ext/timeval.h
@@ -3729,8 +3728,8 @@ node_modules:
   - src/node/ext/call_credentials.cc
   - src/node/ext/channel.cc
   - src/node/ext/channel_credentials.cc
-  - src/node/ext/completion_queue.cc
-  - src/node/ext/completion_queue_async_worker.cc
+  - src/node/ext/completion_queue_threadpool.cc
+  - src/node/ext/completion_queue_uv.cc
   - src/node/ext/node_grpc.cc
   - src/node/ext/server.cc
   - src/node/ext/server_credentials.cc
diff --git a/src/node/ext/completion_queue.h b/src/node/ext/completion_queue.h
index bf280f768b..9b01028ef1 100644
--- a/src/node/ext/completion_queue.h
+++ b/src/node/ext/completion_queue.h
@@ -32,6 +32,7 @@
  */
 
 #include <v8.h>
+#include <grpc/grpc.h>
 
 namespace grpc {
 namespace node {
diff --git a/src/node/ext/completion_queue_async_worker.cc b/src/node/ext/completion_queue_threadpool.cc
similarity index 72%
rename from src/node/ext/completion_queue_async_worker.cc
rename to src/node/ext/completion_queue_threadpool.cc
index f5e03b277b..6302e7a103 100644
--- a/src/node/ext/completion_queue_async_worker.cc
+++ b/src/node/ext/completion_queue_threadpool.cc
@@ -31,18 +31,63 @@
  *
  */
 
+/* I don't like using #ifndef, but I don't see a better way to do this */
+#ifndef GRPC_UV
+
 #include <node.h>
 #include <nan.h>
 
 #include "grpc/grpc.h"
 #include "grpc/support/log.h"
 #include "grpc/support/time.h"
-#include "completion_queue_async_worker.h"
+#include "completion_queue.h"
 #include "call.h"
 
 namespace grpc {
 namespace node {
 
+namespace {
+
+/* A worker that asynchronously calls completion_queue_next, and queues onto the
+   node event loop a call to the function stored in the event's tag. */
+class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
+ public:
+  CompletionQueueAsyncWorker();
+
+  ~CompletionQueueAsyncWorker();
+  /* Calls completion_queue_next with the provided deadline, and stores the
+     event if there was one or sets an error message if there was not */
+  void Execute();
+
+  /* Returns the completion queue attached to this class */
+  static grpc_completion_queue *GetQueue();
+
+  /* Convenience function to create a worker with the given arguments and queue
+     it to run asynchronously */
+  static void Next();
+
+  /* Initialize the CompletionQueueAsyncWorker class */
+  static void Init(v8::Local<v8::Object> exports);
+
+ protected:
+  /* Called when Execute has succeeded (completed without setting an error
+     message). Calls the saved callback with the event that came from
+     completion_queue_next */
+  void HandleOKCallback();
+
+  void HandleErrorCallback();
+
+ private:
+  grpc_event result;
+
+  static grpc_completion_queue *queue;
+
+  // Number of grpc_completion_queue_next calls in the thread pool
+  static int current_threads;
+  // Number of grpc_completion_queue_next calls waiting to enter the thread pool
+  static int waiting_next_calls;
+};
+
 const int max_queue_threads = 2;
 
 using v8::Function;
@@ -137,5 +182,21 @@ void CompletionQueueAsyncWorker::HandleErrorCallback() {
   DestroyTag(result.tag);
 }
 
+}  // namespace
+
+grpc_completion_queue *GetCompletionQueue() {
+  return CompletionQueueAsyncWorker::GetQueue();
+}
+
+void CompletionQueueNext() {
+  CompletionQueueAsyncWorker::Next();
+}
+
+void CompletionQueueInit(Local<Object> exports) {
+  CompletionQueueAsyncWorker::Init(exports);
+}
+
 }  // namespace node
 }  // namespace grpc
+
+#endif  /* GRPC_UV */
diff --git a/src/node/ext/completion_queue.cc b/src/node/ext/completion_queue_uv.cc
similarity index 93%
rename from src/node/ext/completion_queue.cc
rename to src/node/ext/completion_queue_uv.cc
index fcfa77b39c..615973a6c9 100644
--- a/src/node/ext/completion_queue.cc
+++ b/src/node/ext/completion_queue_uv.cc
@@ -31,6 +31,8 @@
  *
  */
 
+#ifdef GRPC_UV
+
 #include <uv.h>
 #include <node.h>
 #include <v8.h>
@@ -38,7 +40,6 @@
 
 #include "call.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 
 namespace grpc {
 namespace node {
@@ -81,34 +82,24 @@ void drain_completion_queue(uv_prepare_t *handle) {
 }
 
 grpc_completion_queue *GetCompletionQueue() {
-#ifdef GRPC_UV
   return queue;
-#else
-  return CompletionQueueAsyncWorker::GetQueue();
-#endif
 }
 
 void CompletionQueueNext() {
-#ifdef GRPC_UV
   if (pending_batches == 0) {
     GPR_ASSERT(!uv_is_active((uv_handle_t *)&prepare));
     uv_prepare_start(&prepare, drain_completion_queue);
   }
   pending_batches++;
-#else
-  CompletionQueueAsyncWorker::Next();
-#endif
 }
 
 void CompletionQueueInit(Local<Object> exports) {
-#ifdef GRPC_UV
   queue = grpc_completion_queue_create(NULL);
   uv_prepare_init(uv_default_loop(), &prepare);
   pending_batches = 0;
-#else
-  CompletionQueueAsyncWorker::Init(exports);
-#endif
 }
 
 }  // namespace node
 }  // namespace grpc
+
+#endif /* GRPC_UV */
-- 
GitLab


From 10cd3566621c17b4e63526b53b3052cc9a555c48 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 9 Nov 2016 15:20:59 -0800
Subject: [PATCH 028/344] Finish moving to new APIs

---
 src/core/ext/census/grpc_plugin.c             |   3 +-
 src/core/lib/support/string.c                 |   3 +
 test/core/bad_client/tests/large_metadata.c   |   2 +-
 test/core/channel/channel_args_test.c         |  21 ++-
 test/core/channel/channel_stack_test.c        |   2 +-
 .../dns_resolver_connectivity_test.c          |   6 +-
 .../resolvers/dns_resolver_test.c             |   4 +-
 .../resolvers/sockaddr_resolver_test.c        |   6 +-
 .../set_initial_connect_string_test.c         |   6 +-
 test/core/compression/algorithm_test.c        |  10 +-
 test/core/compression/message_compress_test.c |  93 ++++++++-----
 test/core/end2end/bad_server_response_test.c  |   5 +-
 test/core/end2end/connection_refused_test.c   |  14 +-
 test/core/end2end/dualstack_socket_test.c     |   2 +-
 test/core/end2end/fixtures/h2_census.c        |  12 +-
 test/core/end2end/fixtures/h2_compress.c      |  14 +-
 .../core/end2end/fixtures/h2_load_reporting.c |   6 +-
 test/core/end2end/fixtures/h2_oauth2.c        |   6 +-
 test/core/end2end/fixtures/h2_ssl.c           |   6 +-
 test/core/end2end/fixtures/h2_ssl_cert.c      |   6 +-
 test/core/end2end/fixtures/h2_ssl_proxy.c     |  12 +-
 test/core/end2end/fuzzers/api_fuzzer.c        |  18 ++-
 test/core/iomgr/tcp_posix_test.c              |  10 +-
 test/core/security/b64_test.c                 |  44 +++---
 test/core/security/credentials_test.c         | 129 ++++++++++++------
 test/core/security/json_token_test.c          |  13 +-
 test/core/security/jwt_verifier_test.c        |  32 +++--
 test/core/security/secure_endpoint_test.c     |   5 +-
 test/core/slice/slice_buffer_test.c           |   2 +-
 test/core/surface/byte_buffer_reader_test.c   |  14 +-
 .../core/surface/secure_channel_create_test.c |   4 +-
 .../surface/sequential_connectivity_test.c    |   7 +-
 test/core/transport/chttp2/bin_decoder_test.c | 103 ++++++++------
 .../transport/chttp2/hpack_encoder_test.c     |  77 ++++++-----
 .../chttp2/hpack_parser_fuzzer_test.c         |   8 +-
 .../core/transport/chttp2/hpack_parser_test.c |  33 +++--
 test/core/transport/chttp2/hpack_table_test.c |  54 ++++----
 test/core/transport/metadata_test.c           | 110 +++++++++------
 38 files changed, 574 insertions(+), 328 deletions(-)

diff --git a/src/core/ext/census/grpc_plugin.c b/src/core/ext/census/grpc_plugin.c
index e43ceafd0c..c9fe453af8 100644
--- a/src/core/ext/census/grpc_plugin.c
+++ b/src/core/ext/census/grpc_plugin.c
@@ -51,7 +51,8 @@ static bool is_census_enabled(const grpc_channel_args *a) {
   return census_enabled();
 }
 
-static bool maybe_add_census_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_stack_builder *builder,
                                     void *arg) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index dc243bf0bf..cafeb4364d 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -266,3 +266,6 @@ int gpr_stricmp(const char *a, const char *b) {
   } while (ca == cb && ca && cb);
   return ca - cb;
 }
+
+void gpr_string_split(const char *input, const char *sep, char ***strs,
+                      size_t *nstrs) {}
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index 809bbe4094..9c804e78c1 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -213,7 +213,7 @@ static void client_validator(grpc_slice_buffer *incoming) {
   *p++ = 11;
   // Compare actual and expected.
   GPR_ASSERT(grpc_slice_cmp(last_frame, expected) == 0);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &last_frame_buffer);
+  grpc_slice_buffer_destroy(&last_frame_buffer);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index 8ef1bff22e..261d0c5916 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -37,10 +37,12 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
-
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/util/test_config.h"
 
 static void test_create(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   grpc_arg arg_int;
   grpc_arg arg_string;
   grpc_arg to_add[2];
@@ -68,10 +70,12 @@ static void test_create(void) {
   GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) ==
              0);
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_set_compression_algorithm(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *ch_args;
 
   ch_args =
@@ -81,10 +85,12 @@ static void test_set_compression_algorithm(void) {
                     GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);
   GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER);
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_compression_algorithm_states(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate;
   unsigned states_bitset;
   size_t i;
@@ -100,10 +106,10 @@ static void test_compression_algorithm_states(void) {
 
   /* disable gzip and deflate */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args, GRPC_COMPRESS_GZIP, 0);
+      &exec_ctx, &ch_args, GRPC_COMPRESS_GZIP, 0);
   GPR_ASSERT(ch_args == ch_args_wo_gzip);
   ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
+      &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -118,7 +124,7 @@ static void test_compression_algorithm_states(void) {
 
   /* re-enabled gzip only */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
+      &exec_ctx, &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -131,7 +137,8 @@ static void test_compression_algorithm_states(void) {
     }
   }
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 1e57df9026..3ecc8c0364 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -155,8 +155,8 @@ static void test_create_channel_stack(void) {
 
   GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done");
 
+  GRPC_MDSTR_UNREF(&exec_ctx, path);
   grpc_exec_ctx_finish(&exec_ctx);
-  GRPC_MDSTR_UNREF(path);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index ffa167a0e7..5ba8ef85e7 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -64,6 +64,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
 }
 
 static grpc_resolver *create_resolver(const char *name) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
   grpc_uri *uri = grpc_uri_parse(name, 0);
   GPR_ASSERT(uri);
@@ -71,9 +72,10 @@ static grpc_resolver *create_resolver(const char *name) {
   memset(&args, 0, sizeof(args));
   args.uri = uri;
   grpc_resolver *resolver =
-      grpc_resolver_factory_create_resolver(factory, &args);
+      grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   grpc_resolver_factory_unref(factory);
   grpc_uri_destroy(uri);
+  grpc_exec_ctx_finish(&exec_ctx);
   return resolver;
 }
 
@@ -123,7 +125,7 @@ int main(int argc, char **argv) {
   GPR_ASSERT(wait_loop(30, &ev2));
   GPR_ASSERT(result != NULL);
 
-  grpc_channel_args_destroy(result);
+  grpc_channel_args_destroy(&exec_ctx, result);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test");
   grpc_exec_ctx_finish(&exec_ctx);
 
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 41a9125431..5603a57b5f 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -48,7 +48,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
   grpc_uri_destroy(uri);
@@ -65,7 +65,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index ebf311ab83..bf49fb155d 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -54,7 +54,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   GPR_ASSERT(channel_arg != NULL);
   GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
   GPR_ASSERT(strcmp(res->expected_server_name, channel_arg->value.string) == 0);
-  grpc_channel_args_destroy(res->resolver_result);
+  grpc_channel_args_destroy(exec_ctx, res->resolver_result);
 }
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
@@ -67,7 +67,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
 
   on_resolution_arg on_res_arg;
@@ -93,7 +93,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
index b342d613b2..d12e1c3e41 100644
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ b/test/core/client_channel/set_initial_connect_string_test.c
@@ -155,9 +155,9 @@ static void start_rpc(int use_creds, int target_port) {
 
 static void cleanup_rpc(void) {
   grpc_event ev;
-  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming_buffer);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
-  grpc_channel_credentials_unref(state.creds);
+  grpc_slice_buffer_destroy(&state.incoming_buffer);
+  grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
+  grpc_channel_credentials_release(state.creds);
   grpc_call_destroy(state.call);
   grpc_completion_queue_shutdown(state.cq);
   do {
diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c
index bdee748ae6..ff17667b94 100644
--- a/test/core/compression/algorithm_test.c
+++ b/test/core/compression/algorithm_test.c
@@ -53,6 +53,7 @@ static void test_algorithm_mesh(void) {
     grpc_compression_algorithm parsed;
     grpc_mdstr *mdstr;
     grpc_mdelem *mdelem;
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     GPR_ASSERT(
         grpc_compression_algorithm_name((grpc_compression_algorithm)i, &name));
     GPR_ASSERT(grpc_compression_algorithm_parse(name, strlen(name), &parsed));
@@ -63,8 +64,9 @@ static void test_algorithm_mesh(void) {
     mdelem = grpc_compression_encoding_mdelem(parsed);
     GPR_ASSERT(mdelem->value == mdstr);
     GPR_ASSERT(mdelem->key == GRPC_MDSTR_GRPC_ENCODING);
-    GRPC_MDSTR_UNREF(mdstr);
-    GRPC_MDELEM_UNREF(mdelem);
+    GRPC_MDSTR_UNREF(&exec_ctx, mdstr);
+    GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
 
   /* test failure */
@@ -73,6 +75,7 @@ static void test_algorithm_mesh(void) {
 }
 
 static void test_algorithm_failure(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_mdstr *mdstr;
 
   gpr_log(GPR_DEBUG, "test_algorithm_failure");
@@ -88,7 +91,8 @@ static void test_algorithm_failure(void) {
              NULL);
   GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT +
                                               1) == NULL);
-  GRPC_MDSTR_UNREF(mdstr);
+  GRPC_MDSTR_UNREF(&exec_ctx, mdstr);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index ee4f0dbe40..2432ca768a 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/support/murmur_hash.h"
 #include "test/core/util/slice_splitter.h"
 #include "test/core/util/test_config.h"
@@ -82,7 +83,12 @@ static void assert_passthrough(grpc_slice value,
 
   grpc_split_slices_to_buffer(uncompressed_split_mode, &value, 1, &input);
 
-  was_compressed = grpc_msg_compress(algorithm, &input, &compressed_raw);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    was_compressed =
+        grpc_msg_compress(&exec_ctx, algorithm, &input, &compressed_raw);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   GPR_ASSERT(input.count > 0);
 
   switch (compress_result_check) {
@@ -99,16 +105,21 @@ static void assert_passthrough(grpc_slice value,
 
   grpc_split_slice_buffer(compressed_split_mode, &compressed_raw, &compressed);
 
-  GPR_ASSERT(grpc_msg_decompress(
-      was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed, &output));
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(grpc_msg_decompress(
+        &exec_ctx, was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed,
+        &output));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   final = grpc_slice_merge(output.slices, output.count);
   GPR_ASSERT(0 == grpc_slice_cmp(value, final));
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &compressed);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &compressed_raw);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&compressed);
+  grpc_slice_buffer_destroy(&compressed_raw);
+  grpc_slice_buffer_destroy(&output);
   grpc_slice_unref(final);
 }
 
@@ -160,12 +171,14 @@ static void test_tiny_data_compress(void) {
 
   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
     if (i == GRPC_COMPRESS_NONE) continue;
-    GPR_ASSERT(0 == grpc_msg_compress(i, &input, &output));
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(0 == grpc_msg_compress(&exec_ctx, i, &input, &output));
+    grpc_exec_ctx_finish(&exec_ctx);
     GPR_ASSERT(1 == output.count);
   }
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&output);
 }
 
 static void test_bad_decompression_data_crc(void) {
@@ -180,8 +193,9 @@ static void test_bad_decompression_data_crc(void) {
   grpc_slice_buffer_init(&output);
   grpc_slice_buffer_add(&input, create_test_value(ONE_MB_A));
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* compress it */
-  grpc_msg_compress(GRPC_COMPRESS_GZIP, &input, &corrupted);
+  grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_GZIP, &input, &corrupted);
   /* corrupt the output by smashing the CRC */
   GPR_ASSERT(corrupted.count > 1);
   GPR_ASSERT(GRPC_SLICE_LENGTH(corrupted.slices[1]) > 8);
@@ -189,11 +203,13 @@ static void test_bad_decompression_data_crc(void) {
   memcpy(GRPC_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4);
 
   /* try (and fail) to decompress the corrupted compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output));
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_GZIP, &corrupted,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &corrupted);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&corrupted);
+  grpc_slice_buffer_destroy(&output);
 }
 
 static void test_bad_decompression_data_trailing_garbage(void) {
@@ -208,10 +224,13 @@ static void test_bad_decompression_data_trailing_garbage(void) {
                   "\x78\xda\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x99", 13));
 
   /* try (and fail) to decompress the invalid compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&output);
 }
 
 static void test_bad_decompression_data_stream(void) {
@@ -224,10 +243,13 @@ static void test_bad_decompression_data_stream(void) {
                         grpc_slice_from_copied_buffer("\x78\xda\xff\xff", 4));
 
   /* try (and fail) to decompress the invalid compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&output);
 }
 
 static void test_bad_compression_algorithm(void) {
@@ -239,16 +261,19 @@ static void test_bad_compression_algorithm(void) {
   grpc_slice_buffer_init(&output);
   grpc_slice_buffer_add(
       &input, grpc_slice_from_copied_string("Never gonna give you up"));
-  was_compressed =
-      grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  was_compressed = grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT,
+                                     &input, &output);
   GPR_ASSERT(0 == was_compressed);
 
-  was_compressed =
-      grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+  was_compressed = grpc_msg_compress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_compressed);
+  grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&output);
 }
 
 static void test_bad_decompression_algorithm(void) {
@@ -261,16 +286,18 @@ static void test_bad_decompression_algorithm(void) {
   grpc_slice_buffer_add(&input,
                         grpc_slice_from_copied_string(
                             "I'm not really compressed but it doesn't matter"));
-  was_decompressed =
-      grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  was_decompressed = grpc_msg_decompress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
 
-  was_decompressed = grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123,
-                                         &input, &output);
+  was_decompressed = grpc_msg_decompress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
+  grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &input);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_slice_buffer_destroy(&input);
+  grpc_slice_buffer_destroy(&output);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 9dc70d79ec..84db87f9f3 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -47,6 +47,7 @@
 #include <grpc/support/thd.h>
 
 #include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
@@ -226,7 +227,7 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
   cq_verifier_destroy(cqv);
 }
 
-static void cleanup_rpc(void) {
+static void cleanup_rpc(grpc_exec_ctx *exec_ctx) {
   grpc_event ev;
   grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
   grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing_buffer);
@@ -298,8 +299,8 @@ static void run_test(const char *response_payload,
   /* clean up */
   grpc_endpoint_shutdown(&exec_ctx, state.tcp);
   grpc_endpoint_destroy(&exec_ctx, state.tcp);
+  cleanup_rpc(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
-  cleanup_rpc();
   test_tcp_server_destroy(&test_server);
 
   grpc_shutdown();
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 13414c0378..d57eaf5a65 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -75,6 +75,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
   /* if using service config, create channel args */
   grpc_channel_args *args = NULL;
   if (use_service_config) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     GPR_ASSERT(wait_for_ready);
     grpc_method_config_table_entry entry = {
         grpc_mdstr_from_string("/service/method"),
@@ -82,12 +83,13 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
     };
     grpc_method_config_table *method_config_table =
         grpc_method_config_table_create(1, &entry);
-    GRPC_MDSTR_UNREF(entry.method_name);
-    grpc_method_config_unref(entry.method_config);
+    GRPC_MDSTR_UNREF(&exec_ctx, entry.method_name);
+    grpc_method_config_unref(&exec_ctx, entry.method_config);
     grpc_arg arg =
         grpc_method_config_table_create_channel_arg(method_config_table);
     args = grpc_channel_args_copy_and_add(args, &arg, 1);
-    grpc_method_config_table_unref(method_config_table);
+    grpc_method_config_table_unref(&exec_ctx, method_config_table);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
 
   /* create a call, channel to a port which will refuse connection */
@@ -144,7 +146,11 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
   gpr_free(details);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
 
-  if (args != NULL) grpc_channel_args_destroy(args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    if (args != NULL) grpc_channel_args_destroy(&exec_ctx, args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   grpc_shutdown();
 }
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index dc03861f86..11e8604f56 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -145,7 +145,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
       gpr_free(hosts_with_port[i]);
     }
     gpr_free(hosts_with_port);
-    grpc_slice_buffer_destroy_internal(exec_ctx, &uri_parts);
+    grpc_slice_buffer_destroy(&uri_parts);
     grpc_slice_unref(uri_slice);
   } else {
     gpr_join_host_port(&client_hostport, client_host, port);
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index c52d7660f5..8e60123ed6 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -85,7 +85,11 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
   client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
   f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client);
-  grpc_channel_args_destroy(client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
@@ -97,7 +101,11 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
   }
   server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
   f->server = grpc_server_create(server_args, NULL);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index fedd2ebc46..c01e45664b 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -78,7 +78,9 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture *f,
                                               grpc_channel_args *client_args) {
   fullstack_compression_fixture_data *ffd = f->fixture_data;
   if (ffd->client_args_compression != NULL) {
-    grpc_channel_args_destroy(ffd->client_args_compression);
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
       client_args, GRPC_COMPRESS_GZIP);
@@ -90,7 +92,9 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
                                               grpc_channel_args *server_args) {
   fullstack_compression_fixture_data *ffd = f->fixture_data;
   if (ffd->server_args_compression != NULL) {
-    grpc_channel_args_destroy(ffd->server_args_compression);
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->server_args_compression = grpc_channel_args_set_compression_algorithm(
       server_args, GRPC_COMPRESS_GZIP);
@@ -104,11 +108,13 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
 }
 
 void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture *f) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   fullstack_compression_fixture_data *ffd = f->fixture_data;
-  grpc_channel_args_destroy(ffd->client_args_compression);
-  grpc_channel_args_destroy(ffd->server_args_compression);
+  grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+  grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
   gpr_free(ffd->localaddr);
   gpr_free(ffd);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* All test configurations */
diff --git a/test/core/end2end/fixtures/h2_load_reporting.c b/test/core/end2end/fixtures/h2_load_reporting.c
index 7a76489b44..38321f34db 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.c
+++ b/test/core/end2end/fixtures/h2_load_reporting.c
@@ -88,7 +88,11 @@ void chttp2_init_server_load_reporting(grpc_end2end_test_fixture *f,
   }
   server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
   f->server = grpc_server_create(server_args, NULL);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c
index 6122f4f2f9..83f759ce2d 100644
--- a/test/core/end2end/fixtures/h2_oauth2.c
+++ b/test/core/end2end/fixtures/h2_oauth2.c
@@ -163,7 +163,11 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_channel_credentials_release(ssl_creds);
   grpc_call_credentials_release(oauth2_creds);
 }
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index bbd522cf30..cf44cd093c 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -118,7 +118,11 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index e39cb491de..ae49cc859a 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -186,7 +186,11 @@ typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype;
     grpc_channel_args *new_client_args =                                     \
         grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);  \
     chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);      \
-    grpc_channel_args_destroy(new_client_args);                              \
+    {                                                                        \
+      grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;                           \
+      grpc_channel_args_destroy(&exec_ctx, new_client_args);                 \
+      grpc_exec_ctx_finish(&exec_ctx);                                       \
+    }                                                                        \
   }
 
 CLIENT_INIT(NONE)
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 27cf3ebf32..740b075bf6 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -79,7 +79,11 @@ static grpc_channel *create_proxy_client(const char *target,
   channel =
       grpc_secure_channel_create(ssl_creds, target, new_client_args, NULL);
   grpc_channel_credentials_release(ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return channel;
 }
 
@@ -151,7 +155,11 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 19ac6ced14..90ad0654c7 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -744,7 +744,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
           grpc_channel_args *args = read_args(&inp);
           g_channel = grpc_insecure_channel_create(target_uri, args, NULL);
           GPR_ASSERT(g_channel != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           gpr_free(target_uri);
           gpr_free(target);
         } else {
@@ -768,7 +772,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
           grpc_channel_args *args = read_args(&inp);
           g_server = grpc_server_create(args, NULL);
           GPR_ASSERT(g_server != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           grpc_server_register_completion_queue(g_server, cq, NULL);
           grpc_server_start(g_server);
           server_shutdown = false;
@@ -1104,7 +1112,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
           grpc_channel_credentials *creds = read_channel_creds(&inp);
           g_channel = grpc_secure_channel_create(creds, target_uri, args, NULL);
           GPR_ASSERT(g_channel != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           gpr_free(target_uri);
           gpr_free(target);
           grpc_channel_credentials_release(creds);
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 81b9ef5dff..065064fe1e 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -50,6 +50,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/iomgr/endpoint_tests.h"
 #include "test/core/util/test_config.h"
 
@@ -212,7 +214,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -263,7 +265,7 @@ static void large_read_test(size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -404,7 +406,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
   }
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &outgoing);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
   grpc_endpoint_destroy(&exec_ctx, ep);
   gpr_free(slices);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -472,7 +474,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy_internal(exec_ctx, &state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
   grpc_exec_ctx_flush(&exec_ctx);
   gpr_mu_lock(g_mu);
diff --git a/test/core/security/b64_test.c b/test/core/security/b64_test.c
index af883f51e9..28af48075e 100644
--- a/test/core/security/b64_test.c
+++ b/test/core/security/b64_test.c
@@ -38,6 +38,8 @@
 #include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 static int buffers_are_equal(const unsigned char *buf1,
@@ -57,12 +59,14 @@ static void test_simple_encode_decode_b64(int url_safe, int multiline) {
   const char *hello = "hello";
   char *hello_b64 =
       grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
-  grpc_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice hello_slice = grpc_base64_decode(&exec_ctx, hello_b64, url_safe);
   GPR_ASSERT(GRPC_SLICE_LENGTH(hello_slice) == strlen(hello));
   GPR_ASSERT(strncmp((const char *)GRPC_SLICE_START_PTR(hello_slice), hello,
                      GRPC_SLICE_LENGTH(hello_slice)) == 0);
 
-  grpc_slice_unref(hello_slice);
+  grpc_slice_unref_internal(&exec_ctx, hello_slice);
+  grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(hello_b64);
 }
 
@@ -75,13 +79,15 @@ static void test_full_range_encode_decode_b64(int url_safe, int multiline) {
 
   /* Try all the different paddings. */
   for (i = 0; i < 3; i++) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
-    orig_decoded = grpc_base64_decode(b64, url_safe);
+    orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
     GPR_ASSERT(GRPC_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
     GPR_ASSERT(buffers_are_equal(orig, GRPC_SLICE_START_PTR(orig_decoded),
                                  sizeof(orig) - i));
-    grpc_slice_unref(orig_decoded);
+    grpc_slice_unref_internal(&exec_ctx, orig_decoded);
     gpr_free(b64);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
 }
 
@@ -117,7 +123,7 @@ static void test_full_range_encode_decode_b64_urlsafe_multiline(void) {
   test_full_range_encode_decode_b64(1, 1);
 }
 
-static void test_url_safe_unsafe_mismtach_failure(void) {
+static void test_url_safe_unsafe_mismatch_failure(void) {
   unsigned char orig[256];
   size_t i;
   char *b64;
@@ -125,17 +131,19 @@ static void test_url_safe_unsafe_mismtach_failure(void) {
   int url_safe = 1;
   for (i = 0; i < sizeof(orig); i++) orig[i] = (uint8_t)i;
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
-  orig_decoded = grpc_base64_decode(b64, !url_safe);
+  orig_decoded = grpc_base64_decode(&exec_ctx, b64, !url_safe);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
   gpr_free(b64);
-  grpc_slice_unref(orig_decoded);
+  grpc_slice_unref_internal(&exec_ctx, orig_decoded);
 
   b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
-  orig_decoded = grpc_base64_decode(b64, url_safe);
+  orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
   gpr_free(b64);
-  grpc_slice_unref(orig_decoded);
+  grpc_slice_unref_internal(&exec_ctx, orig_decoded);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_rfc4648_test_vectors(void) {
@@ -173,38 +181,40 @@ static void test_rfc4648_test_vectors(void) {
 static void test_unpadded_decode(void) {
   grpc_slice decoded;
 
-  decoded = grpc_base64_decode("Zm9vYmFy", 0);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmFy", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foobar") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9vYmE", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmE", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fooba") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9vYg", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYg", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foob") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9v", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9v", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foo") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm8", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm8", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fo") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zg", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zg", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "f") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "", 0);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(decoded));
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
@@ -217,7 +227,7 @@ int main(int argc, char **argv) {
   test_full_range_encode_decode_b64_multiline();
   test_full_range_encode_decode_b64_urlsafe_no_multiline();
   test_full_range_encode_decode_b64_urlsafe_multiline();
-  test_url_safe_unsafe_mismtach_failure();
+  test_url_safe_unsafe_mismatch_failure();
   test_rfc4648_test_vectors();
   test_unpadded_decode();
   return 0;
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d4c755088d..8fd4737c8f 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -166,24 +166,29 @@ static grpc_httpcli_response http_response(int status, const char *body) {
 /* -- Tests. -- */
 
 static void test_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 0);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_ref_unref_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   grpc_credentials_md_store_ref(store);
   grpc_credentials_md_store_ref(store);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 0);
-  grpc_credentials_md_store_unref(store);
-  grpc_credentials_md_store_unref(store);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_to_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   const char *key_str = "hello";
   const char *value_str = "there blah blah blah blah blah blah blah";
@@ -195,10 +200,12 @@ static void test_add_to_empty_md_store(void) {
   GPR_ASSERT(grpc_slice_cmp(value, store->entries[0].value) == 0);
   grpc_slice_unref(key);
   grpc_slice_unref(value);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_cstrings_to_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   const char *key_str = "hello";
   const char *value_str = "there blah blah blah blah blah blah blah";
@@ -206,18 +213,22 @@ static void test_add_cstrings_to_empty_md_store(void) {
   GPR_ASSERT(store->num_entries == 1);
   GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].key, key_str) == 0);
   GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].value, value_str) == 0);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_empty_preallocated_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 4);
   GPR_ASSERT(store->entries != NULL);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_abunch_to_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
   size_t num_entries = 1000;
   const char *key_str = "hello";
@@ -230,16 +241,19 @@ static void test_add_abunch_to_md_store(void) {
     GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].key, key_str) == 0);
     GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].value, value_str) == 0);
   }
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
       http_response(200, valid_oauth2_json_response);
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
+             GRPC_CREDENTIALS_OK);
   GPR_ASSERT(token_lifetime.tv_sec == 3599);
   GPR_ASSERT(token_lifetime.tv_nsec == 0);
   GPR_ASSERT(token_md->num_entries == 1);
@@ -248,32 +262,38 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
   GPR_ASSERT(grpc_slice_str_cmp(token_md->entries[0].value,
                                 "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
              0);
-  grpc_credentials_md_store_unref(token_md);
+  grpc_credentials_md_store_unref(&exec_ctx, token_md);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
       http_response(401, valid_oauth2_json_response);
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response = http_response(200, "");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -282,12 +302,14 @@ static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
                     " \"expires_in\":3599, "
                     " \"token_type\":\"Bearer\"");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response = http_response(200,
@@ -295,12 +317,14 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
                                                  " \"expires_in\":3599, "
                                                  " \"token_type\":\"Bearer\"}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -309,13 +333,15 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
                     " \"expires_in\":3599, "
                     "}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
     void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -323,9 +349,10 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
                     " \"token_type\":\"Bearer\"}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems,
@@ -361,7 +388,7 @@ static void check_google_iam_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 2);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_google_iam_creds(void) {
@@ -385,7 +412,7 @@ static void check_access_token_metadata(
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 1);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_access_token_creds(void) {
@@ -401,9 +428,10 @@ static void test_access_token_creds(void) {
 }
 
 static grpc_security_status check_channel_oauth2_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   GPR_ASSERT(strcmp(c->type, "mock") == 0);
   GPR_ASSERT(call_creds != NULL);
   GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
@@ -411,6 +439,7 @@ static grpc_security_status check_channel_oauth2_create_security_connector(
 }
 
 static void test_channel_oauth2_composite_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
       NULL, check_channel_oauth2_create_security_connector, NULL};
@@ -424,9 +453,10 @@ static void test_channel_oauth2_composite_creds(void) {
   grpc_channel_credentials_release(channel_creds);
   grpc_call_credentials_release(oauth2_creds);
   GPR_ASSERT(grpc_channel_credentials_create_security_connector(
-                 channel_oauth2_creds, NULL, NULL, NULL, &new_args) ==
-             GRPC_SECURITY_OK);
+                 &exec_ctx, channel_oauth2_creds, NULL, NULL, NULL,
+                 &new_args) == GRPC_SECURITY_OK);
   grpc_channel_credentials_release(channel_oauth2_creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void check_oauth2_google_iam_composite_metadata(
@@ -443,7 +473,7 @@ static void check_oauth2_google_iam_composite_metadata(
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 3);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_oauth2_google_iam_composite_creds(void) {
@@ -459,8 +489,8 @@ static void test_oauth2_google_iam_composite_creds(void) {
   grpc_call_credentials *composite_creds =
       grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
                                              NULL);
-  grpc_call_credentials_unref(oauth2_creds);
-  grpc_call_credentials_unref(google_iam_creds);
+  grpc_call_credentials_unref(&exec_ctx, oauth2_creds);
+  grpc_call_credentials_unref(&exec_ctx, google_iam_creds);
   GPR_ASSERT(
       strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
   creds_array =
@@ -478,9 +508,10 @@ static void test_oauth2_google_iam_composite_creds(void) {
 
 static grpc_security_status
 check_channel_oauth2_google_iam_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   const grpc_call_credentials_array *creds_array;
   GPR_ASSERT(strcmp(c->type, "mock") == 0);
   GPR_ASSERT(call_creds != NULL);
@@ -495,6 +526,7 @@ check_channel_oauth2_google_iam_create_security_connector(
 }
 
 static void test_channel_oauth2_google_iam_composite_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
       NULL, check_channel_oauth2_google_iam_create_security_connector, NULL};
@@ -517,10 +549,11 @@ static void test_channel_oauth2_google_iam_composite_creds(void) {
   grpc_call_credentials_release(google_iam_creds);
 
   GPR_ASSERT(grpc_channel_credentials_create_security_connector(
-                 channel_oauth2_iam_creds, NULL, NULL, NULL, &new_args) ==
-             GRPC_SECURITY_OK);
+                 &exec_ctx, channel_oauth2_iam_creds, NULL, NULL, NULL,
+                 &new_args) == GRPC_SECURITY_OK);
 
   grpc_channel_credentials_release(channel_oauth2_iam_creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void on_oauth2_creds_get_metadata_success(
@@ -619,7 +652,7 @@ static void test_compute_engine_creds_success(void) {
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_call_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -634,7 +667,7 @@ static void test_compute_engine_creds_failure(void) {
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_call_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -706,7 +739,7 @@ static void test_refresh_token_creds_success(void) {
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
 
-  grpc_call_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -723,7 +756,7 @@ static void test_refresh_token_creds_failure(void) {
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_call_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -832,7 +865,7 @@ static void test_jwt_creds_success(void) {
   grpc_exec_ctx_flush(&exec_ctx);
 
   gpr_free(json_key_string);
-  grpc_call_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(&exec_ctx, jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
 }
 
@@ -851,7 +884,7 @@ static void test_jwt_creds_signing_failure(void) {
       on_jwt_creds_get_metadata_failure, (void *)test_user_data);
 
   gpr_free(json_key_string);
-  grpc_call_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(&exec_ctx, jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -870,6 +903,7 @@ static void set_google_default_creds_env_var_with_file_contents(
 }
 
 static void test_google_default_creds_auth_key(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_service_account_jwt_access_credentials *jwt;
   grpc_composite_channel_credentials *creds;
   char *json_key = test_json_key_str();
@@ -885,11 +919,13 @@ static void test_google_default_creds_auth_key(void) {
       strcmp(jwt->key.client_id,
              "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
       0);
-  grpc_channel_credentials_unref(&creds->base);
+  grpc_channel_credentials_unref(&exec_ctx, &creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_google_default_creds_refresh_token(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_google_refresh_token_credentials *refresh;
   grpc_composite_channel_credentials *creds;
   grpc_flush_cached_google_default_credentials();
@@ -901,8 +937,9 @@ static void test_google_default_creds_refresh_token(void) {
   refresh = (grpc_google_refresh_token_credentials *)creds->call_creds;
   GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
                     "32555999999.apps.googleusercontent.com") == 0);
-  grpc_channel_credentials_unref(&creds->base);
+  grpc_channel_credentials_unref(&exec_ctx, &creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static int default_creds_gce_detection_httpcli_get_success_override(
@@ -1142,6 +1179,8 @@ static void test_get_well_known_google_credentials_file_path(void) {
 }
 
 static void test_channel_creds_duplicate_without_call_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   grpc_channel_credentials *channel_creds =
       grpc_fake_transport_security_credentials_create();
 
@@ -1149,21 +1188,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) {
       grpc_channel_credentials_duplicate_without_call_credentials(
           channel_creds);
   GPR_ASSERT(dup == channel_creds);
-  grpc_channel_credentials_unref(dup);
+  grpc_channel_credentials_unref(&exec_ctx, dup);
 
   grpc_call_credentials *call_creds =
       grpc_access_token_credentials_create("blah", NULL);
   grpc_channel_credentials *composite_creds =
       grpc_composite_channel_credentials_create(channel_creds, call_creds,
                                                 NULL);
-  grpc_call_credentials_unref(call_creds);
+  grpc_call_credentials_unref(&exec_ctx, call_creds);
   dup = grpc_channel_credentials_duplicate_without_call_credentials(
       composite_creds);
   GPR_ASSERT(dup == channel_creds);
-  grpc_channel_credentials_unref(dup);
+  grpc_channel_credentials_unref(&exec_ctx, dup);
 
-  grpc_channel_credentials_unref(channel_creds);
-  grpc_channel_credentials_unref(composite_creds);
+  grpc_channel_credentials_unref(&exec_ctx, channel_creds);
+  grpc_channel_credentials_unref(&exec_ctx, composite_creds);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 201655881f..5cebb09bb2 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/json/json.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 /* This JSON key was generated with the GCE console and revoked immediately.
@@ -220,6 +221,7 @@ static void test_parse_json_key_failure_no_private_key(void) {
 
 static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
                                            char **scratchpad) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   char *b64;
   char *decoded;
   grpc_json *json;
@@ -227,7 +229,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
   b64 = gpr_malloc(len + 1);
   strncpy(b64, str, len);
   b64[len] = '\0';
-  slice = grpc_base64_decode(b64, 1);
+  slice = grpc_base64_decode(&exec_ctx, b64, 1);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(slice));
   decoded = gpr_malloc(GRPC_SLICE_LENGTH(slice) + 1);
   strncpy(decoded, (const char *)GRPC_SLICE_START_PTR(slice),
@@ -237,6 +239,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
   gpr_free(b64);
   *scratchpad = decoded;
   grpc_slice_unref(slice);
+  grpc_exec_ctx_finish(&exec_ctx);
   return json;
 }
 
@@ -338,10 +341,12 @@ static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
 static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
                                 const char *signed_data,
                                 size_t signed_data_size) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
   EVP_PKEY *key = EVP_PKEY_new();
 
-  grpc_slice sig = grpc_base64_decode(b64_signature, 1);
+  grpc_slice sig = grpc_base64_decode(&exec_ctx, b64_signature, 1);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
   GPR_ASSERT(GRPC_SLICE_LENGTH(sig) == 128);
 
@@ -355,9 +360,11 @@ static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
   GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(sig),
                                    GRPC_SLICE_LENGTH(sig)) == 1);
 
-  grpc_slice_unref(sig);
+  grpc_slice_unref_internal(&exec_ctx, sig);
   if (key != NULL) EVP_PKEY_free(key);
   if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static char *service_account_creds_jwt_encode_and_sign(
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index f8afba8d6d..14321d164e 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -185,7 +185,8 @@ static void test_claims_success(void) {
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -194,7 +195,8 @@ static void test_claims_success(void) {
   GPR_ASSERT(strcmp(grpc_jwt_claims_id(claims), "jwtuniqueid") == 0);
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
              GRPC_JWT_VERIFIER_OK);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_expired_claims_failure(void) {
@@ -206,7 +208,8 @@ static void test_expired_claims_failure(void) {
   gpr_timespec exp_exp = {120, 0, GPR_CLOCK_REALTIME};
   gpr_timespec exp_nbf = {60, 0, GPR_CLOCK_REALTIME};
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -219,14 +222,17 @@ static void test_expired_claims_failure(void) {
 
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
              GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_invalid_claims_failure(void) {
   grpc_slice s = grpc_slice_from_copied_string(invalid_claims);
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
-  GPR_ASSERT(grpc_jwt_claims_from_json(json, s) == NULL);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(grpc_jwt_claims_from_json(&exec_ctx, json, s) == NULL);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_bad_audience_claims_failure(void) {
@@ -235,11 +241,13 @@ static void test_bad_audience_claims_failure(void) {
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://bar.com") ==
              GRPC_JWT_VERIFIER_BAD_AUDIENCE);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static char *json_key_str(const char *last_part) {
@@ -305,7 +313,9 @@ static void on_verification_success(void *user_data,
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(user_data == (void *)expected_user_data);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), expected_audience) == 0);
-  grpc_jwt_claims_destroy(claims);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_jwt_verifier_google_email_issuer_success(void) {
@@ -483,7 +493,11 @@ static void corrupt_jwt_sig(char *jwt) {
   uint8_t *sig_bytes;
   char *last_dot = strrchr(jwt, '.');
   GPR_ASSERT(last_dot != NULL);
-  sig = grpc_base64_decode(last_dot + 1, 1);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    sig = grpc_base64_decode(&exec_ctx, last_dot + 1, 1);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
   sig_bytes = GRPC_SLICE_START_PTR(sig);
   (*sig_bytes)++; /* Corrupt first byte. */
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index e49662d428..3a0c2bb272 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -42,6 +42,7 @@
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/tsi/fake_transport_security.h"
 #include "test/core/util/test_config.h"
 
@@ -170,8 +171,8 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_slice_unref(s);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &incoming);
+  grpc_slice_unref_internal(&exec_ctx, s);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &incoming);
 
   clean_up();
 }
diff --git a/test/core/slice/slice_buffer_test.c b/test/core/slice/slice_buffer_test.c
index e5ef3047e5..bf9ae197d2 100644
--- a/test/core/slice/slice_buffer_test.c
+++ b/test/core/slice/slice_buffer_test.c
@@ -68,7 +68,7 @@ void test_slice_buffer_add() {
   }
   GPR_ASSERT(buf.count == 0);
   GPR_ASSERT(buf.length == 0);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &buf);
+  grpc_slice_buffer_destroy(&buf);
 }
 
 void test_slice_buffer_move_first() {
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index 0d1628821b..2f1f72f0e0 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -40,9 +40,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
-#include "test/core/util/test_config.h"
 
 #include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "test/core/util/test_config.h"
 
 #include <string.h>
 
@@ -145,7 +146,12 @@ static void read_compressed_slice(grpc_compression_algorithm algorithm,
   input_slice = grpc_slice_malloc(input_size);
   memset(GRPC_SLICE_START_PTR(input_slice), 'a', input_size);
   grpc_slice_buffer_add(&sliceb_in, input_slice); /* takes ownership */
-  GPR_ASSERT(grpc_msg_compress(algorithm, &sliceb_in, &sliceb_out));
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(
+        grpc_msg_compress(&exec_ctx, algorithm, &sliceb_in, &sliceb_out));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   buffer = grpc_raw_compressed_byte_buffer_create(sliceb_out.slices,
                                                   sliceb_out.count, algorithm);
@@ -162,8 +168,8 @@ static void read_compressed_slice(grpc_compression_algorithm algorithm,
   GPR_ASSERT(read_count == input_size);
   grpc_byte_buffer_reader_destroy(&reader);
   grpc_byte_buffer_destroy(buffer);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &sliceb_out);
-  grpc_slice_buffer_destroy_internal(exec_ctx, &sliceb_in);
+  grpc_slice_buffer_destroy(&sliceb_out);
+  grpc_slice_buffer_destroy(&sliceb_in);
 }
 
 static void test_read_gzip_compressed_slice(void) {
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
index 444ebdc093..ab4067dbe1 100644
--- a/test/core/surface/secure_channel_create_test.c
+++ b/test/core/surface/secure_channel_create_test.c
@@ -51,7 +51,9 @@ void test_unknown_scheme_target(void) {
   creds = grpc_fake_transport_security_credentials_create();
   chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL);
   GPR_ASSERT(chan == NULL);
-  grpc_channel_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_channel_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void test_security_connector_already_in_arg(void) {
diff --git a/test/core/surface/sequential_connectivity_test.c b/test/core/surface/sequential_connectivity_test.c
index fe87f119f2..3292718762 100644
--- a/test/core/surface/sequential_connectivity_test.c
+++ b/test/core/surface/sequential_connectivity_test.c
@@ -39,6 +39,7 @@
 #include <grpc/support/thd.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
@@ -162,7 +163,11 @@ static grpc_channel *secure_test_create_channel(const char *addr) {
       grpc_channel_args_copy_and_add(NULL, &ssl_name_override, 1);
   grpc_channel *channel =
       grpc_secure_channel_create(ssl_creds, addr, new_client_args, NULL);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_channel_credentials_release(ssl_creds);
   return channel;
 }
diff --git a/test/core/transport/chttp2/bin_decoder_test.c b/test/core/transport/chttp2/bin_decoder_test.c
index 7ddc30291a..221112ab21 100644
--- a/test/core/transport/chttp2/bin_decoder_test.c
+++ b/test/core/transport/chttp2/bin_decoder_test.c
@@ -38,13 +38,14 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
 static int all_ok = 1;
 
-static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
-                            int line) {
+static void expect_slice_eq(grpc_exec_ctx *exec_ctx, grpc_slice expected,
+                            grpc_slice slice, char *debug, int line) {
   if (0 != grpc_slice_cmp(slice, expected)) {
     char *hs = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
     char *he = grpc_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -54,92 +55,104 @@ static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
     gpr_free(he);
     all_ok = 0;
   }
-  grpc_slice_unref(expected);
-  grpc_slice_unref(slice);
+  grpc_slice_unref_internal(exec_ctx, expected);
+  grpc_slice_unref_internal(exec_ctx, slice);
 }
 
-static grpc_slice base64_encode(const char *s) {
+static grpc_slice base64_encode(grpc_exec_ctx *exec_ctx, const char *s) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
   grpc_slice out = grpc_chttp2_base64_encode(ss);
-  grpc_slice_unref(ss);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-static grpc_slice base64_decode(const char *s) {
+static grpc_slice base64_decode(grpc_exec_ctx *exec_ctx, const char *s) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
-  grpc_slice out = grpc_chttp2_base64_decode(ss);
-  grpc_slice_unref(ss);
+  grpc_slice out = grpc_chttp2_base64_decode(exec_ctx, ss);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-static grpc_slice base64_decode_with_length(const char *s,
+static grpc_slice base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                            const char *s,
                                             size_t output_length) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
-  grpc_slice out = grpc_chttp2_base64_decode_with_length(ss, output_length);
-  grpc_slice_unref(ss);
+  grpc_slice out =
+      grpc_chttp2_base64_decode_with_length(exec_ctx, ss, output_length);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-#define EXPECT_SLICE_EQ(expected, slice)                                    \
-  expect_slice_eq(                                                          \
-      grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \
-      #slice, __LINE__);
+#define EXPECT_SLICE_EQ(exec_ctx, expected, slice)                             \
+  expect_slice_eq(                                                             \
+      exec_ctx, grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), \
+      slice, #slice, __LINE__);
 
-#define ENCODE_AND_DECODE(s) \
-  EXPECT_SLICE_EQ(           \
-      s, grpc_chttp2_base64_decode_with_length(base64_encode(s), strlen(s)));
+#define ENCODE_AND_DECODE(exec_ctx, s)                   \
+  EXPECT_SLICE_EQ(exec_ctx, s,                           \
+                  grpc_chttp2_base64_decode_with_length( \
+                      exec_ctx, base64_encode(exec_ctx, s), strlen(s)));
 
 int main(int argc, char **argv) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   /* ENCODE_AND_DECODE tests grpc_chttp2_base64_decode_with_length(), which
      takes encoded base64 strings without pad chars, but output length is
      required. */
   /* Base64 test vectors from RFC 4648 */
-  ENCODE_AND_DECODE("");
-  ENCODE_AND_DECODE("f");
-  ENCODE_AND_DECODE("foo");
-  ENCODE_AND_DECODE("fo");
-  ENCODE_AND_DECODE("foob");
-  ENCODE_AND_DECODE("fooba");
-  ENCODE_AND_DECODE("foobar");
+  ENCODE_AND_DECODE(&exec_ctx, "");
+  ENCODE_AND_DECODE(&exec_ctx, "f");
+  ENCODE_AND_DECODE(&exec_ctx, "foo");
+  ENCODE_AND_DECODE(&exec_ctx, "fo");
+  ENCODE_AND_DECODE(&exec_ctx, "foob");
+  ENCODE_AND_DECODE(&exec_ctx, "fooba");
+  ENCODE_AND_DECODE(&exec_ctx, "foobar");
 
-  ENCODE_AND_DECODE("\xc0\xc1\xc2\xc3\xc4\xc5");
+  ENCODE_AND_DECODE(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5");
 
   /* Base64 test vectors from RFC 4648, with pad chars */
   /* BASE64("") = "" */
-  EXPECT_SLICE_EQ("", base64_decode(""));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, ""));
   /* BASE64("f") = "Zg==" */
-  EXPECT_SLICE_EQ("f", base64_decode("Zg=="));
+  EXPECT_SLICE_EQ(&exec_ctx, "f", base64_decode(&exec_ctx, "Zg=="));
   /* BASE64("fo") = "Zm8=" */
-  EXPECT_SLICE_EQ("fo", base64_decode("Zm8="));
+  EXPECT_SLICE_EQ(&exec_ctx, "fo", base64_decode(&exec_ctx, "Zm8="));
   /* BASE64("foo") = "Zm9v" */
-  EXPECT_SLICE_EQ("foo", base64_decode("Zm9v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "foo", base64_decode(&exec_ctx, "Zm9v"));
   /* BASE64("foob") = "Zm9vYg==" */
-  EXPECT_SLICE_EQ("foob", base64_decode("Zm9vYg=="));
+  EXPECT_SLICE_EQ(&exec_ctx, "foob", base64_decode(&exec_ctx, "Zm9vYg=="));
   /* BASE64("fooba") = "Zm9vYmE=" */
-  EXPECT_SLICE_EQ("fooba", base64_decode("Zm9vYmE="));
+  EXPECT_SLICE_EQ(&exec_ctx, "fooba", base64_decode(&exec_ctx, "Zm9vYmE="));
   /* BASE64("foobar") = "Zm9vYmFy" */
-  EXPECT_SLICE_EQ("foobar", base64_decode("Zm9vYmFy"));
+  EXPECT_SLICE_EQ(&exec_ctx, "foobar", base64_decode(&exec_ctx, "Zm9vYmFy"));
 
-  EXPECT_SLICE_EQ("\xc0\xc1\xc2\xc3\xc4\xc5", base64_decode("wMHCw8TF"));
+  EXPECT_SLICE_EQ(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5",
+                  base64_decode(&exec_ctx, "wMHCw8TF"));
 
   // Test illegal input length in grpc_chttp2_base64_decode
-  EXPECT_SLICE_EQ("", base64_decode("a"));
-  EXPECT_SLICE_EQ("", base64_decode("ab"));
-  EXPECT_SLICE_EQ("", base64_decode("abc"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "a"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "ab"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "abc"));
 
   // Test illegal charactors in grpc_chttp2_base64_decode
-  EXPECT_SLICE_EQ("", base64_decode("Zm:v"));
-  EXPECT_SLICE_EQ("", base64_decode("Zm=v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm:v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm=v"));
 
   // Test output_length longer than max possible output length in
   // grpc_chttp2_base64_decode_with_length
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zg", 2));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm8", 3));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm9v", 4));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode_with_length(&exec_ctx, "Zg", 2));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm8", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm9v", 4));
 
   // Test illegal charactors in grpc_chttp2_base64_decode_with_length
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm:v", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm=v", 3));
+
+  grpc_exec_ctx_finish(&exec_ctx);
 
   return all_ok ? 0 : 1;
 }
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 6f1a1f7223..1fd2540d65 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -41,6 +41,7 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/metadata.h"
@@ -59,8 +60,9 @@ size_t cap_to_delete = 0;
 
 /* verify that the output generated by encoding the stream matches the
    hexstring passed in */
-static void verify(size_t window_available, int eof, size_t expect_window_used,
-                   const char *expected, size_t nheaders, ...) {
+static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
+                   size_t expect_window_used, const char *expected,
+                   size_t nheaders, ...) {
   grpc_slice_buffer output;
   grpc_slice merged;
   grpc_slice expect = parse_hexstring(expected);
@@ -79,7 +81,7 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
       e[i - 1].next = &e[i];
       e[i].prev = &e[i - 1];
     }
-    e[i].md = grpc_mdelem_from_strings(key, value);
+    e[i].md = grpc_mdelem_from_strings(exec_ctx, key, value);
   }
   e[0].prev = NULL;
   e[nheaders - 1].next = NULL;
@@ -98,11 +100,11 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
-                            &output);
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, eof, 16384,
+                            &stats, &output);
   merged = grpc_slice_merge(output.slices, output.count);
   grpc_slice_buffer_destroy_internal(exec_ctx, &output);
-  grpc_metadata_batch_destroy(&b);
+  grpc_metadata_batch_destroy(exec_ctx, &b);
 
   if (0 != grpc_slice_cmp(merged, expect)) {
     char *expect_str = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -115,31 +117,32 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
     g_failure = 1;
   }
 
-  grpc_slice_unref(merged);
-  grpc_slice_unref(expect);
+  grpc_slice_unref_internal(exec_ctx, merged);
+  grpc_slice_unref_internal(exec_ctx, expect);
 }
 
-static void test_basic_headers(void) {
+static void test_basic_headers(grpc_exec_ctx *exec_ctx) {
   int i;
 
-  verify(0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
-  verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a", "b",
+  verify(exec_ctx, 0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a",
+         "b", "c");
+  verify(exec_ctx, 0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b",
          "c");
-  verify(0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b", "c");
-  verify(0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
+  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
 
   /* flush out what's there to make a few values look very popular */
   for (i = 0; i < 350; i++) {
-    verify(0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b", "c", "a",
-           "d");
+    verify(exec_ctx, 0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b",
+           "c", "a", "d");
   }
 
-  verify(0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a", "k",
-         "v");
+  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a",
+         "k", "v");
   /* this could be 000004 0104 deadbeef 0f 30 0176 also */
-  verify(0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
+  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
 }
 
 static void encode_int_to_str(int i, char *p) {
@@ -150,7 +153,7 @@ static void encode_int_to_str(int i, char *p) {
   p[2] = 0;
 }
 
-static void test_decode_table_overflow(void) {
+static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
   int i;
   char key[3], value[3];
   char *expect;
@@ -173,22 +176,24 @@ static void test_decode_table_overflow(void) {
     }
 
     if (i > 0) {
-      verify(0, 0, 0, expect, 2, "aa", "ba", key, value);
+      verify(exec_ctx, 0, 0, 0, expect, 2, "aa", "ba", key, value);
     } else {
-      verify(0, 0, 0, expect, 1, key, value);
+      verify(exec_ctx, 0, 0, 0, expect, 1, key, value);
     }
     gpr_free(expect);
   }
 
   /* if the above passes, then we must have just knocked this pair out of the
      decoder stack, and so we'll be forced to re-encode it */
-  verify(0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa", "ba");
+  verify(exec_ctx, 0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa",
+         "ba");
 }
 
-static void verify_table_size_change_match_elem_size(const char *key,
+static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
+                                                     const char *key,
                                                      const char *value) {
   grpc_slice_buffer output;
-  grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+  grpc_mdelem *elem = grpc_mdelem_from_strings(exec_ctx, key, value);
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   size_t initial_table_size = g_compressor.table_size;
   grpc_linked_mdelem *e = gpr_malloc(sizeof(*e));
@@ -203,25 +208,27 @@ static void verify_table_size_change_match_elem_size(const char *key,
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats,
-                            &output);
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, 0, 16384,
+                            &stats, &output);
   grpc_slice_buffer_destroy_internal(exec_ctx, &output);
-  grpc_metadata_batch_destroy(&b);
+  grpc_metadata_batch_destroy(exec_ctx, &b);
 
   GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
   gpr_free(e);
 }
 
-static void test_encode_header_size(void) {
-  verify_table_size_change_match_elem_size("hello", "world");
-  verify_table_size_change_match_elem_size("hello-bin", "world");
+static void test_encode_header_size(grpc_exec_ctx *exec_ctx) {
+  verify_table_size_change_match_elem_size(exec_ctx, "hello", "world");
+  verify_table_size_change_match_elem_size(exec_ctx, "hello-bin", "world");
 }
 
-static void run_test(void (*test)(), const char *name) {
+static void run_test(void (*test)(grpc_exec_ctx *exec_ctx), const char *name) {
   gpr_log(GPR_INFO, "RUN TEST: %s", name);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hpack_compressor_init(&g_compressor);
-  test();
-  grpc_chttp2_hpack_compressor_destroy(&g_compressor);
+  test(&exec_ctx);
+  grpc_chttp2_hpack_compressor_destroy(&exec_ctx, &g_compressor);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
index 95acbf1a68..4e00f49b66 100644
--- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
@@ -44,7 +44,7 @@ bool squelch = true;
 bool leak_check = true;
 
 static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) {
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 static void dont_log(gpr_log_func_args *args) {}
 
@@ -53,13 +53,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   if (squelch) gpr_set_log_function(dont_log);
   grpc_init();
   grpc_chttp2_hpack_parser parser;
-  grpc_chttp2_hpack_parser_init(&parser);
-  parser.on_header = onhdr;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  parser.on_header = onhdr;
   GRPC_ERROR_UNREF(
       grpc_chttp2_hpack_parser_parse(&exec_ctx, &parser, data, data + size));
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_chttp2_hpack_parser_destroy(&parser);
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index e2813df70c..8f48849c97 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -54,7 +54,7 @@ static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) {
   GPR_ASSERT(evalue);
   GPR_ASSERT(grpc_slice_str_cmp(md->key->slice, ekey) == 0);
   GPR_ASSERT(grpc_slice_str_cmp(md->value->slice, evalue) == 0);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 
 static void test_vector(grpc_chttp2_hpack_parser *parser,
@@ -94,8 +94,9 @@ static void test_vector(grpc_chttp2_hpack_parser *parser,
 
 static void test_vectors(grpc_slice_split_mode mode) {
   grpc_chttp2_hpack_parser parser;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.2.1 */
   test_vector(&parser, mode,
               "400a 6375 7374 6f6d 2d6b 6579 0d63 7573"
@@ -111,9 +112,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
               "password", "secret", NULL);
   /* D.2.4 */
   test_vector(&parser, mode, "82", ":method", "GET", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.3.1 */
   test_vector(&parser, mode,
               "8286 8441 0f77 7777 2e65 7861 6d70 6c65"
@@ -131,9 +132,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
               ":method", "GET", ":scheme", "https", ":path", "/index.html",
               ":authority", "www.example.com", "custom-key", "custom-value",
               NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.4.1 */
   test_vector(&parser, mode,
               "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
@@ -151,11 +152,11 @@ static void test_vectors(grpc_slice_split_mode mode) {
               ":method", "GET", ":scheme", "https", ":path", "/index.html",
               ":authority", "www.example.com", "custom-key", "custom-value",
               NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
-  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
-  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
   /* D.5.1 */
   test_vector(&parser, mode,
               "4803 3330 3258 0770 7269 7661 7465 611d"
@@ -185,11 +186,11 @@ static void test_vectors(grpc_slice_split_mode mode) {
               "https://www.example.com", "content-encoding", "gzip",
               "set-cookie",
               "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
-  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
-  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
   /* D.6.1 */
   test_vector(&parser, mode,
               "4882 6402 5885 aec3 771a 4b61 96d0 7abe"
@@ -216,7 +217,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
               "https://www.example.com", "content-encoding", "gzip",
               "set-cookie",
               "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 1a7e2442ca..ef2ad66b5c 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -59,9 +59,10 @@ static void assert_index(const grpc_chttp2_hptbl *tbl, uint32_t idx,
 }
 
 static void test_static_lookup(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hptbl tbl;
 
-  grpc_chttp2_hptbl_init(&tbl);
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
 
   LOG_TEST("test_static_lookup");
   assert_index(&tbl, 1, ":authority", "");
@@ -126,7 +127,8 @@ static void test_static_lookup(void) {
   assert_index(&tbl, 60, "via", "");
   assert_index(&tbl, 61, "www-authenticate", "");
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_many_additions(void) {
@@ -137,15 +139,16 @@ static void test_many_additions(void) {
 
   LOG_TEST("test_many_additions");
 
-  grpc_chttp2_hptbl_init(&tbl);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
 
   for (i = 0; i < 100000; i++) {
     grpc_mdelem *elem;
     gpr_asprintf(&key, "K:%d", i);
     gpr_asprintf(&value, "VALUE:%d", i);
-    elem = grpc_mdelem_from_strings(key, value);
-    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-    GRPC_MDELEM_UNREF(elem);
+    elem = grpc_mdelem_from_strings(&exec_ctx, key, value);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+    GRPC_MDELEM_UNREF(&exec_ctx, elem);
     assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
     gpr_free(key);
     gpr_free(value);
@@ -158,19 +161,23 @@ static void test_many_additions(void) {
     }
   }
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static grpc_chttp2_hptbl_find_result find_simple(grpc_chttp2_hptbl *tbl,
                                                  const char *key,
                                                  const char *value) {
-  grpc_mdelem *md = grpc_mdelem_from_strings(key, value);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_mdelem *md = grpc_mdelem_from_strings(&exec_ctx, key, value);
   grpc_chttp2_hptbl_find_result r = grpc_chttp2_hptbl_find(tbl, md);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(&exec_ctx, md);
+  grpc_exec_ctx_finish(&exec_ctx);
   return r;
 }
 
 static void test_find(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hptbl tbl;
   uint32_t i;
   char buffer[32];
@@ -179,16 +186,16 @@ static void test_find(void) {
 
   LOG_TEST("test_find");
 
-  grpc_chttp2_hptbl_init(&tbl);
-  elem = grpc_mdelem_from_strings("abc", "xyz");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
-  elem = grpc_mdelem_from_strings("abc", "123");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
-  elem = grpc_mdelem_from_strings("x", "1");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "abc", "xyz");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "abc", "123");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "x", "1");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
 
   r = find_simple(&tbl, "abc", "123");
   GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY);
@@ -237,9 +244,9 @@ static void test_find(void) {
   /* overflow the string buffer, check find still works */
   for (i = 0; i < 10000; i++) {
     int64_ttoa(i, buffer);
-    elem = grpc_mdelem_from_strings("test", buffer);
-    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-    GRPC_MDELEM_UNREF(elem);
+    elem = grpc_mdelem_from_strings(&exec_ctx, "test", buffer);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+    GRPC_MDELEM_UNREF(&exec_ctx, elem);
   }
 
   r = find_simple(&tbl, "abc", "123");
@@ -267,7 +274,8 @@ static void test_find(void) {
   GPR_ASSERT(r.index != 0);
   GPR_ASSERT(r.has_value == 0);
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index 5c89d8530a..3625043d07 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -42,6 +42,7 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/util/test_config.h"
@@ -63,6 +64,7 @@ static void test_create_string(void) {
   LOG_TEST("test_create_string");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   s1 = grpc_mdstr_from_string("hello");
   s2 = grpc_mdstr_from_string("hello");
   s3 = grpc_mdstr_from_string("very much not hello");
@@ -70,9 +72,10 @@ static void test_create_string(void) {
   GPR_ASSERT(s3 != s1);
   GPR_ASSERT(grpc_slice_str_cmp(s1->slice, "hello") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(s3->slice, "very much not hello") == 0);
-  GRPC_MDSTR_UNREF(s1);
-  GRPC_MDSTR_UNREF(s2);
-  GRPC_MDSTR_UNREF(s3);
+  GRPC_MDSTR_UNREF(&exec_ctx, s1);
+  GRPC_MDSTR_UNREF(&exec_ctx, s2);
+  GRPC_MDSTR_UNREF(&exec_ctx, s3);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -82,9 +85,10 @@ static void test_create_metadata(void) {
   LOG_TEST("test_create_metadata");
 
   grpc_init();
-  m1 = grpc_mdelem_from_strings("a", "b");
-  m2 = grpc_mdelem_from_strings("a", "b");
-  m3 = grpc_mdelem_from_strings("a", "c");
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  m1 = grpc_mdelem_from_strings(&exec_ctx, "a", "b");
+  m2 = grpc_mdelem_from_strings(&exec_ctx, "a", "b");
+  m3 = grpc_mdelem_from_strings(&exec_ctx, "a", "c");
   GPR_ASSERT(m1 == m2);
   GPR_ASSERT(m3 != m1);
   GPR_ASSERT(m3->key == m1->key);
@@ -92,9 +96,10 @@ static void test_create_metadata(void) {
   GPR_ASSERT(grpc_slice_str_cmp(m1->key->slice, "a") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(m1->value->slice, "b") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(m3->value->slice, "c") == 0);
-  GRPC_MDELEM_UNREF(m1);
-  GRPC_MDELEM_UNREF(m2);
-  GRPC_MDELEM_UNREF(m3);
+  GRPC_MDELEM_UNREF(&exec_ctx, m1);
+  GRPC_MDELEM_UNREF(&exec_ctx, m2);
+  GRPC_MDELEM_UNREF(&exec_ctx, m3);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -105,11 +110,14 @@ static void test_create_many_ephemeral_metadata(void) {
   LOG_TEST("test_create_many_ephemeral_metadata");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* add, and immediately delete a bunch of different elements */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer));
+    GRPC_MDELEM_UNREF(&exec_ctx,
+                      grpc_mdelem_from_strings(&exec_ctx, "a", buffer));
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -122,22 +130,24 @@ static void test_create_many_persistant_metadata(void) {
   LOG_TEST("test_create_many_persistant_metadata");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* add phase */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    created[i] = grpc_mdelem_from_strings("a", buffer);
+    created[i] = grpc_mdelem_from_strings(&exec_ctx, "a", buffer);
   }
   /* verify phase */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    md = grpc_mdelem_from_strings("a", buffer);
+    md = grpc_mdelem_from_strings(&exec_ctx, "a", buffer);
     GPR_ASSERT(md == created[i]);
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(&exec_ctx, md);
   }
   /* cleanup phase */
   for (i = 0; i < MANY; i++) {
-    GRPC_MDELEM_UNREF(created[i]);
+    GRPC_MDELEM_UNREF(&exec_ctx, created[i]);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
   gpr_free(created);
@@ -147,9 +157,11 @@ static void test_spin_creating_the_same_thing(void) {
   LOG_TEST("test_spin_creating_the_same_thing");
 
   grpc_init();
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -164,6 +176,7 @@ static void test_things_stick_around(void) {
   LOG_TEST("test_things_stick_around");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   for (i = 0; i < nstrs; i++) {
     gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x", i);
@@ -174,7 +187,7 @@ static void test_things_stick_around(void) {
 
   for (i = 0; i < nstrs; i++) {
     GRPC_MDSTR_REF(strs[i]);
-    GRPC_MDSTR_UNREF(strs[i]);
+    GRPC_MDSTR_UNREF(&exec_ctx, strs[i]);
   }
 
   for (i = 0; i < nstrs; i++) {
@@ -186,17 +199,18 @@ static void test_things_stick_around(void) {
   }
 
   for (i = 0; i < nstrs; i++) {
-    GRPC_MDSTR_UNREF(strs[shuf[i]]);
+    GRPC_MDSTR_UNREF(&exec_ctx, strs[shuf[i]]);
     for (j = i + 1; j < nstrs; j++) {
       gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x",
                    shuf[j]);
       test = grpc_mdstr_from_string(buffer);
       GPR_ASSERT(test == strs[shuf[j]]);
-      GRPC_MDSTR_UNREF(test);
+      GRPC_MDSTR_UNREF(&exec_ctx, test);
       gpr_free(buffer);
     }
   }
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
   gpr_free(strs);
   gpr_free(shuf);
@@ -210,19 +224,21 @@ static void test_slices_work(void) {
   LOG_TEST("test_slices_work");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   str = grpc_mdstr_from_string(
       "123456789012345678901234567890123456789012345678901234567890");
   slice = grpc_slice_ref(str->slice);
-  GRPC_MDSTR_UNREF(str);
-  grpc_slice_unref(slice);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
+  grpc_slice_unref_internal(&exec_ctx, slice);
 
   str = grpc_mdstr_from_string(
       "123456789012345678901234567890123456789012345678901234567890");
   slice = grpc_slice_ref(str->slice);
-  grpc_slice_unref(slice);
-  GRPC_MDSTR_UNREF(str);
+  grpc_slice_unref_internal(&exec_ctx, slice);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -234,13 +250,15 @@ static void test_base64_and_huffman_works(void) {
   LOG_TEST("test_base64_and_huffman_works");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   str = grpc_mdstr_from_string("abcdefg");
   slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
   slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
   GPR_ASSERT(0 == grpc_slice_cmp(slice1, slice2));
 
-  grpc_slice_unref(slice2);
-  GRPC_MDSTR_UNREF(str);
+  grpc_slice_unref_internal(&exec_ctx, slice2);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -251,29 +269,33 @@ static void test_user_data_works(void) {
   LOG_TEST("test_user_data_works");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   ud1 = gpr_malloc(sizeof(int));
   *ud1 = 1;
   ud2 = gpr_malloc(sizeof(int));
   *ud2 = 2;
-  md = grpc_mdelem_from_strings("abc", "123");
+  md = grpc_mdelem_from_strings(&exec_ctx, "abc", "123");
   grpc_mdelem_set_user_data(md, gpr_free, ud1);
   grpc_mdelem_set_user_data(md, gpr_free, ud2);
   GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(&exec_ctx, md);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
-static void verify_ascii_header_size(const char *key, const char *value) {
-  grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+static void verify_ascii_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+                                     const char *value) {
+  grpc_mdelem *elem = grpc_mdelem_from_strings(exec_ctx, key, value);
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   size_t expected_size = 32 + strlen(key) + strlen(value);
   GPR_ASSERT(expected_size == elem_size);
-  GRPC_MDELEM_UNREF(elem);
+  GRPC_MDELEM_UNREF(exec_ctx, elem);
 }
 
-static void verify_binary_header_size(const char *key, const uint8_t *value,
-                                      size_t value_len) {
-  grpc_mdelem *elem = grpc_mdelem_from_string_and_buffer(key, value, value_len);
+static void verify_binary_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const uint8_t *value, size_t value_len) {
+  grpc_mdelem *elem =
+      grpc_mdelem_from_string_and_buffer(exec_ctx, key, value, value_len);
   GPR_ASSERT(grpc_is_binary_header(key, strlen(key)));
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   grpc_slice value_slice =
@@ -281,33 +303,37 @@ static void verify_binary_header_size(const char *key, const uint8_t *value,
   grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
   size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded);
   GPR_ASSERT(expected_size == elem_size);
-  grpc_slice_unref(value_slice);
-  grpc_slice_unref(base64_encoded);
-  GRPC_MDELEM_UNREF(elem);
+  grpc_slice_unref_internal(exec_ctx, value_slice);
+  grpc_slice_unref_internal(exec_ctx, base64_encoded);
+  GRPC_MDELEM_UNREF(exec_ctx, elem);
 }
 
 #define BUFFER_SIZE 64
 static void test_mdelem_sizes_in_hpack(void) {
   LOG_TEST("test_mdelem_size");
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   uint8_t binary_value[BUFFER_SIZE] = {0};
   for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
     binary_value[i] = i;
   }
 
-  verify_ascii_header_size("hello", "world");
-  verify_ascii_header_size("hello", "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-  verify_ascii_header_size(":scheme", "http");
+  verify_ascii_header_size(&exec_ctx, "hello", "world");
+  verify_ascii_header_size(&exec_ctx, "hello",
+                           "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+  verify_ascii_header_size(&exec_ctx, ":scheme", "http");
 
   for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
-    verify_binary_header_size("hello-bin", binary_value, i);
+    verify_binary_header_size(&exec_ctx, "hello-bin", binary_value, i);
   }
 
   const char *static_metadata = grpc_static_metadata_strings[0];
   memcpy(binary_value, static_metadata, strlen(static_metadata));
-  verify_binary_header_size("hello-bin", binary_value, strlen(static_metadata));
+  verify_binary_header_size(&exec_ctx, "hello-bin", binary_value,
+                            strlen(static_metadata));
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
-- 
GitLab


From 18b4ba34b3a10816d6e336d3b3572515554386cb Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 9 Nov 2016 15:23:42 -0800
Subject: [PATCH 029/344] Enable sanity check

---
 src/core/ext/lb_policy/grpclb/grpclb.c    | 7 ++++---
 src/core/lib/channel/http_server_filter.c | 2 +-
 tools/run_tests/sanity/sanity_tests.yaml  | 2 ++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index c81c0fb332..a85c16b881 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -116,6 +116,7 @@
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/backoff.h"
 #include "src/core/lib/support/string.h"
@@ -975,7 +976,7 @@ static void lb_call_init(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy) {
   grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
   glb_policy->lb_request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  grpc_slice_unref(request_payload_slice);
+  grpc_slice_unref_internal(exec_ctx, request_payload_slice);
   grpc_grpclb_request_destroy(request);
 
   glb_policy->lb_call_status_details = NULL;
@@ -1093,7 +1094,7 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
         grpc_grpclb_response_parse_serverlist(response_slice);
     if (serverlist != NULL) {
       GPR_ASSERT(glb_policy->lb_call != NULL);
-      grpc_slice_unref(response_slice);
+      grpc_slice_unref_internal(exec_ctx, response_slice);
       if (grpc_lb_glb_trace) {
         gpr_log(GPR_INFO, "Serverlist with %lu servers received",
                 (unsigned long)serverlist->num_servers);
@@ -1136,7 +1137,7 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
     } else { /* serverlist == NULL */
       gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
               grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
-      grpc_slice_unref(response_slice);
+      grpc_slice_unref_internal(exec_ctx, response_slice);
     }
 
     if (!glb_policy->shutting_down) {
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index da31176ce9..cb0fe230cf 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -324,7 +324,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->read_slice_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer);
 }
 
 /* Constructor for channel_data */
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 32e62dd529..37819166e3 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -3,6 +3,7 @@
 - script: tools/run_tests/sanity/check_sources_and_headers.py
 - script: tools/run_tests/sanity/check_submodules.sh
 - script: tools/run_tests/sanity/check_test_filtering.py
+- script: tools/run_tests/sanity/core_banned_functions.py
 - script: tools/buildgen/generate_projects.sh -j 3
   cpu_cost: 3
 - script: tools/distrib/check_copyright.py
@@ -12,3 +13,4 @@
 - script: tools/distrib/check_nanopb_output.sh
 - script: tools/distrib/check_include_guards.py
 - script: tools/distrib/python/check_grpcio_tools.py
+
-- 
GitLab


From 7cdad96fc49090eb5e3a12a7cca5a9f257d3f301 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 10 Nov 2016 08:37:21 -0800
Subject: [PATCH 030/344] Fix foward declaration duplication

---
 BUILD                                         |   9 +
 CMakeLists.txt                                |   7 +
 Makefile                                      |  13 +-
 build.yaml                                    |   1 +
 gRPC-Core.podspec                             |   2 +
 grpc.gemspec                                  |   2 +
 include/grpc/impl/codegen/exec_ctx_fwd.h      |  41 +
 include/grpc/impl/codegen/slice.h             |   2 +-
 package.xml                                   |   2 +
 src/core/lib/iomgr/closure.h                  |   6 +-
 .../core/surface/public_headers_must_be_c89.c |   1 +
 tools/doxygen/Doxyfile.c++                    |   1 +
 tools/doxygen/Doxyfile.c++.internal           |   1 +
 tools/doxygen/Doxyfile.core                   |   2 +
 tools/doxygen/Doxyfile.core.internal          |   2 +
 tools/run_tests/sources_and_headers.json      |   4 +
 tools/run_tests/tests.json                    | 891 ++++++++++--------
 vsprojects/vcxproj/gpr/gpr.vcxproj            |   1 +
 vsprojects/vcxproj/gpr/gpr.vcxproj.filters    |   3 +
 vsprojects/vcxproj/grpc++/grpc++.vcxproj      |   1 +
 .../vcxproj/grpc++/grpc++.vcxproj.filters     |   3 +
 .../grpc++_test_util/grpc++_test_util.vcxproj |   1 +
 .../grpc++_test_util.vcxproj.filters          |   3 +
 .../grpc++_unsecure/grpc++_unsecure.vcxproj   |   1 +
 .../grpc++_unsecure.vcxproj.filters           |   3 +
 vsprojects/vcxproj/grpc/grpc.vcxproj          |   1 +
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters  |   3 +
 .../grpc_test_util/grpc_test_util.vcxproj     |   1 +
 .../grpc_test_util.vcxproj.filters            |   3 +
 .../grpc_unsecure/grpc_unsecure.vcxproj       |   1 +
 .../grpc_unsecure.vcxproj.filters             |   3 +
 .../codegen_test_full.vcxproj                 |   1 +
 .../codegen_test_full.vcxproj.filters         |   3 +
 .../codegen_test_minimal.vcxproj              |   1 +
 .../codegen_test_minimal.vcxproj.filters      |   3 +
 .../end2end_nosec_tests.vcxproj               |   2 +
 .../end2end_nosec_tests.vcxproj.filters       |   3 +
 .../tests/end2end_tests/end2end_tests.vcxproj |   2 +
 .../end2end_tests.vcxproj.filters             |   3 +
 .../grpc_tool_test/grpc_tool_test.vcxproj     |   1 +
 .../grpc_tool_test.vcxproj.filters            |   3 +
 41 files changed, 619 insertions(+), 418 deletions(-)
 create mode 100644 include/grpc/impl/codegen/exec_ctx_fwd.h

diff --git a/BUILD b/BUILD
index 894c7b2c6d..ec561f5856 100644
--- a/BUILD
+++ b/BUILD
@@ -135,6 +135,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -560,6 +561,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -954,6 +956,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1331,6 +1334,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1486,6 +1490,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1630,6 +1635,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1795,6 +1801,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1957,6 +1964,7 @@ objc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -2221,6 +2229,7 @@ objc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98d54f2198..9b219e9dc0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -258,6 +258,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -535,6 +536,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -785,6 +787,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1034,6 +1037,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1197,6 +1201,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1355,6 +1360,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1551,6 +1557,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
diff --git a/Makefile b/Makefile
index 5b0dc44699..40c10b6050 100644
--- a/Makefile
+++ b/Makefile
@@ -2544,6 +2544,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -2849,6 +2850,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3118,6 +3120,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3334,6 +3337,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3622,6 +3626,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3866,6 +3871,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4053,6 +4059,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4398,6 +4405,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4576,6 +4584,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -6970,6 +6979,7 @@ endif
 LIBEND2END_TESTS_SRC = \
     test/core/end2end/end2end_tests.c \
     test/core/end2end/end2end_test_utils.c \
+    test/core/end2end/tests/authority_not_supported.c \
     test/core/end2end/tests/bad_hostname.c \
     test/core/end2end/tests/binary_metadata.c \
     test/core/end2end/tests/call_creds.c \
@@ -7015,7 +7025,6 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
-    test/core/end2end/tests/authority_not_supported.c \
 
 PUBLIC_HEADERS_C += \
 
@@ -7056,6 +7065,7 @@ endif
 LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/end2end_nosec_tests.c \
     test/core/end2end/end2end_test_utils.c \
+    test/core/end2end/tests/authority_not_supported.c \
     test/core/end2end/tests/bad_hostname.c \
     test/core/end2end/tests/binary_metadata.c \
     test/core/end2end/tests/cancel_after_accept.c \
@@ -7100,7 +7110,6 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
-    test/core/end2end/tests/authority_not_supported.c \
 
 PUBLIC_HEADERS_C += \
 
diff --git a/build.yaml b/build.yaml
index e8e5c4b5ee..2134860c6b 100644
--- a/build.yaml
+++ b/build.yaml
@@ -144,6 +144,7 @@ filegroups:
   - include/grpc/impl/codegen/atm_gcc_atomic.h
   - include/grpc/impl/codegen/atm_gcc_sync.h
   - include/grpc/impl/codegen/atm_windows.h
+  - include/grpc/impl/codegen/exec_ctx_fwd.h
   - include/grpc/impl/codegen/gpr_types.h
   - include/grpc/impl/codegen/port_platform.h
   - include/grpc/impl/codegen/slice.h
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 8869bec32e..1a1b9fc86b 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -146,6 +146,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
                       'include/grpc/impl/codegen/atm_windows.h',
+                      'include/grpc/impl/codegen/exec_ctx_fwd.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
@@ -172,6 +173,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
                       'include/grpc/impl/codegen/atm_windows.h',
+                      'include/grpc/impl/codegen/exec_ctx_fwd.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index b071fccb82..9832bb5ce6 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -74,6 +74,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+  s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -156,6 +157,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+  s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
diff --git a/include/grpc/impl/codegen/exec_ctx_fwd.h b/include/grpc/impl/codegen/exec_ctx_fwd.h
new file mode 100644
index 0000000000..6dff2d248c
--- /dev/null
+++ b/include/grpc/impl/codegen/exec_ctx_fwd.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_EXEC_CTX_H
+#define GRPC_EXEC_CTX_H
+
+/* forward declaration for exec_ctx.h */
+struct grpc_exec_ctx;
+typedef struct grpc_exec_ctx grpc_exec_ctx;
+
+#endif
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index ef60ce1220..4d4a86fa22 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,7 +37,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-typedef struct grpc_exec_ctx grpc_exec_ctx;
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 
 /* Slice API
 
diff --git a/package.xml b/package.xml
index 348ad5f23c..c5b55b8966 100644
--- a/package.xml
+++ b/package.xml
@@ -81,6 +81,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -163,6 +164,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2b4b271eaa..ec0114a2a4 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -35,6 +35,8 @@
 #define GRPC_CORE_LIB_IOMGR_CLOSURE_H
 
 #include <grpc/support/port_platform.h>
+
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <stdbool.h>
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/support/mpscq.h"
@@ -42,10 +44,6 @@
 struct grpc_closure;
 typedef struct grpc_closure grpc_closure;
 
-/* forward declaration for exec_ctx.h */
-struct grpc_exec_ctx;
-typedef struct grpc_exec_ctx grpc_exec_ctx;
-
 typedef struct grpc_closure_list {
   grpc_closure *head;
   grpc_closure *tail;
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index d4cfa25d44..610495377c 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -42,6 +42,7 @@
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/impl/codegen/port_platform.h>
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index ff3a0e381d..62d6e794f9 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 04e8f4e7f2..52c406cba8 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 1e748ba4a8..4a1378eeaa 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -818,6 +819,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 55b8d40aca..2be24683ef 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -1208,6 +1209,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 3cc33ae5d2..a4fd5b8f94 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6257,6 +6257,7 @@
       "test/core/end2end/end2end_test_utils.c", 
       "test/core/end2end/end2end_tests.c", 
       "test/core/end2end/end2end_tests.h", 
+      "test/core/end2end/tests/authority_not_supported.c", 
       "test/core/end2end/tests/bad_hostname.c", 
       "test/core/end2end/tests/binary_metadata.c", 
       "test/core/end2end/tests/call_creds.c", 
@@ -6325,6 +6326,7 @@
       "test/core/end2end/end2end_nosec_tests.c", 
       "test/core/end2end/end2end_test_utils.c", 
       "test/core/end2end/end2end_tests.h", 
+      "test/core/end2end/tests/authority_not_supported.c", 
       "test/core/end2end/tests/bad_hostname.c", 
       "test/core/end2end/tests/binary_metadata.c", 
       "test/core/end2end/tests/cancel_after_accept.c", 
@@ -6569,6 +6571,7 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_windows.h", 
+      "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
@@ -6585,6 +6588,7 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_windows.h", 
+      "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 47df78ead1..366e944357 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -4975,6 +4975,29 @@
       "windows"
     ]
   }, 
+  {
+    "args": [
+      "authority_not_supported"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -6015,25 +6038,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],    
+    ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "mac", 
       "posix"
-    ],    
-    "cpu_cost": 1.0,  
+    ], 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
+    "exclude_iomgrs": [], 
     "flaky": false, 
-    "language": "c",  
-    "name": "h2_census_test", 
+    "language": "c", 
+    "name": "h2_compress_test", 
     "platforms": [
       "windows", 
       "linux", 
       "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -7074,25 +7098,25 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_compress_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -8088,24 +8112,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_fakesec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -9029,23 +9055,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_fd_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
     "platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -10086,25 +10115,22 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
-      "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full_test",
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
-      "posix"
+      "linux"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -10963,19 +10989,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "linux"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full+pipe_test",
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
     "platforms": [
-      "linux"
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -11970,25 +12003,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full+trace_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -13072,24 +13107,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_http_proxy_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -14130,25 +14167,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_load_reporting_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -15232,24 +15271,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_oauth2_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -16165,24 +16207,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_proxy_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -17146,24 +17191,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -18055,24 +18103,29 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair+trace_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -19090,24 +19143,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair_1byte_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -20148,25 +20203,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_ssl_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -21207,25 +21263,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_ssl_cert_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -22141,24 +22199,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_ssl_proxy_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -23174,23 +23234,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_uds_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
     "platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -24208,25 +24271,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_census_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -25244,25 +25308,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_compress_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -26163,23 +26228,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_fd_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
     "platforms": [
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -27197,25 +27265,22 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
-      "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full_nosec_test",
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
-      "posix"
+      "linux"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -28055,19 +28120,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "linux"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full+pipe_nosec_test",
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
     "platforms": [
-      "linux"
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -29039,25 +29111,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_full+trace_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -30117,24 +30191,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_http_proxy_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -31152,25 +31228,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_load_reporting_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -32062,24 +32140,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_proxy_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -33019,24 +33100,27 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -33904,24 +33988,29 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "windows", 
+      "linux", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair+trace_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "windows", 
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -34913,26 +35002,26 @@
   {
     "args": [
       "authority_not_supported"
-    ],
+    ], 
     "ci_platforms": [
-      "windows",
-      "linux",
+      "linux", 
+      "mac", 
       "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [
-      "msan"
-    ],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_sockpair_1byte_nosec_test",
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
     "platforms": [
-      "windows",
-      "linux",
-      "mac",
+      "linux", 
+      "mac", 
       "posix"
     ]
-  },
+  }, 
   {
     "args": [
       "bad_hostname"
@@ -35922,26 +36011,6 @@
       "posix"
     ]
   }, 
-  {
-    "args": [
-      "authority_not_supported"
-    ],
-    "ci_platforms": [
-      "linux",
-      "mac",
-      "posix"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "flaky": false,
-    "language": "c",
-    "name": "h2_uds_nosec_test",
-    "platforms": [
-      "linux",
-      "mac",
-      "posix"
-    ]
-  },
   {
     "args": [
       "--scenarios_json", 
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index ce593473c0..f87e9be543 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -177,6 +177,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index a50a9f4200..ffa89d77cc 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -225,6 +225,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index f281db72b6..3dd4da1e01 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index f359e4ef31..f589efbf55 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -354,6 +354,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index d2305b2e25..75997b6498 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -185,6 +185,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index d1aaba7092..421ab760b3 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -147,6 +147,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 1511a2cfe4..a11510e360 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index bed77b25a4..747f1ca71b 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -339,6 +339,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index c608cb8943..09c96b5dbd 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -286,6 +286,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index c6ca85cab6..0172458e50 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -699,6 +699,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 764f4615b6..81e4b3613a 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -166,6 +166,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 2b72043001..66802c17ab 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -456,6 +456,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index ed68f03ad5..2e40335a2a 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -277,6 +277,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index e8c16e531f..7f96adddd0 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -615,6 +615,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index a2b2a1dfa0..8e4c71fc3f 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -198,6 +198,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index 94b6c2530e..cc0286af9f 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -135,6 +135,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 1a3c157983..1a6829b09f 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -198,6 +198,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index 1f4b60ca4d..bfe435aa04 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -138,6 +138,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
index 3d510d5156..954ac21b49 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
@@ -155,6 +155,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\end2end_test_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\authority_not_supported.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
index a0b01ddbc8..b2747d2578 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
@@ -7,6 +7,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\end2end_test_utils.c">
       <Filter>test\core\end2end</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\authority_not_supported.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
index 5699e8308e..51b744bc21 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -155,6 +155,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\end2end_test_utils.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\authority_not_supported.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\binary_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
index bfb5e2b229..33e7098ecf 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
@@ -7,6 +7,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\end2end_test_utils.c">
       <Filter>test\core\end2end</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\authority_not_supported.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\bad_hostname.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index 1e3cc3ca04..ea33eef9b4 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -199,6 +199,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 1c308c5881..6cd6b07394 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -129,6 +129,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-- 
GitLab


From 59af1bf4689d2992d23e0493465caec455bd05b2 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Fri, 28 Oct 2016 10:29:43 -0700
Subject: [PATCH 031/344] Update messages.proto and add a new test

---
 src/objective-c/tests/InteropTests.m          | 48 +++++++++++++
 .../tests/RemoteTestClient/messages.proto     | 71 ++++++++++++++++---
 2 files changed, 110 insertions(+), 9 deletions(-)

diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index f04a7e6441..f38e703005 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -321,6 +321,54 @@
   [self waitForExpectationsWithTimeout:4 handler:nil];
 }
 
+- (void)testErroneousPingPongRPC {
+  XCTAssertNotNil(self.class.host);
+  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
+
+  NSArray *requests = @[@27182, @8, @1828, @45904];
+  NSArray *responses = @[@31415, @9, @2653, @58979];
+
+  GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
+
+  __block int index = 0;
+
+  RMTStreamingOutputCallRequest *request =
+      [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+                                      requestedResponseSize:responses[index]];
+
+  [requestsBuffer writeValue:request];
+
+  [_service fullDuplexCallWithRequestsWriter:requestsBuffer
+                                eventHandler:^(BOOL done,
+                                               RMTStreamingOutputCallResponse *response,
+                                               NSError *error) {
+      if (index == 0) {
+        XCTAssertNil(error, @"Finished with unexpected error: %@", error);
+        XCTAssertNotNil(response, @"Event handler called without an event.");
+        XCTAssertFalse(done);
+
+        id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]];
+        XCTAssertEqualObjects(response, expected);
+        index += 1;
+
+        RMTStreamingOutputCallRequest *request =
+        [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+                                        requestedResponseSize:responses[index]];
+        RMTEchoStatus *status = [RMTEchoStatus message];
+        status.code = 7;
+        status.message = @"Error message!";
+        request.responseStatus = status;
+        [requestsBuffer writeValue:request];
+      } else {
+        XCTAssertNil(response);
+        XCTAssertNotNil(error);
+
+        [expectation fulfill];
+      }
+  }];
+  [self waitForExpectationsWithTimeout:4 handler:nil];
+}
+
 #ifndef GRPC_COMPILE_WITH_CRONET
 // TODO(makdharma@): Fix this test
 - (void)testEmptyStreamRPC {
diff --git a/src/objective-c/tests/RemoteTestClient/messages.proto b/src/objective-c/tests/RemoteTestClient/messages.proto
index 85d93c2ff9..b8b8b668d0 100644
--- a/src/objective-c/tests/RemoteTestClient/messages.proto
+++ b/src/objective-c/tests/RemoteTestClient/messages.proto
@@ -1,4 +1,5 @@
-// Copyright 2015, Google Inc.
+
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -35,34 +36,45 @@ package grpc.testing;
 
 option objc_class_prefix = "RMT";
 
+// 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";
+message BoolValue {
+  // The bool value.
+  bool value = 1;
+}
+
+// DEPRECATED, don't use. To be removed shortly.
 // The type of payload that should be returned.
 enum PayloadType {
   // Compressable text format.
   COMPRESSABLE = 0;
-
-  // Uncompressable binary format.
-  UNCOMPRESSABLE = 1;
-
-  // Randomly chosen from all other formats defined in this enum.
-  RANDOM = 2;
 }
 
 // A block of data, to simply increase gRPC message size.
 message Payload {
+  // DEPRECATED, don't use. To be removed shortly.
   // The type of data in body.
   PayloadType type = 1;
   // Primary contents of payload.
   bytes body = 2;
 }
 
+// A protobuf representation for grpc status. This is used by test
+// clients to specify a status that the server should attempt to return.
+message EchoStatus {
+  int32 code = 1;
+  string message = 2;
+}
+
 // Unary request.
 message SimpleRequest {
+  // 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.
   PayloadType response_type = 1;
 
   // Desired payload size in the response from the server.
-  // If response_type is COMPRESSABLE, this denotes the size before compression.
   int32 response_size = 2;
 
   // Optional input payload sent along with the request.
@@ -73,6 +85,18 @@ message SimpleRequest {
 
   // Whether SimpleResponse should include OAuth scope.
   bool fill_oauth_scope = 5;
+
+  // 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.
+  BoolValue response_compressed = 6;
+
+  // Whether server should return a given status
+  EchoStatus response_status = 7;
+
+  // Whether the server should expect this request to be compressed.
+  BoolValue expect_compressed = 8;
 }
 
 // Unary response, as configured by the request.
@@ -91,6 +115,12 @@ message StreamingInputCallRequest {
   // Optional input payload sent along with the request.
   Payload payload = 1;
 
+  // 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.
+  BoolValue expect_compressed = 2;
+
   // Not expecting any payload from the response.
 }
 
@@ -103,16 +133,22 @@ message StreamingInputCallResponse {
 // Configuration for a particular response.
 message ResponseParameters {
   // Desired payload sizes in responses from the server.
-  // If response_type is COMPRESSABLE, this denotes the size before compression.
   int32 size = 1;
 
   // Desired interval between consecutive responses in the response stream in
   // microseconds.
   int32 interval_us = 2;
+
+  // 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.
+  BoolValue compressed = 3;
 }
 
 // Server-streaming request.
 message StreamingOutputCallRequest {
+  // 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
@@ -124,6 +160,9 @@ message StreamingOutputCallRequest {
 
   // Optional input payload sent along with the request.
   Payload payload = 3;
+
+  // Whether server should return a given status
+  EchoStatus response_status = 7;
 }
 
 // Server-streaming response, as configured by the request and parameters.
@@ -131,3 +170,17 @@ message StreamingOutputCallResponse {
   // Payload to increase response size.
   Payload payload = 1;
 }
+
+// For reconnect interop test only.
+// Client tells server what reconnection parameters it used.
+message ReconnectParams {
+  int32 max_reconnect_backoff_ms = 1;
+}
+
+// For reconnect interop test only.
+// Server tells client whether its reconnects are following the spec and the
+// reconnect backoffs it saw.
+message ReconnectInfo {
+  bool passed = 1;
+  repeated int32 backoff_ms = 2;
+}
-- 
GitLab


From 14fe5187babcea2117d680ed212e92e6c6107bbc Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Thu, 10 Nov 2016 17:20:29 -0800
Subject: [PATCH 032/344] tests hacks

---
 src/core/ext/transport/chttp2/transport/writing.c |  4 ++--
 src/objective-c/tests/InteropTests.m              | 13 +++++--------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index e0d87725e9..cef4fe3ee6 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -301,10 +301,10 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
             &transport_writing->outbuf);
       }
       if (!transport_writing->is_client && !stream_writing->read_closed) {
-        gpr_slice_buffer_add(&transport_writing->outbuf,
+/*        gpr_slice_buffer_add(&transport_writing->outbuf,
                              grpc_chttp2_rst_stream_create(
                                  stream_writing->id, GRPC_CHTTP2_NO_ERROR,
-                                 &stream_writing->stats));
+                                 &stream_writing->stats)); */
       }
       stream_writing->send_trailing_metadata = NULL;
       stream_writing->sent_trailing_metadata = 1;
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index f38e703005..add63614e7 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -325,16 +325,13 @@
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
 
-  NSArray *requests = @[@27182, @8, @1828, @45904];
-  NSArray *responses = @[@31415, @9, @2653, @58979];
-
   GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
 
   __block int index = 0;
 
   RMTStreamingOutputCallRequest *request =
-      [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
-                                      requestedResponseSize:responses[index]];
+      [RMTStreamingOutputCallRequest messageWithPayloadSize:@256
+                                      requestedResponseSize:@256];
 
   [requestsBuffer writeValue:request];
 
@@ -347,13 +344,13 @@
         XCTAssertNotNil(response, @"Event handler called without an event.");
         XCTAssertFalse(done);
 
-        id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]];
+        id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:@256];
         XCTAssertEqualObjects(response, expected);
         index += 1;
 
         RMTStreamingOutputCallRequest *request =
-        [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
-                                        requestedResponseSize:responses[index]];
+        [RMTStreamingOutputCallRequest messageWithPayloadSize:@256
+                                        requestedResponseSize:@0];
         RMTEchoStatus *status = [RMTEchoStatus message];
         status.code = 7;
         status.message = @"Error message!";
-- 
GitLab


From e10c33381910c30cb2f94d63a258e9d06bfedc0c Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Fri, 11 Nov 2016 16:23:15 -0800
Subject: [PATCH 033/344] Send reset from the client when server closes stream
 unexpectedly

---
 src/core/ext/transport/chttp2/transport/parsing.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index e1fc0ddee2..6e86431b1c 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -253,8 +253,16 @@ void grpc_chttp2_publish_reads(
     }
 
     if (stream_parsing->received_close) {
-      grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
-                                     1, 0, GRPC_ERROR_NONE);
+      if (transport_global->is_client && !stream_global->write_closed) {
+        gpr_slice_buffer_add(&transport_global->qbuf,
+                             grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, GRPC_CHTTP2_NO_ERROR, &stream_parsing->stats.outgoing));
+        grpc_chttp2_initiate_write(exec_ctx, transport_global, false, "rst");
+        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
+                                       1, 1, GRPC_ERROR_NONE);
+      } else {
+        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
+                                       1, 0, GRPC_ERROR_NONE);
+      }
     }
   }
 }
-- 
GitLab


From 2ac52edbfe5c82a4693ab6cc72af404d108f6b01 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 1 Nov 2016 11:48:46 -0700
Subject: [PATCH 034/344] Ensure something executes the new rst_stream code

---
 .../server_hanging_response_1_header          | Bin 0 -> 18 bytes
 .../server_hanging_response_2_header2         | Bin 0 -> 27 bytes
 ..._client_examples_of_bad_closing_streams.py |  49 ++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header
 create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2
 create mode 100755 test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py

diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header b/test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header
new file mode 100644
index 0000000000000000000000000000000000000000..d2abd17464c60ac237e196886d309bba43a7014b
GIT binary patch
literal 18
ScmZQzU|?Z@0!CIKgAo7#ZU77b

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2
new file mode 100644
index 0000000000000000000000000000000000000000..752af468ba6f8c6b1a9bd95cc082ebed73cc3b6a
GIT binary patch
literal 27
VcmZQzU|?Z@0!9#v5rkPm1ONc+01^NI

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py b/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py
new file mode 100755
index 0000000000..d80c1e0442
--- /dev/null
+++ b/test/core/end2end/fuzzers/generate_client_examples_of_bad_closing_streams.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python2.7
+# 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.
+
+import os
+import sys
+
+os.chdir(os.path.dirname(sys.argv[0]))
+
+streams = {
+  'server_hanging_response_1_header': (
+    [0,0,0,4,0,0,0,0,0] + # settings frame
+    [0,0,0,1,5,0,0,0,1] # trailers
+  ),
+  'server_hanging_response_2_header2': (
+    [0,0,0,4,0,0,0,0,0] + # settings frame
+    [0,0,0,1,4,0,0,0,1] + # headers
+    [0,0,0,1,5,0,0,0,1] # trailers
+  ),
+}
+
+for name, stream in streams.items():
+  open('client_fuzzer_corpus/%s' % name, 'w').write(bytearray(stream))
-- 
GitLab


From 10790401dd7f1faa4aa2ab5d4801b91d788d3e2d Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 1 Nov 2016 13:25:04 -0700
Subject: [PATCH 035/344] Missed file

---
 tools/run_tests/tests.json | 44 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 88869e6497..5ed5a0ebbc 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -62714,6 +62714,50 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/settings_frame_1.bin"
-- 
GitLab


From 72541d08fd71c6fdf0cac94a83929231de93cc6e Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Fri, 11 Nov 2016 17:14:44 -0800
Subject: [PATCH 036/344] undo test hack

---
 src/core/ext/transport/chttp2/transport/writing.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index cef4fe3ee6..e0d87725e9 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -301,10 +301,10 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
             &transport_writing->outbuf);
       }
       if (!transport_writing->is_client && !stream_writing->read_closed) {
-/*        gpr_slice_buffer_add(&transport_writing->outbuf,
+        gpr_slice_buffer_add(&transport_writing->outbuf,
                              grpc_chttp2_rst_stream_create(
                                  stream_writing->id, GRPC_CHTTP2_NO_ERROR,
-                                 &stream_writing->stats)); */
+                                 &stream_writing->stats));
       }
       stream_writing->send_trailing_metadata = NULL;
       stream_writing->sent_trailing_metadata = 1;
-- 
GitLab


From d5a7a8a61eb3c1d5759f79c9cb4667a4d2df0d25 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 14 Nov 2016 07:41:18 -0800
Subject: [PATCH 037/344] Add missing function

---
 src/core/lib/support/string.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index cafeb4364d..4db3f9a66c 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -267,5 +267,28 @@ int gpr_stricmp(const char *a, const char *b) {
   return ca - cb;
 }
 
+static void add_string_to_split(const char *beg, const char *end, char ***strs,
+                                size_t *nstrs, size_t *capstrs) {
+  char *out = gpr_malloc((size_t)(end - beg) + 1);
+  memcpy(out, beg, end - beg);
+  out[end - beg] = 0;
+  if (*nstrs == *capstrs) {
+    *capstrs = GPR_MAX(8, 2 * *capstrs);
+    *strs = gpr_realloc(*strs, sizeof(*strs) * *capstrs);
+  }
+  (*strs)[*nstrs] = out;
+  ++*nstrs;
+}
+
 void gpr_string_split(const char *input, const char *sep, char ***strs,
-                      size_t *nstrs) {}
+                      size_t *nstrs) {
+  char *next;
+  *strs = NULL;
+  *nstrs = 0;
+  size_t capstrs = 0;
+  while ((next = strstr(input, sep))) {
+    add_string_to_split(input, next, strs, nstrs, &capstrs);
+    input = next + strlen(sep);
+  }
+  add_string_to_split(input, input + strlen(input), strs, nstrs, &capstrs);
+}
-- 
GitLab


From 3cf79228ffcdd5c867b4067d6f6a5743a14d3ff1 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 14 Nov 2016 08:02:45 -0800
Subject: [PATCH 038/344] Review feedback

---
 include/grpc/impl/codegen/grpc_types.h             |  4 ++--
 src/core/lib/iomgr/executor.h                      |  2 +-
 src/core/lib/iomgr/iomgr.c                         | 12 +++++-------
 src/core/lib/iomgr/iomgr.h                         |  6 ++++--
 .../lib/security/credentials/jwt/jwt_verifier.c    | 10 ++++++----
 .../lib/security/credentials/jwt/jwt_verifier.h    |  3 ++-
 src/core/lib/slice/slice_buffer.c                  |  5 +----
 src/core/lib/surface/init.c                        |  4 ++--
 test/core/internal_api_canaries/iomgr.c            |  4 ++--
 test/core/iomgr/fd_conservation_posix_test.c       |  6 +++++-
 test/core/iomgr/fd_posix_test.c                    |  5 +++--
 test/core/iomgr/resolve_address_test.c             |  8 ++++++--
 test/core/iomgr/udp_server_test.c                  |  2 +-
 test/core/security/jwt_verifier_test.c             | 14 +++++++-------
 test/core/security/verify_jwt.c                    |  4 ++--
 tools/run_tests/sanity/core_banned_functions.py    | 13 ++++++-------
 16 files changed, 55 insertions(+), 47 deletions(-)

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index e8472fba46..a44358f020 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -34,10 +34,10 @@
 #ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 #define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/slice.h>
-
-#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/status.h>
 
 #include <stddef.h>
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index da9dcd07d0..7bf8f21940 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -48,6 +48,6 @@ void grpc_executor_init();
 void grpc_executor_push(grpc_closure *closure, grpc_error *error);
 
 /** Shutdown the executor, running all pending work as part of the call */
-void grpc_executor_shutdown();
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx);
 
 #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c
index 4fd83e0b22..8a233d0ba8 100644
--- a/src/core/lib/iomgr/iomgr.c
+++ b/src/core/lib/iomgr/iomgr.c
@@ -83,11 +83,10 @@ static void dump_objects(const char *kind) {
   }
 }
 
-void grpc_iomgr_shutdown(void) {
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) {
   gpr_timespec shutdown_deadline = gpr_time_add(
       gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
   gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   grpc_iomgr_platform_flush();
 
@@ -104,10 +103,9 @@ void grpc_iomgr_shutdown(void) {
       }
       last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
     }
-    if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC),
-                         NULL)) {
+    if (grpc_timer_check(exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL)) {
       gpr_mu_unlock(&g_mu);
-      grpc_exec_ctx_flush(&exec_ctx);
+      grpc_exec_ctx_flush(exec_ctx);
       gpr_mu_lock(&g_mu);
       continue;
     }
@@ -138,8 +136,8 @@ void grpc_iomgr_shutdown(void) {
   }
   gpr_mu_unlock(&g_mu);
 
-  grpc_timer_list_shutdown(&exec_ctx);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_timer_list_shutdown(exec_ctx);
+  grpc_exec_ctx_flush(exec_ctx);
 
   /* ensure all threads have left g_mu */
   gpr_mu_lock(&g_mu);
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index c1cfaf302e..245a1e08aa 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -34,12 +34,14 @@
 #ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H
 #define GRPC_CORE_LIB_IOMGR_IOMGR_H
 
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include "src/core/lib/iomgr/port.h"
 
 /** Initializes the iomgr. */
 void grpc_iomgr_init(void);
 
-/** Signals the intention to shutdown the iomgr. */
-void grpc_iomgr_shutdown(void);
+/** Signals the intention to shutdown the iomgr. Expects to be able to flush
+ * exec_ctx. */
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx);
 
 #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 0281db385b..71febc248a 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -629,7 +629,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
 end:
   if (json != NULL) grpc_json_destroy(json);
   if (verification_key != NULL) EVP_PKEY_free(verification_key);
-  ctx->user_cb(ctx->user_data, status, claims);
+  ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
   verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
@@ -682,7 +682,8 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
 
 error:
   if (json != NULL) grpc_json_destroy(json);
-  ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
+  ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+               NULL);
   verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
@@ -793,7 +794,8 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
   return;
 
 error:
-  ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
+  ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+               NULL);
   verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
@@ -844,7 +846,7 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
 error:
   if (header != NULL) jose_header_destroy(exec_ctx, header);
   if (claims != NULL) grpc_jwt_claims_destroy(exec_ctx, claims);
-  cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
+  cb(exec_ctx, user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
 }
 
 grpc_jwt_verifier *grpc_jwt_verifier_create(
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index c084575bcf..b79f411903 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -115,7 +115,8 @@ void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier);
    is done (maybe in another thread).
    It is the responsibility of the callee to call grpc_jwt_claims_destroy on
    the claims. */
-typedef void (*grpc_jwt_verification_done_cb)(void *user_data,
+typedef void (*grpc_jwt_verification_done_cb)(grpc_exec_ctx *exec_ctx,
+                                              void *user_data,
                                               grpc_jwt_verifier_status status,
                                               grpc_jwt_claims *claims);
 
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 872bd10a09..08eaf4963a 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -75,10 +75,7 @@ void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
 
 void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
-  if (sb->slices != sb->inlined) {
-    gpr_free(sb->slices);
-  }
+  grpc_slice_buffer_destroy_internal(&exec_ctx, sb);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index d3b602cf2a..e20e602547 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -227,9 +227,9 @@ void grpc_shutdown(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_mu_lock(&g_init_mu);
   if (--g_initializations == 0) {
-    grpc_executor_shutdown();
+    grpc_executor_shutdown(&exec_ctx);
     grpc_cq_global_shutdown();
-    grpc_iomgr_shutdown();
+    grpc_iomgr_shutdown(&exec_ctx);
     gpr_timers_global_destroy();
     grpc_tracer_shutdown();
     for (i = g_number_of_plugins; i >= 0; i--) {
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
index f1efa87a69..18bc7b5938 100644
--- a/test/core/internal_api_canaries/iomgr.c
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -48,7 +48,7 @@
 static void test_code(void) {
   /* iomgr.h */
   grpc_iomgr_init();
-  grpc_iomgr_shutdown();
+  grpc_iomgr_shutdown(NULL);
 
   /* closure.h */
   grpc_closure closure;
@@ -99,7 +99,7 @@ static void test_code(void) {
   /* executor.h */
   grpc_executor_init();
   grpc_executor_push(&closure, GRPC_ERROR_CREATE("Phi"));
-  grpc_executor_shutdown();
+  grpc_executor_shutdown(NULL);
 
   /* pollset.h */
   grpc_pollset_size();
diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c
index 652b37eb6f..3dffa02c3c 100644
--- a/test/core/iomgr/fd_conservation_posix_test.c
+++ b/test/core/iomgr/fd_conservation_posix_test.c
@@ -65,6 +65,10 @@ int main(int argc, char **argv) {
 
   grpc_resource_quota_unref(resource_quota);
 
-  grpc_iomgr_shutdown();
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_iomgr_shutdown(&exec_ctx);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return 0;
 }
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 6166699fe6..951a247d02 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -548,9 +548,10 @@ int main(int argc, char **argv) {
   test_grpc_fd_change();
   grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_exec_ctx_flush(&exec_ctx);
   gpr_free(g_pollset);
-  grpc_iomgr_shutdown();
+  grpc_iomgr_shutdown(&exec_ctx);
+  grpc_exec_ctx_finish(&exec_ctx);
   return 0;
 }
 
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 2dd0d88b3f..36ee0db97a 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -172,7 +172,11 @@ int main(int argc, char **argv) {
   test_ipv6_without_port();
   test_invalid_ip_addresses();
   test_unparseable_hostports();
-  grpc_iomgr_shutdown();
-  grpc_executor_shutdown();
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_executor_shutdown(&exec_ctx);
+    grpc_iomgr_shutdown(&exec_ctx);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return 0;
 }
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 9bea229466..6bd6d60604 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -238,7 +238,7 @@ int main(int argc, char **argv) {
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
-  grpc_iomgr_shutdown();
+  grpc_shutdown();
   return 0;
 }
 
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index 14321d164e..71da935eeb 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -306,16 +306,14 @@ static int httpcli_get_google_keys_for_email(
   return 1;
 }
 
-static void on_verification_success(void *user_data,
+static void on_verification_success(grpc_exec_ctx *exec_ctx, void *user_data,
                                     grpc_jwt_verifier_status status,
                                     grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_OK);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(user_data == (void *)expected_user_data);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), expected_audience) == 0);
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_jwt_claims_destroy(&exec_ctx, claims);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_jwt_claims_destroy(exec_ctx, claims);
 }
 
 static void test_jwt_verifier_google_email_issuer_success(void) {
@@ -423,7 +421,8 @@ static void test_jwt_verifier_url_issuer_success(void) {
   grpc_httpcli_set_override(NULL, NULL);
 }
 
-static void on_verification_key_retrieval_error(void *user_data,
+static void on_verification_key_retrieval_error(grpc_exec_ctx *exec_ctx,
+                                                void *user_data,
                                                 grpc_jwt_verifier_status status,
                                                 grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR);
@@ -508,7 +507,8 @@ static void corrupt_jwt_sig(char *jwt) {
   grpc_slice_unref(sig);
 }
 
-static void on_verification_bad_signature(void *user_data,
+static void on_verification_bad_signature(grpc_exec_ctx *exec_ctx,
+                                          void *user_data,
                                           grpc_jwt_verifier_status status,
                                           grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_SIGNATURE);
@@ -549,7 +549,7 @@ static int httpcli_get_should_not_be_called(grpc_exec_ctx *exec_ctx,
   return 1;
 }
 
-static void on_verification_bad_format(void *user_data,
+static void on_verification_bad_format(grpc_exec_ctx *exec_ctx, void *user_data,
                                        grpc_jwt_verifier_status status,
                                        grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_FORMAT);
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 043d29e6bb..32169bb8d2 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -59,7 +59,7 @@ static void print_usage_and_exit(gpr_cmdline *cl, const char *argv0) {
   exit(1);
 }
 
-static void on_jwt_verification_done(void *user_data,
+static void on_jwt_verification_done(grpc_exec_ctx *exec_ctx, void *user_data,
                                      grpc_jwt_verifier_status status,
                                      grpc_jwt_claims *claims) {
   synchronizer *sync = user_data;
@@ -72,7 +72,7 @@ static void on_jwt_verification_done(void *user_data,
         grpc_json_dump_to_string((grpc_json *)grpc_jwt_claims_json(claims), 2);
     printf("Claims: \n\n%s\n", claims_str);
     gpr_free(claims_str);
-    grpc_jwt_claims_destroy(claims);
+    grpc_jwt_claims_destroy(exec_ctx, claims);
   } else {
     GPR_ASSERT(claims == NULL);
     fprintf(stderr, "Verification failed with error %s\n",
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index a3d4d6337e..cf88c42d46 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -7,12 +7,12 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
 
 # map of banned function signature to whitelist
 BANNED_EXCEPT = {
-    'grpc_resource_quota_ref(': ('src/core/lib/iomgr/resource_quota.c'),
-    'grpc_resource_quota_unref(': ('src/core/lib/iomgr/resource_quota.c'),
-    'grpc_slice_buffer_destroy(': ('src/core/lib/slice/slice_buffer.c'),
-    'grpc_slice_buffer_reset_and_unref(': ('src/core/lib/slice/slice_buffer.c'),
-    'grpc_slice_ref(': ('src/core/lib/slice/slice.c'),
-    'grpc_slice_unref(': ('src/core/lib/slice/slice.c'),
+    'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.c'],
+    'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.c'],
+    'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.c'],
+    'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
+    'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
+    'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
 }
 
 errors = 0
@@ -29,4 +29,3 @@ for root, dirs, files in os.walk('src/core'):
         errors += 1
 
 assert errors == 0
-
-- 
GitLab


From 7851ea37ce81cc3fefdd416977f15cc616e8fa65 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 16 Nov 2016 15:41:56 -0800
Subject: [PATCH 039/344] Fixes

---
 src/core/lib/iomgr/executor.c            | 6 ++----
 src/core/lib/support/string.c            | 2 +-
 test/core/end2end/tests/filter_latency.c | 3 ++-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 8d7535d6fe..4e78b619fb 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -121,9 +121,8 @@ void grpc_executor_push(grpc_closure *closure, grpc_error *error) {
   gpr_mu_unlock(&g_executor.mu);
 }
 
-void grpc_executor_shutdown() {
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
   int pending_join;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   gpr_mu_lock(&g_executor.mu);
   pending_join = g_executor.pending_join;
@@ -133,8 +132,7 @@ void grpc_executor_shutdown() {
    * list below because we aren't accepting new work */
 
   /* Execute pending callbacks, some may be performing cleanups */
-  grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_exec_ctx_enqueue_list(exec_ctx, &g_executor.closures, NULL);
   GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
   if (pending_join) {
     gpr_thd_join(g_executor.tid);
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index 4db3f9a66c..85b915f118 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -270,7 +270,7 @@ int gpr_stricmp(const char *a, const char *b) {
 static void add_string_to_split(const char *beg, const char *end, char ***strs,
                                 size_t *nstrs, size_t *capstrs) {
   char *out = gpr_malloc((size_t)(end - beg) + 1);
-  memcpy(out, beg, end - beg);
+  memcpy(out, beg, (size_t)(end - beg));
   out[end - beg] = 0;
   if (*nstrs == *capstrs) {
     *capstrs = GPR_MAX(8, 2 * *capstrs);
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b1222..043f12dd9a 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -314,7 +314,8 @@ static const grpc_channel_filter test_server_filter = {
  * Registration
  */
 
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+                             grpc_channel_stack_builder *builder, void *arg) {
   grpc_channel_filter *filter = arg;
   if (g_enable_filter) {
     // Want to add the filter as close to the end as possible, to make
-- 
GitLab


From e1e928330f94e15aaceea0d058351776358fe7ee Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 16 Nov 2016 15:43:43 -0800
Subject: [PATCH 040/344] Fix include guards

---
 include/grpc/impl/codegen/exec_ctx_fwd.h | 6 +++---
 src/core/lib/slice/slice_internal.h      | 6 +++---
 src/core/lib/transport/pid_controller.h  | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/grpc/impl/codegen/exec_ctx_fwd.h b/include/grpc/impl/codegen/exec_ctx_fwd.h
index 6dff2d248c..32edcedbb3 100644
--- a/include/grpc/impl/codegen/exec_ctx_fwd.h
+++ b/include/grpc/impl/codegen/exec_ctx_fwd.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef GRPC_EXEC_CTX_H
-#define GRPC_EXEC_CTX_H
+#ifndef GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+#define GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
 
 /* forward declaration for exec_ctx.h */
 struct grpc_exec_ctx;
 typedef struct grpc_exec_ctx grpc_exec_ctx;
 
-#endif
+#endif /* GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H */
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
index 72b0a590bb..6185333ca7 100644
--- a/src/core/lib/slice/slice_internal.h
+++ b/src/core/lib/slice/slice_internal.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
-#define GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
+#ifndef GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+#define GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
 
 #include <grpc/slice.h>
 #include <grpc/slice_buffer.h>
@@ -46,4 +46,4 @@ void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
 void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_slice_buffer *sb);
 
-#endif
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */
diff --git a/src/core/lib/transport/pid_controller.h b/src/core/lib/transport/pid_controller.h
index 059b5b0834..83c82d6471 100644
--- a/src/core/lib/transport/pid_controller.h
+++ b/src/core/lib/transport/pid_controller.h
@@ -61,4 +61,4 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller);
 double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
                                   double error, double dt);
 
-#endif
+#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */
-- 
GitLab


From f2752ebb3b81cbad4e3b9ac0df5d7021c4659243 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 16 Nov 2016 15:46:56 -0800
Subject: [PATCH 041/344] Fix build

---
 src/core/lib/iomgr/ev_epoll_linux.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 91041a7c28..86674ca8c6 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -31,7 +31,6 @@
  *
  */
 
-#include <grpc/grpc_posix.h>
 #include "src/core/lib/iomgr/port.h"
 
 /* This polling engine is only relevant on linux kernels supporting epoll() */
-- 
GitLab


From 0d3ea83b69f15c37a8e46aad92bd453e2e63b173 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Thu, 17 Nov 2016 01:25:27 -0800
Subject: [PATCH 042/344] Update CronetFramework version number to 1.0.0 and
 use new URL

---
 src/objective-c/CronetFramework.podspec | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/objective-c/CronetFramework.podspec b/src/objective-c/CronetFramework.podspec
index 2f47b02c0c..538479b96b 100644
--- a/src/objective-c/CronetFramework.podspec
+++ b/src/objective-c/CronetFramework.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name         = "CronetFramework"
-  s.version      = "0.0.3"
+  s.version      = "1.0.0"
   s.summary      = "Cronet, precompiled and used as a framework."
   s.homepage     = "http://chromium.org"
   s.license      = {
@@ -69,7 +69,7 @@ Pod::Spec.new do |s|
   s.vendored_framework = "Cronet.framework"
   s.author             = "The Chromium Authors"
   s.ios.deployment_target = "8.0"
-  s.source       = { :http => 'https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework.zip' }
+  s.source       = { :http => 'https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework-1.0.0.zip' }
   s.preserve_paths = "Cronet.framework"
   s.public_header_files = "Cronet.framework/Headers/**/*{.h}"
   s.source_files = "Cronet.framework/Headers/**/*{.h}"
-- 
GitLab


From 21d4b2d930642b2b8d272352dfa982b5102efd1e Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 18 Nov 2016 09:53:41 -0800
Subject: [PATCH 043/344] Pass client channel factory and server name via
 channel args.

---
 include/grpc/impl/codegen/grpc_types.h        |  2 +
 src/core/ext/client_channel/client_channel.c  | 48 +++++--------
 src/core/ext/client_channel/client_channel.h  |  7 --
 .../chttp2/client/insecure/channel_create.c   | 50 ++++++++------
 .../client/secure/secure_channel_create.c     | 67 ++++++++++++-------
 5 files changed, 93 insertions(+), 81 deletions(-)

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 8c5215faee..5ecc5ba043 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -220,6 +220,8 @@ typedef struct {
 #define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
 /** The grpc_socket_mutator instance that set the socket options. A pointer. */
 #define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
+/** Client channel factory.  Not intended for external use. */
+#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory"
 /** \} */
 
 /** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index b66fed4b88..a607f73c04 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -44,6 +44,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
@@ -454,20 +455,31 @@ static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem,
                                  grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
-
   memset(chand, 0, sizeof(*chand));
-
   GPR_ASSERT(args->is_last);
   GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
-
+  // Initialize data members.
   gpr_mu_init(&chand->mu);
+  chand->owning_stack = args->channel_stack;
   grpc_closure_init(&chand->on_resolver_result_changed,
                     on_resolver_result_changed, chand);
-  chand->owning_stack = args->channel_stack;
-
+  chand->interested_parties = grpc_pollset_set_create();
   grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
                                "client_channel");
-  chand->interested_parties = grpc_pollset_set_create();
+  // Record client channel factory.
+  const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
+                                               GRPC_ARG_CLIENT_CHANNEL_FACTORY);
+  GPR_ASSERT(arg != NULL);
+  GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
+  grpc_client_channel_factory_ref(arg->value.pointer.p);
+  chand->client_channel_factory = arg->value.pointer.p;
+  // Instantiate resolver.
+  arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_NAME);
+  GPR_ASSERT(arg != NULL);
+  GPR_ASSERT(arg->type == GRPC_ARG_STRING);
+  chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
+// FIXME: return failure instead of asserting
+  GPR_ASSERT(chand->resolver != NULL);
 }
 
 /* Destructor for channel_data */
@@ -1080,30 +1092,6 @@ const grpc_channel_filter grpc_client_channel_filter = {
     "client-channel",
 };
 
-void grpc_client_channel_finish_initialization(
-    grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
-    grpc_resolver *resolver,
-    grpc_client_channel_factory *client_channel_factory) {
-  /* post construction initialization: set the transport setup pointer */
-  GPR_ASSERT(client_channel_factory != NULL);
-  grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
-  channel_data *chand = elem->channel_data;
-  gpr_mu_lock(&chand->mu);
-  GPR_ASSERT(!chand->resolver);
-  chand->resolver = resolver;
-  GRPC_RESOLVER_REF(resolver, "channel");
-  if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
-      chand->exit_idle_when_lb_policy_arrives) {
-    chand->started_resolving = true;
-    GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-    grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result,
-                       &chand->on_resolver_result_changed);
-  }
-  chand->client_channel_factory = client_channel_factory;
-  grpc_client_channel_factory_ref(client_channel_factory);
-  gpr_mu_unlock(&chand->mu);
-}
-
 grpc_connectivity_state grpc_client_channel_check_connectivity_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
   channel_data *chand = elem->channel_data;
diff --git a/src/core/ext/client_channel/client_channel.h b/src/core/ext/client_channel/client_channel.h
index ab5a84fdfb..9ba012865c 100644
--- a/src/core/ext/client_channel/client_channel.h
+++ b/src/core/ext/client_channel/client_channel.h
@@ -47,13 +47,6 @@
 
 extern const grpc_channel_filter grpc_client_channel_filter;
 
-/* Post-construction initializer to give the client channel its resolver
-   and factory. */
-void grpc_client_channel_finish_initialization(
-    grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
-    grpc_resolver *resolver,
-    grpc_client_channel_factory *client_channel_factory);
-
 grpc_connectivity_state grpc_client_channel_check_connectivity_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect);
 
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 8e03fd82c1..d448b90992 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -42,7 +42,6 @@
 
 #include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/compress_filter.h"
@@ -195,20 +194,7 @@ static grpc_channel *client_channel_factory_create_channel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const char *target, grpc_client_channel_type type,
     const grpc_channel_args *args) {
-  grpc_channel *channel =
-      grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
-  grpc_resolver *resolver = grpc_resolver_create(target, args);
-  if (!resolver) {
-    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
-                                "client_channel_factory_create_channel");
-    return NULL;
-  }
-
-  grpc_client_channel_finish_initialization(
-      exec_ctx, grpc_channel_get_channel_stack(channel), resolver, cc_factory);
-  GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
-
-  return channel;
+  return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
 }
 
 static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -219,6 +205,21 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
 static grpc_client_channel_factory client_channel_factory = {
     &client_channel_factory_vtable};
 
+static void *cc_factory_arg_copy(void *cc_factory) {
+  return cc_factory;
+}
+
+static void cc_factory_arg_destroy(void *cc_factory) {}
+
+static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
+  if (cc_factory1 < cc_factory2) return -1;
+  if (cc_factory1 > cc_factory2) return 1;
+  return 0;
+}
+
+static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
+    cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
+
 /* Create a client channel:
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
@@ -231,15 +232,26 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
       "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
       (target, args, reserved));
   GPR_ASSERT(!reserved);
-
   grpc_client_channel_factory *factory =
       (grpc_client_channel_factory *)&client_channel_factory;
+  // Add channel args containing the server name and client channel factory.
+  grpc_arg new_args[2];
+  new_args[0].type = GRPC_ARG_STRING;
+  new_args[0].key = GRPC_ARG_SERVER_NAME;
+  new_args[0].value.string = (char *)target;
+  new_args[1].type = GRPC_ARG_POINTER;
+  new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
+  new_args[1].value.pointer.p = factory;
+  new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+  grpc_channel_args *args_copy =
+      grpc_channel_args_copy_and_add(args, new_args, GPR_ARRAY_SIZE(new_args));
+  // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
-      &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args);
-
+      &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
+  // Clean up.
+  grpc_channel_args_destroy(args_copy);
   grpc_client_channel_factory_unref(&exec_ctx, factory);
   grpc_exec_ctx_finish(&exec_ctx);
-
   return channel != NULL ? channel : grpc_lame_client_channel_create(
                                          target, GRPC_STATUS_INTERNAL,
                                          "Failed to create client channel");
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 04c88a2d36..b53e637fc2 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -42,7 +42,6 @@
 
 #include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
@@ -273,20 +272,7 @@ static grpc_channel *client_channel_factory_create_channel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const char *target, grpc_client_channel_type type,
     const grpc_channel_args *args) {
-  client_channel_factory *f = (client_channel_factory *)cc_factory;
-  grpc_channel *channel =
-      grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
-  grpc_resolver *resolver = grpc_resolver_create(target, args);
-  if (resolver != NULL) {
-    grpc_client_channel_finish_initialization(
-        exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
-    GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
-  } else {
-    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
-                                "client_channel_factory_create_channel");
-    channel = NULL;
-  }
-  return channel;
+  return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
 }
 
 static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -294,6 +280,28 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
      client_channel_factory_create_subchannel,
      client_channel_factory_create_channel};
 
+static void *cc_factory_arg_copy(void *cc_factory) {
+  client_channel_factory_ref(cc_factory);
+  return cc_factory;
+}
+
+static void cc_factory_arg_destroy(void *cc_factory) {
+  // TODO(roth): remove local exec_ctx when
+  // https://github.com/grpc/grpc/pull/8705 is merged
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  client_channel_factory_unref(&exec_ctx, cc_factory);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
+  if (cc_factory1 < cc_factory2) return -1;
+  if (cc_factory1 > cc_factory2) return 1;
+  return 0;
+}
+
+static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
+    cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
+
 /* Create a secure client channel:
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
@@ -326,14 +334,6 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
   }
-  grpc_arg connector_arg =
-      grpc_security_connector_to_arg(&security_connector->base);
-  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
-      new_args_from_connector != NULL ? new_args_from_connector : args,
-      &connector_arg, 1);
-  if (new_args_from_connector != NULL) {
-    grpc_channel_args_destroy(new_args_from_connector);
-  }
   // Create client channel factory.
   client_channel_factory *f = gpr_malloc(sizeof(*f));
   memset(f, 0, sizeof(*f));
@@ -342,13 +342,30 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
                               "grpc_secure_channel_create");
   f->security_connector = security_connector;
+  // Add channel args containing the server name, client channel
+  // factory, and security connector.
+  grpc_arg new_args[3];
+  new_args[0].type = GRPC_ARG_STRING;
+  new_args[0].key = GRPC_ARG_SERVER_NAME;
+  new_args[0].value.string = (char *)target;
+  new_args[1].type = GRPC_ARG_POINTER;
+  new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
+  new_args[1].value.pointer.p = f;
+  new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+  new_args[2] = grpc_security_connector_to_arg(&security_connector->base);
+  grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
+      new_args_from_connector != NULL ? new_args_from_connector : args,
+      new_args, GPR_ARRAY_SIZE(new_args));
+  if (new_args_from_connector != NULL) {
+    grpc_channel_args_destroy(new_args_from_connector);
+  }
   // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
-      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
+      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
   // Clean up.
   GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
                                 "secure_client_channel_factory_create_channel");
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(args_copy);
   grpc_client_channel_factory_unref(&exec_ctx, &f->base);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel; /* may be NULL */
-- 
GitLab


From 86e905901fa1331f2326f0a881dd79322eeff6c8 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 18 Nov 2016 09:56:40 -0800
Subject: [PATCH 044/344] Avoid confusion between server name and URI.

---
 include/grpc/impl/codegen/grpc_types.h                          | 2 ++
 src/core/ext/client_channel/client_channel.c                    | 2 +-
 src/core/ext/transport/chttp2/client/insecure/channel_create.c  | 2 +-
 .../ext/transport/chttp2/client/secure/secure_channel_create.c  | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 5ecc5ba043..9a9118ceaf 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -213,6 +213,8 @@ typedef struct {
 #define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
 /** LB policy name. */
 #define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
+/** Server URI. Not intended for external use. */
+#define GRPC_ARG_SERVER_URI "grpc.server_uri"
 /** Server name. Not intended for external use. */
 #define GRPC_ARG_SERVER_NAME "grpc.server_name"
 /** Resolved addresses in a form used by the LB policy.
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index a607f73c04..7df3bca5d8 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -474,7 +474,7 @@ static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   grpc_client_channel_factory_ref(arg->value.pointer.p);
   chand->client_channel_factory = arg->value.pointer.p;
   // Instantiate resolver.
-  arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_NAME);
+  arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
   chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index d448b90992..0d2395266b 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -237,7 +237,7 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
   // Add channel args containing the server name and client channel factory.
   grpc_arg new_args[2];
   new_args[0].type = GRPC_ARG_STRING;
-  new_args[0].key = GRPC_ARG_SERVER_NAME;
+  new_args[0].key = GRPC_ARG_SERVER_URI;
   new_args[0].value.string = (char *)target;
   new_args[1].type = GRPC_ARG_POINTER;
   new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index b53e637fc2..be57f30bd0 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -346,7 +346,7 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   // factory, and security connector.
   grpc_arg new_args[3];
   new_args[0].type = GRPC_ARG_STRING;
-  new_args[0].key = GRPC_ARG_SERVER_NAME;
+  new_args[0].key = GRPC_ARG_SERVER_URI;
   new_args[0].value.string = (char *)target;
   new_args[1].type = GRPC_ARG_POINTER;
   new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
-- 
GitLab


From 5e2566e92b0603cfa6c6a989ab7e2372525ca03d Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 18 Nov 2016 10:53:13 -0800
Subject: [PATCH 045/344] Change destroy_call_elem() to return a grpc_error*.

---
 src/core/ext/census/grpc_filter.c             |  7 +++---
 src/core/ext/client_channel/client_channel.c  | 12 ++++++----
 src/core/ext/client_channel/subchannel.c      | 16 +++++++++----
 .../load_reporting/load_reporting_filter.c    |  8 ++++---
 src/core/lib/channel/channel_stack.c          | 24 ++++++++++++-------
 src/core/lib/channel/channel_stack.h          | 17 ++++++-------
 src/core/lib/channel/channel_stack_builder.c  | 23 +++++++++---------
 src/core/lib/channel/channel_stack_builder.h  | 11 ++++-----
 src/core/lib/channel/compress_filter.c        |  7 +++---
 src/core/lib/channel/connected_channel.c      |  7 +++---
 src/core/lib/channel/deadline_filter.c        |  7 +++---
 src/core/lib/channel/http_client_filter.c     |  7 +++---
 src/core/lib/channel/http_server_filter.c     |  7 +++---
 src/core/lib/channel/message_size_filter.c    |  7 +++---
 .../security/transport/client_auth_filter.c   |  7 +++---
 .../security/transport/server_auth_filter.c   |  7 +++---
 src/core/lib/surface/channel.c                | 15 ++++++++----
 src/core/lib/surface/lame_client.c            |  7 +++---
 src/core/lib/surface/server.c                 |  7 +++---
 .../end2end/tests/filter_call_init_fails.c    |  8 ++++---
 test/core/end2end/tests/filter_causes_close.c |  8 ++++---
 test/core/end2end/tests/filter_latency.c      |  8 ++++---
 22 files changed, 133 insertions(+), 94 deletions(-)

diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 397dbc40a8..c73385f98b 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -167,11 +167,12 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
 }
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(chand != NULL);
+  return GRPC_ERROR_NONE;
 }
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 7df3bca5d8..13d8036b8d 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -451,9 +451,9 @@ static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
 }
 
 /* Constructor for channel_data */
-static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
-                                 grpc_channel_element *elem,
-                                 grpc_channel_element_args *args) {
+static grpc_error* cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_element *elem,
+                                        grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
   memset(chand, 0, sizeof(*chand));
   GPR_ASSERT(args->is_last);
@@ -478,8 +478,10 @@ static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
   chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
-// FIXME: return failure instead of asserting
-  GPR_ASSERT(chand->resolver != NULL);
+  if (chand->resolver == NULL) {
+    return GRPC_ERROR_CREATE("resolver creation failed");
+  }
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel_data */
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index a148b2a0e1..f1ed95ba9d 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -542,14 +542,20 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
   grpc_channel_stack_builder_set_transport(builder,
                                            c->connecting_result.transport);
 
-  if (grpc_channel_init_create_stack(exec_ctx, builder,
-                                     GRPC_CLIENT_SUBCHANNEL)) {
-    con = grpc_channel_stack_builder_finish(exec_ctx, builder, 0, 1,
-                                            connection_destroy, NULL);
-  } else {
+  if (!grpc_channel_init_create_stack(exec_ctx, builder,
+                                      GRPC_CLIENT_SUBCHANNEL)) {
     grpc_channel_stack_builder_destroy(builder);
     abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
   }
+  grpc_error *error = grpc_channel_stack_builder_finish(
+      exec_ctx, builder, 0, 1, connection_destroy, NULL, (void**)&con);
+  if (error != GRPC_ERROR_NONE) {
+    const char* msg = grpc_error_string(error);
+    gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", msg);
+    grpc_error_free_string(msg);
+    GRPC_ERROR_UNREF(error);
+    abort(); /* TODO(ctiller): what to do here? */
+  }
   stk = CHANNEL_STACK_FROM_CONNECTION(con);
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
 
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index b810e20bb9..a0feb086c7 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -152,9 +152,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   GPR_ASSERT(!args->is_last);
 
   channel_data *chand = elem->channel_data;
@@ -171,6 +171,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
                                                 NULL,
                                                 NULL};
                                                 */
+
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 999ad5f507..ab78dfbf3e 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -102,13 +102,11 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack,
   return CALL_ELEMS_FROM_STACK(call_stack) + index;
 }
 
-void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
-                             grpc_iomgr_cb_func destroy, void *destroy_arg,
-                             const grpc_channel_filter **filters,
-                             size_t filter_count,
-                             const grpc_channel_args *channel_args,
-                             grpc_transport *optional_transport,
-                             const char *name, grpc_channel_stack *stack) {
+grpc_error* grpc_channel_stack_init(
+    grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count,
+    const grpc_channel_args *channel_args, grpc_transport *optional_transport,
+    const char *name, grpc_channel_stack *stack) {
   size_t call_size =
       ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
@@ -126,6 +124,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
 
   /* init per-filter data */
+  grpc_error *first_error = GRPC_ERROR_NONE;
   for (i = 0; i < filter_count; i++) {
     args.channel_stack = stack;
     args.channel_args = channel_args;
@@ -134,7 +133,15 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
     args.is_last = i == (filter_count - 1);
     elems[i].filter = filters[i];
     elems[i].channel_data = user_data;
-    elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args);
+    grpc_error *error =
+        elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args);
+    if (error != GRPC_ERROR_NONE) {
+      if (first_error == GRPC_ERROR_NONE) {
+        first_error = error;
+      } else {
+        GRPC_ERROR_UNREF(error);
+      }
+    }
     user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
     call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
   }
@@ -144,6 +151,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
              grpc_channel_stack_size(filters, filter_count));
 
   stack->call_stack_size = call_size;
+  return first_error;
 }
 
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 004643d45f..9491b9ab1b 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -146,8 +146,9 @@ typedef struct {
      is_first, is_last designate this elements position in the stack, and are
      useful for asserting correct configuration by upper layer code.
      The filter does not need to do any chaining */
-  void (*init_channel_elem)(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem,
-                            grpc_channel_element_args *args);
+  grpc_error *(*init_channel_elem)(grpc_exec_ctx *exec_ctx,
+                                   grpc_channel_element *elem,
+                                   grpc_channel_element_args *args);
   /* Destroy per channel data.
      The filter does not need to do any chaining */
   void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx,
@@ -214,12 +215,12 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i);
 size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
                                size_t filter_count);
 /* Initialize a channel stack given some filters */
-void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
-                             grpc_iomgr_cb_func destroy, void *destroy_arg,
-                             const grpc_channel_filter **filters,
-                             size_t filter_count, const grpc_channel_args *args,
-                             grpc_transport *optional_transport,
-                             const char *name, grpc_channel_stack *stack);
+grpc_error* grpc_channel_stack_init(
+    grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, const grpc_channel_filter **filters,
+    size_t filter_count, const grpc_channel_args *args,
+    grpc_transport *optional_transport, const char *name,
+    grpc_channel_stack *stack);
 /* Destroy a channel stack */
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
                                 grpc_channel_stack *stack);
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index eda4968f48..747db0749e 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -227,11 +227,10 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
   gpr_free(builder);
 }
 
-void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
-                                        grpc_channel_stack_builder *builder,
-                                        size_t prefix_bytes, int initial_refs,
-                                        grpc_iomgr_cb_func destroy,
-                                        void *destroy_arg) {
+grpc_error *grpc_channel_stack_builder_finish(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    size_t prefix_bytes, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, void **result) {
   // count the number of filters
   size_t num_filters = 0;
   for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
@@ -250,15 +249,15 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
   size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters);
 
   // allocate memory, with prefix_bytes followed by channel_stack_size
-  char *result = gpr_malloc(prefix_bytes + channel_stack_size);
+  *result = gpr_malloc(prefix_bytes + channel_stack_size);
   // fetch a pointer to the channel stack
   grpc_channel_stack *channel_stack =
-      (grpc_channel_stack *)(result + prefix_bytes);
+      (grpc_channel_stack *)(*result + prefix_bytes);
   // and initialize it
-  grpc_channel_stack_init(exec_ctx, initial_refs, destroy,
-                          destroy_arg == NULL ? result : destroy_arg, filters,
-                          num_filters, builder->args, builder->transport,
-                          builder->name, channel_stack);
+  grpc_error* error = grpc_channel_stack_init(
+      exec_ctx, initial_refs, destroy,
+      destroy_arg == NULL ? *result : destroy_arg, filters, num_filters,
+      builder->args, builder->transport, builder->name, channel_stack);
 
   // run post-initialization functions
   i = 0;
@@ -273,5 +272,5 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
   grpc_channel_stack_builder_destroy(builder);
   gpr_free((grpc_channel_filter **)filters);
 
-  return result;
+  return error;
 }
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 4a00f7bfdb..65bfebcabc 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -146,16 +146,15 @@ bool grpc_channel_stack_builder_append_filter(
 void grpc_channel_stack_builder_iterator_destroy(
     grpc_channel_stack_builder_iterator *iterator);
 
-/// Destroy the builder, return the freshly minted channel stack
+/// Destroy the builder, return the freshly minted channel stack in \a result.
 /// Allocates \a prefix_bytes bytes before the channel stack
 /// Returns the base pointer of the allocated block
 /// \a initial_refs, \a destroy, \a destroy_arg are as per
 /// grpc_channel_stack_init
-void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
-                                        grpc_channel_stack_builder *builder,
-                                        size_t prefix_bytes, int initial_refs,
-                                        grpc_iomgr_cb_func destroy,
-                                        void *destroy_arg);
+grpc_error *grpc_channel_stack_builder_finish(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    size_t prefix_bytes, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, void **result);
 
 /// Destroy the builder without creating a channel stack
 void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 2874d63fc7..2afe28941a 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -285,9 +285,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   channel_data *channeld = elem->channel_data;
 
   channeld->enabled_algorithms_bitset =
@@ -315,6 +315,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   }
 
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 038e819f72..92739f70c7 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -114,12 +114,13 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   channel_data *cd = (channel_data *)elem->channel_data;
   GPR_ASSERT(args->is_last);
   cd->transport = NULL;
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel_data */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 0e703d8d27..470ccfea57 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -207,10 +207,11 @@ void grpc_deadline_state_client_start_transport_stream_op(
 //
 
 // Constructor for channel_data.  Used for both client and server filters.
-static void init_channel_elem(grpc_exec_ctx* exec_ctx,
-                              grpc_channel_element* elem,
-                              grpc_channel_element_args* args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
+                                     grpc_channel_element* elem,
+                                     grpc_channel_element_args* args) {
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 
 // Destructor for channel_data.  Used for both client and server filters.
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index f57d7c2453..8be9e0a2cb 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -415,9 +415,9 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(args->optional_transport != NULL);
@@ -428,6 +428,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
       GRPC_MDSTR_USER_AGENT,
       user_agent_from_args(args->channel_args,
                            args->optional_transport->vtable->name));
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index 6a33689fec..035124ade9 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -326,10 +326,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 1331fe1c65..c6bfb80d78 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -195,9 +195,9 @@ static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                               void* ignored) {}
 
 // Constructor for channel_data.
-static void init_channel_elem(grpc_exec_ctx* exec_ctx,
-                              grpc_channel_element* elem,
-                              grpc_channel_element_args* args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
+                                     grpc_channel_element* elem,
+                                     grpc_channel_element_args* args) {
   GPR_ASSERT(!args->is_last);
   channel_data* chand = elem->channel_data;
   memset(chand, 0, sizeof(*chand));
@@ -228,6 +228,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
         (grpc_method_config_table*)channel_arg->value.pointer.p,
         method_config_convert_value, &message_size_limits_vtable);
   }
+  return GRPC_ERROR_NONE;
 }
 
 // Destructor for channel_data.
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 053bf5972c..eeb11feeb2 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -303,9 +303,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   grpc_security_connector *sc =
       grpc_find_security_connector_in_args(args->channel_args);
   grpc_auth_context *auth_context =
@@ -327,6 +327,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
           sc, "client_auth_filter");
   chand->auth_context =
       GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index eaa1d0720b..3abbeb35ef 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -238,9 +238,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               void *ignored) {}
 
 /* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   grpc_auth_context *auth_context =
       grpc_find_auth_context_in_args(args->channel_args);
   grpc_server_credentials *creds =
@@ -256,6 +256,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->auth_context =
       GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
   chand->creds = grpc_server_credentials_ref(creds);
+  return GRPC_ERROR_NONE;
 }
 
 /* Destructor for channel data */
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 1389df6886..1b5cf5ffec 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -97,11 +97,16 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
   if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
     grpc_channel_stack_builder_destroy(builder);
     return NULL;
-  } else {
-    args = grpc_channel_args_copy(
-        grpc_channel_stack_builder_get_channel_arguments(builder));
-    channel = grpc_channel_stack_builder_finish(
-        exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL);
+  }
+  args = grpc_channel_args_copy(
+      grpc_channel_stack_builder_get_channel_arguments(builder));
+  grpc_error* error = grpc_channel_stack_builder_finish(
+      exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
+      (void**)&channel);
+  if (error != GRPC_ERROR_NONE) {
+    grpc_channel_stack_destroy(exec_ctx, (grpc_channel_stack *)channel);
+    gpr_free(channel);
+    return NULL;
   }
 
   memset(channel, 0, sizeof(*channel));
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d0df8e7e17..995a88de9e 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -123,11 +123,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   gpr_free(and_free_memory);
 }
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   GPR_ASSERT(args->is_first);
   GPR_ASSERT(args->is_last);
+  return GRPC_ERROR_NONE;
 }
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 89dd825460..eeeb6cd432 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -913,9 +913,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   server_unref(exec_ctx, chand->server);
 }
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(args->is_first);
   GPR_ASSERT(!args->is_last);
@@ -926,6 +926,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->connectivity_state = GRPC_CHANNEL_IDLE;
   grpc_closure_init(&chand->channel_connectivity_changed,
                     channel_connectivity_changed, chand);
+  return GRPC_ERROR_NONE;
 }
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 41ae575fff..13a32bf64d 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -216,9 +216,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {}
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index bf9fd9073d..4c1ff8459a 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -243,9 +243,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {}
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b1222..3e9c0352a5 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -275,9 +275,11 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_unlock(&g_mu);
 }
 
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {}
+static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
+  return GRPC_ERROR_NONE;
+}
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
-- 
GitLab


From c1087883579714691dc5cb3a66445da497c1a08c Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 18 Nov 2016 10:54:45 -0800
Subject: [PATCH 046/344] clang-format

---
 src/core/ext/census/grpc_filter.c                        | 2 +-
 src/core/ext/client_channel/client_channel.c             | 2 +-
 src/core/ext/client_channel/subchannel.c                 | 4 ++--
 src/core/ext/load_reporting/load_reporting_filter.c      | 2 +-
 .../transport/chttp2/client/insecure/channel_create.c    | 4 +---
 src/core/lib/channel/channel_stack.c                     | 2 +-
 src/core/lib/channel/channel_stack.h                     | 9 ++++-----
 src/core/lib/channel/channel_stack_builder.c             | 2 +-
 src/core/lib/channel/compress_filter.c                   | 2 +-
 src/core/lib/channel/connected_channel.c                 | 2 +-
 src/core/lib/channel/http_client_filter.c                | 2 +-
 src/core/lib/channel/http_server_filter.c                | 2 +-
 src/core/lib/security/transport/client_auth_filter.c     | 2 +-
 src/core/lib/security/transport/server_auth_filter.c     | 2 +-
 src/core/lib/surface/channel.c                           | 4 ++--
 src/core/lib/surface/lame_client.c                       | 2 +-
 src/core/lib/surface/server.c                            | 2 +-
 test/core/end2end/tests/filter_call_init_fails.c         | 2 +-
 test/core/end2end/tests/filter_causes_close.c            | 2 +-
 test/core/end2end/tests/filter_latency.c                 | 2 +-
 20 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index c73385f98b..3e8acc85e1 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -167,7 +167,7 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
 }
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 13d8036b8d..64f507f424 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -451,7 +451,7 @@ static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
 }
 
 /* Constructor for channel_data */
-static grpc_error* cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
                                         grpc_channel_element *elem,
                                         grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index f1ed95ba9d..b25957518a 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -548,9 +548,9 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
     abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
   }
   grpc_error *error = grpc_channel_stack_builder_finish(
-      exec_ctx, builder, 0, 1, connection_destroy, NULL, (void**)&con);
+      exec_ctx, builder, 0, 1, connection_destroy, NULL, (void **)&con);
   if (error != GRPC_ERROR_NONE) {
-    const char* msg = grpc_error_string(error);
+    const char *msg = grpc_error_string(error);
     gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", msg);
     grpc_error_free_string(msg);
     GRPC_ERROR_UNREF(error);
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index a0feb086c7..18bb826948 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -152,7 +152,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   GPR_ASSERT(!args->is_last);
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 0d2395266b..9e0478feab 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -205,9 +205,7 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
 static grpc_client_channel_factory client_channel_factory = {
     &client_channel_factory_vtable};
 
-static void *cc_factory_arg_copy(void *cc_factory) {
-  return cc_factory;
-}
+static void *cc_factory_arg_copy(void *cc_factory) { return cc_factory; }
 
 static void cc_factory_arg_destroy(void *cc_factory) {}
 
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index ab78dfbf3e..1d0b7d4f31 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -102,7 +102,7 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack,
   return CALL_ELEMS_FROM_STACK(call_stack) + index;
 }
 
-grpc_error* grpc_channel_stack_init(
+grpc_error *grpc_channel_stack_init(
     grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
     void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count,
     const grpc_channel_args *channel_args, grpc_transport *optional_transport,
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 9491b9ab1b..5d064c5695 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -215,12 +215,11 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i);
 size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
                                size_t filter_count);
 /* Initialize a channel stack given some filters */
-grpc_error* grpc_channel_stack_init(
+grpc_error *grpc_channel_stack_init(
     grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
-    void *destroy_arg, const grpc_channel_filter **filters,
-    size_t filter_count, const grpc_channel_args *args,
-    grpc_transport *optional_transport, const char *name,
-    grpc_channel_stack *stack);
+    void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count,
+    const grpc_channel_args *args, grpc_transport *optional_transport,
+    const char *name, grpc_channel_stack *stack);
 /* Destroy a channel stack */
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
                                 grpc_channel_stack *stack);
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index 747db0749e..047d85f44d 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -254,7 +254,7 @@ grpc_error *grpc_channel_stack_builder_finish(
   grpc_channel_stack *channel_stack =
       (grpc_channel_stack *)(*result + prefix_bytes);
   // and initialize it
-  grpc_error* error = grpc_channel_stack_init(
+  grpc_error *error = grpc_channel_stack_init(
       exec_ctx, initial_refs, destroy,
       destroy_arg == NULL ? *result : destroy_arg, filters, num_filters,
       builder->args, builder->transport, builder->name, channel_stack);
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 2afe28941a..0e336dc330 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -285,7 +285,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   channel_data *channeld = elem->channel_data;
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 92739f70c7..c2a36b5558 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -114,7 +114,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   channel_data *cd = (channel_data *)elem->channel_data;
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 8be9e0a2cb..35528e1b8c 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -415,7 +415,7 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index 035124ade9..4b976ed8d5 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -326,7 +326,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   GPR_ASSERT(!args->is_last);
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index eeb11feeb2..da897296e4 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -303,7 +303,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   grpc_security_connector *sc =
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index 3abbeb35ef..e6a242e68f 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -238,7 +238,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               void *ignored) {}
 
 /* Constructor for channel_data */
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   grpc_auth_context *auth_context =
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 1b5cf5ffec..22bb55c7b4 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -100,9 +100,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
   }
   args = grpc_channel_args_copy(
       grpc_channel_stack_builder_get_channel_arguments(builder));
-  grpc_error* error = grpc_channel_stack_builder_finish(
+  grpc_error *error = grpc_channel_stack_builder_finish(
       exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
-      (void**)&channel);
+      (void **)&channel);
   if (error != GRPC_ERROR_NONE) {
     grpc_channel_stack_destroy(exec_ctx, (grpc_channel_stack *)channel);
     gpr_free(channel);
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index 995a88de9e..57da94ac1e 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -123,7 +123,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   gpr_free(and_free_memory);
 }
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   GPR_ASSERT(args->is_first);
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index eeeb6cd432..78bd13bbbd 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -913,7 +913,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   server_unref(exec_ctx, chand->server);
 }
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 13a32bf64d..6d9351ed8c 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -216,7 +216,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   return GRPC_ERROR_NONE;
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index 4c1ff8459a..21905b98fa 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -243,7 +243,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   return GRPC_ERROR_NONE;
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 3e9c0352a5..9263dcc203 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -275,7 +275,7 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_unlock(&g_mu);
 }
 
-static grpc_error* init_channel_elem(grpc_exec_ctx *exec_ctx,
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_channel_element *elem,
                                      grpc_channel_element_args *args) {
   return GRPC_ERROR_NONE;
-- 
GitLab


From e4a013d6545fe9ab14e8317fe5a88bedb553059c Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Mon, 21 Nov 2016 17:12:59 -0800
Subject: [PATCH 047/344] Re-enable Node 7 artifact build

---
 tools/run_tests/build_artifact_node.bat | 2 +-
 tools/run_tests/build_artifact_node.sh  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/run_tests/build_artifact_node.bat b/tools/run_tests/build_artifact_node.bat
index 57d55ef19e..2e0ecd21d0 100644
--- a/tools/run_tests/build_artifact_node.bat
+++ b/tools/run_tests/build_artifact_node.bat
@@ -27,7 +27,7 @@
 @rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
+set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0
 
 set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
 
diff --git a/tools/run_tests/build_artifact_node.sh b/tools/run_tests/build_artifact_node.sh
index 9d06472aa4..778a5c95d4 100755
--- a/tools/run_tests/build_artifact_node.sh
+++ b/tools/run_tests/build_artifact_node.sh
@@ -42,7 +42,7 @@ mkdir -p artifacts
 
 npm update
 
-node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
+node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 7.0.0 )
 
 for version in ${node_versions[@]}
 do
-- 
GitLab


From 03fc19876de683e3c8b4ca3ddc71af6c9756b07a Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Tue, 22 Nov 2016 14:24:49 -0800
Subject: [PATCH 048/344] wait for write loop to finish at end of ruby read
 loop, on client side calls

---
 src/ruby/lib/grpc/generic/bidi_call.rb | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 75ddff0bfd..2b882313f2 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -208,6 +208,10 @@ module GRPC
       GRPC.logger.debug('bidi-read-loop: finished')
       @reads_complete = true
       finished
+      # Make sure that the write loop is done done before finishing the call.
+      # Note that blocking is ok at this point because we've already received
+      # a status
+      @enq_th.join if is_client
     end
   end
 end
-- 
GitLab


From 3d48cf4ed30032d417c3b64df11b7fb45220388c Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 23 Nov 2016 09:50:22 -0800
Subject: [PATCH 049/344] dont break out of response stream iterator in
 benchmark client

---
 src/ruby/qps/client.rb | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb
index 8aed866da5..817192626b 100644
--- a/src/ruby/qps/client.rb
+++ b/src/ruby/qps/client.rb
@@ -134,6 +134,7 @@ class BenchmarkClient
     resp = stub.streaming_call(q.each_item)
     start = Time.now
     q.push(req)
+    pushed_sentinal = false
     resp.each do |r|
       @histogram.add((Time.now-start)*1e9)
       if !@done
@@ -141,8 +142,9 @@ class BenchmarkClient
         start = Time.now
         q.push(req)
       else
-        q.push(self)
-        break
+        q.push(self) unless pushed_sentinal
+	# Continue polling on the responses to consume and release resources
+        pushed_sentinal = true
       end
     end
   end
-- 
GitLab


From 3f1db28ed01a87c4df0b7019b272c96b680ac5cb Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 23 Nov 2016 09:59:48 -0800
Subject: [PATCH 050/344] clang-format

---
 src/core/ext/transport/chttp2/transport/parsing.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 6e86431b1c..cbbffc5a61 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -254,14 +254,17 @@ void grpc_chttp2_publish_reads(
 
     if (stream_parsing->received_close) {
       if (transport_global->is_client && !stream_global->write_closed) {
-        gpr_slice_buffer_add(&transport_global->qbuf,
-                             grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, GRPC_CHTTP2_NO_ERROR, &stream_parsing->stats.outgoing));
+        gpr_slice_buffer_add(
+            &transport_global->qbuf,
+            grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id,
+                                          GRPC_CHTTP2_NO_ERROR,
+                                          &stream_parsing->stats.outgoing));
         grpc_chttp2_initiate_write(exec_ctx, transport_global, false, "rst");
-        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
-                                       1, 1, GRPC_ERROR_NONE);
+        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global,
+                                       stream_global, 1, 1, GRPC_ERROR_NONE);
       } else {
-        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global,
-                                       1, 0, GRPC_ERROR_NONE);
+        grpc_chttp2_mark_stream_closed(exec_ctx, transport_global,
+                                       stream_global, 1, 0, GRPC_ERROR_NONE);
       }
     }
   }
-- 
GitLab


From 7f8a628f6ae1c67020c9137ea53d2f9f20b00a50 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 23 Nov 2016 10:36:08 -0800
Subject: [PATCH 051/344] fix race between app and GC on ruby server shutdown

---
 src/ruby/ext/grpc/rb_server.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index bf26841fd2..6783fd3f88 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -37,6 +37,7 @@
 #include "rb_server.h"
 
 #include <grpc/grpc.h>
+#include <grpc/support/atm.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/log.h>
 #include "rb_call.h"
@@ -59,11 +60,13 @@ typedef struct grpc_rb_server {
   /* The actual server */
   grpc_server *wrapped;
   grpc_completion_queue *queue;
+  gpr_atm shutdown_started;
 } grpc_rb_server;
 
 static void destroy_server(grpc_rb_server *server, gpr_timespec deadline) {
   grpc_event ev;
-  if (server->wrapped != NULL) {
+  // This can be started by app or implicitly by GC. Avoid a race between these.
+  if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
     grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
     ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
     if (ev.type == GRPC_QUEUE_TIMEOUT) {
@@ -115,6 +118,7 @@ static const rb_data_type_t grpc_rb_server_data_type = {
 static VALUE grpc_rb_server_alloc(VALUE cls) {
   grpc_rb_server *wrapper = ALLOC(grpc_rb_server);
   wrapper->wrapped = NULL;
+  wrapper->shutdown_started = (gpr_atm)0;
   return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper);
 }
 
-- 
GitLab


From 6ead007882233ec2664e66548adbb8c938c32752 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 23 Nov 2016 12:09:09 -0800
Subject: [PATCH 052/344] Revert "Update messages.proto and add a new test" as
 the test is not supported in v1.0.x

This reverts commit 59af1bf4689d2992d23e0493465caec455bd05b2.
---
 src/objective-c/tests/InteropTests.m          | 45 ------------
 .../tests/RemoteTestClient/messages.proto     | 71 +++----------------
 2 files changed, 9 insertions(+), 107 deletions(-)

diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index add63614e7..f04a7e6441 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -321,51 +321,6 @@
   [self waitForExpectationsWithTimeout:4 handler:nil];
 }
 
-- (void)testErroneousPingPongRPC {
-  XCTAssertNotNil(self.class.host);
-  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
-
-  GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
-
-  __block int index = 0;
-
-  RMTStreamingOutputCallRequest *request =
-      [RMTStreamingOutputCallRequest messageWithPayloadSize:@256
-                                      requestedResponseSize:@256];
-
-  [requestsBuffer writeValue:request];
-
-  [_service fullDuplexCallWithRequestsWriter:requestsBuffer
-                                eventHandler:^(BOOL done,
-                                               RMTStreamingOutputCallResponse *response,
-                                               NSError *error) {
-      if (index == 0) {
-        XCTAssertNil(error, @"Finished with unexpected error: %@", error);
-        XCTAssertNotNil(response, @"Event handler called without an event.");
-        XCTAssertFalse(done);
-
-        id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:@256];
-        XCTAssertEqualObjects(response, expected);
-        index += 1;
-
-        RMTStreamingOutputCallRequest *request =
-        [RMTStreamingOutputCallRequest messageWithPayloadSize:@256
-                                        requestedResponseSize:@0];
-        RMTEchoStatus *status = [RMTEchoStatus message];
-        status.code = 7;
-        status.message = @"Error message!";
-        request.responseStatus = status;
-        [requestsBuffer writeValue:request];
-      } else {
-        XCTAssertNil(response);
-        XCTAssertNotNil(error);
-
-        [expectation fulfill];
-      }
-  }];
-  [self waitForExpectationsWithTimeout:4 handler:nil];
-}
-
 #ifndef GRPC_COMPILE_WITH_CRONET
 // TODO(makdharma@): Fix this test
 - (void)testEmptyStreamRPC {
diff --git a/src/objective-c/tests/RemoteTestClient/messages.proto b/src/objective-c/tests/RemoteTestClient/messages.proto
index b8b8b668d0..85d93c2ff9 100644
--- a/src/objective-c/tests/RemoteTestClient/messages.proto
+++ b/src/objective-c/tests/RemoteTestClient/messages.proto
@@ -1,5 +1,4 @@
-
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -36,45 +35,34 @@ package grpc.testing;
 
 option objc_class_prefix = "RMT";
 
-// 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";
-message BoolValue {
-  // The bool value.
-  bool value = 1;
-}
-
-// DEPRECATED, don't use. To be removed shortly.
 // The type of payload that should be returned.
 enum PayloadType {
   // Compressable text format.
   COMPRESSABLE = 0;
+
+  // Uncompressable binary format.
+  UNCOMPRESSABLE = 1;
+
+  // Randomly chosen from all other formats defined in this enum.
+  RANDOM = 2;
 }
 
 // A block of data, to simply increase gRPC message size.
 message Payload {
-  // DEPRECATED, don't use. To be removed shortly.
   // The type of data in body.
   PayloadType type = 1;
   // Primary contents of payload.
   bytes body = 2;
 }
 
-// A protobuf representation for grpc status. This is used by test
-// clients to specify a status that the server should attempt to return.
-message EchoStatus {
-  int32 code = 1;
-  string message = 2;
-}
-
 // Unary request.
 message SimpleRequest {
-  // 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.
   PayloadType response_type = 1;
 
   // Desired payload size in the response from the server.
+  // If response_type is COMPRESSABLE, this denotes the size before compression.
   int32 response_size = 2;
 
   // Optional input payload sent along with the request.
@@ -85,18 +73,6 @@ message SimpleRequest {
 
   // Whether SimpleResponse should include OAuth scope.
   bool fill_oauth_scope = 5;
-
-  // 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.
-  BoolValue response_compressed = 6;
-
-  // Whether server should return a given status
-  EchoStatus response_status = 7;
-
-  // Whether the server should expect this request to be compressed.
-  BoolValue expect_compressed = 8;
 }
 
 // Unary response, as configured by the request.
@@ -115,12 +91,6 @@ message StreamingInputCallRequest {
   // Optional input payload sent along with the request.
   Payload payload = 1;
 
-  // 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.
-  BoolValue expect_compressed = 2;
-
   // Not expecting any payload from the response.
 }
 
@@ -133,22 +103,16 @@ message StreamingInputCallResponse {
 // Configuration for a particular response.
 message ResponseParameters {
   // Desired payload sizes in responses from the server.
+  // If response_type is COMPRESSABLE, this denotes the size before compression.
   int32 size = 1;
 
   // Desired interval between consecutive responses in the response stream in
   // microseconds.
   int32 interval_us = 2;
-
-  // 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.
-  BoolValue compressed = 3;
 }
 
 // Server-streaming request.
 message StreamingOutputCallRequest {
-  // 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
@@ -160,9 +124,6 @@ message StreamingOutputCallRequest {
 
   // Optional input payload sent along with the request.
   Payload payload = 3;
-
-  // Whether server should return a given status
-  EchoStatus response_status = 7;
 }
 
 // Server-streaming response, as configured by the request and parameters.
@@ -170,17 +131,3 @@ message StreamingOutputCallResponse {
   // Payload to increase response size.
   Payload payload = 1;
 }
-
-// For reconnect interop test only.
-// Client tells server what reconnection parameters it used.
-message ReconnectParams {
-  int32 max_reconnect_backoff_ms = 1;
-}
-
-// For reconnect interop test only.
-// Server tells client whether its reconnects are following the spec and the
-// reconnect backoffs it saw.
-message ReconnectInfo {
-  bool passed = 1;
-  repeated int32 backoff_ms = 2;
-}
-- 
GitLab


From 878ff0835dc94c99609d8a3c93fc346ea36e18e4 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 23 Nov 2016 15:27:56 -0800
Subject: [PATCH 053/344] Revert "Missed file"

This reverts commit 10790401dd7f1faa4aa2ab5d4801b91d788d3e2d.
---
 tools/run_tests/tests.json | 44 --------------------------------------
 1 file changed, 44 deletions(-)

diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 5ed5a0ebbc..88869e6497 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -62714,50 +62714,6 @@
     ], 
     "uses_polling": false
   }, 
-  {
-    "args": [
-      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [
-      "tsan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "client_fuzzer_one_entry", 
-    "platforms": [
-      "linux"
-    ], 
-    "uses_polling": false
-  }, 
-  {
-    "args": [
-      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [
-      "tsan"
-    ], 
-    "exclude_iomgrs": [
-      "uv"
-    ], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "client_fuzzer_one_entry", 
-    "platforms": [
-      "linux"
-    ], 
-    "uses_polling": false
-  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/settings_frame_1.bin"
-- 
GitLab


From d7425740045acb658c365f905c4988460628ef33 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 23 Nov 2016 15:29:44 -0800
Subject: [PATCH 054/344] Fix breaking generate_project.py

---
 tools/run_tests/tests.json | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 88869e6497..55fc0e38d1 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -62714,6 +62714,44 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_1_header"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/server_hanging_response_2_header2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/settings_frame_1.bin"
-- 
GitLab


From e85477646c5b6ec159715a7e8d9ebaaf6d451777 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 28 Nov 2016 17:42:53 +0000
Subject: [PATCH 055/344] Fix build problems.

---
 src/core/lib/channel/channel_stack_builder.c |  2 +-
 src/cpp/common/channel_filter.h              | 13 +++++++++----
 test/core/channel/channel_stack_test.c       |  7 ++++---
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index 047d85f44d..dd11e5bf6b 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -252,7 +252,7 @@ grpc_error *grpc_channel_stack_builder_finish(
   *result = gpr_malloc(prefix_bytes + channel_stack_size);
   // fetch a pointer to the channel stack
   grpc_channel_stack *channel_stack =
-      (grpc_channel_stack *)(*result + prefix_bytes);
+      (grpc_channel_stack *)((char *)(*result) + prefix_bytes);
   // and initialize it
   grpc_error *error = grpc_channel_stack_init(
       exec_ctx, initial_refs, destroy,
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index e420efc71c..6bda74b9be 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -220,6 +220,9 @@ class ChannelData {
     if (peer_) gpr_free((void *)peer_);
   }
 
+  /// Initializes the call data.
+  virtual grpc_error *Init() { return GRPC_ERROR_NONE; }
+
   /// Caller does NOT take ownership of result.
   const char *peer() const { return peer_; }
 
@@ -276,15 +279,17 @@ class ChannelFilter final {
  public:
   static const size_t channel_data_size = sizeof(ChannelDataType);
 
-  static void InitChannelElement(grpc_exec_ctx *exec_ctx,
-                                 grpc_channel_element *elem,
-                                 grpc_channel_element_args *args) {
+  static grpc_error *InitChannelElement(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_element *elem,
+                                        grpc_channel_element_args *args) {
     const char *peer =
         args->optional_transport
             ? grpc_transport_get_peer(exec_ctx, args->optional_transport)
             : nullptr;
     // Construct the object in the already-allocated memory.
-    new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
+    ChannelDataType* channel_data =
+        new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
+    return channel_data->Init();
   }
 
   static void DestroyChannelElement(grpc_exec_ctx *exec_ctx,
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 0840820cca..b43d05eec3 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -41,9 +41,9 @@
 
 #include "test/core/util/test_config.h"
 
-static void channel_init_func(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
+static grpc_error *channel_init_func(grpc_exec_ctx *exec_ctx,
+                                     grpc_channel_element *elem,
+                                     grpc_channel_element_args *args) {
   GPR_ASSERT(args->channel_args->num_args == 1);
   GPR_ASSERT(args->channel_args->args[0].type == GRPC_ARG_INTEGER);
   GPR_ASSERT(0 == strcmp(args->channel_args->args[0].key, "test_key"));
@@ -51,6 +51,7 @@ static void channel_init_func(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(args->is_first);
   GPR_ASSERT(args->is_last);
   *(int *)(elem->channel_data) = 0;
+  return GRPC_ERROR_NONE;
 }
 
 static grpc_error *call_init_func(grpc_exec_ctx *exec_ctx,
-- 
GitLab


From a0ed373d3cb6d93b55ebe753b276c2ddf1fc7b65 Mon Sep 17 00:00:00 2001
From: Garrett Casto <gcasto@chromium.org>
Date: Mon, 7 Nov 2016 20:36:31 -0800
Subject: [PATCH 056/344] Change interface

---
 BUILD                                         |   2 +-
 build.yaml                                    |   2 +-
 .../client/secure/cronet_channel_create.c     |   2 +-
 .../cronet/transport/cronet_api_dummy.c       |  29 +--
 .../cronet/transport/cronet_transport.c       | 116 ++++-----
 src/objective-c/GRPCClient/GRPCCall+Cronet.h  |   6 +-
 src/objective-c/GRPCClient/GRPCCall+Cronet.m  |   6 +-
 .../GRPCClient/private/GRPCChannel.m          |   4 +-
 third_party/Cronet/bidirectional_stream_c.h   | 246 ++++++++++++++++++
 .../objective_c/Cronet/cronet_c_for_grpc.h    | 202 --------------
 tools/run_tests/sources_and_headers.json      |   2 +-
 11 files changed, 330 insertions(+), 287 deletions(-)
 create mode 100644 third_party/Cronet/bidirectional_stream_c.h
 delete mode 100644 third_party/objective_c/Cronet/cronet_c_for_grpc.h

diff --git a/BUILD b/BUILD
index f80e5f0664..955cb73af5 100644
--- a/BUILD
+++ b/BUILD
@@ -687,7 +687,7 @@ cc_library(
     "src/core/lib/transport/timeout_encoding.h",
     "src/core/lib/transport/transport.h",
     "src/core/lib/transport/transport_impl.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
+    "third_party/Cronet/bidirectional_stream_c.h",
     "src/core/ext/transport/chttp2/transport/bin_decoder.h",
     "src/core/ext/transport/chttp2/transport/bin_encoder.h",
     "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
diff --git a/build.yaml b/build.yaml
index 407b50ca7b..24f34ad77f 100644
--- a/build.yaml
+++ b/build.yaml
@@ -657,7 +657,7 @@ filegroups:
   - include/grpc/grpc_security.h
   - include/grpc/grpc_security_constants.h
   headers:
-  - third_party/objective_c/Cronet/cronet_c_for_grpc.h
+  - third_party/Cronet/bidirectional_stream_c.h
   src:
   - src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
   - src/core/ext/transport/cronet/transport/cronet_api_dummy.c
diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
index df1acddcc0..477cf07f45 100644
--- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
+++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
@@ -60,7 +60,7 @@ GRPCAPI grpc_channel *grpc_cronet_secure_channel_create(
   ct->host = gpr_malloc(strlen(target) + 1);
   strcpy(ct->host, target);
   gpr_log(GPR_DEBUG,
-          "grpc_create_cronet_transport: cronet_engine = %p, target=%s", engine,
+          "grpc_create_cronet_transport: stream_engine = %p, target=%s", engine,
           ct->host);
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/src/core/ext/transport/cronet/transport/cronet_api_dummy.c b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
index 687026c9fd..1c4253f43f 100644
--- a/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
+++ b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
@@ -38,48 +38,47 @@ library, so we can build it in all environments */
 
 #include <grpc/support/log.h>
 
-#include "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+#include "third_party/Cronet/bidirectional_stream_c.h"
 
 #ifdef GRPC_COMPILE_WITH_CRONET
 /* link with the real CRONET library in the build system */
 #else
 /* Dummy implementation of cronet API just to test for build-ability */
-cronet_bidirectional_stream* cronet_bidirectional_stream_create(
-    cronet_engine* engine, void* annotation,
-    cronet_bidirectional_stream_callback* callback) {
+bidirectional_stream* bidirectional_stream_create(
+    stream_engine* engine, void* annotation,
+    bidirectional_stream_callback* callback) {
   GPR_ASSERT(0);
   return NULL;
 }
 
-int cronet_bidirectional_stream_destroy(cronet_bidirectional_stream* stream) {
+int bidirectional_stream_destroy(bidirectional_stream* stream) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int cronet_bidirectional_stream_start(
-    cronet_bidirectional_stream* stream, const char* url, int priority,
-    const char* method, const cronet_bidirectional_stream_header_array* headers,
+int bidirectional_stream_start(
+    bidirectional_stream* stream, const char* url, int priority,
+    const char* method, const bidirectional_stream_header_array* headers,
     bool end_of_stream) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int cronet_bidirectional_stream_read(cronet_bidirectional_stream* stream,
-                                     char* buffer, int capacity) {
+int bidirectional_stream_read(bidirectional_stream* stream,
+                              char* buffer, int capacity) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int cronet_bidirectional_stream_write(cronet_bidirectional_stream* stream,
-                                      const char* buffer, int count,
-                                      bool end_of_stream) {
+int bidirectional_stream_write(bidirectional_stream* stream,
+                               const char* buffer, int count,
+                               bool end_of_stream) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int cronet_bidirectional_stream_cancel(cronet_bidirectional_stream* stream) {
+void bidirectional_stream_cancel(bidirectional_stream* stream) {
   GPR_ASSERT(0);
-  return 0;
 }
 
 #endif /* GRPC_COMPILE_WITH_CRONET */
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index a4c110101e..28c4fbe9fe 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -49,7 +49,7 @@
 #include "src/core/lib/transport/metadata_batch.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/transport_impl.h"
-#include "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+#include "third_party/Cronet/bidirectional_stream_c.h"
 
 #define GRPC_HEADER_SIZE_IN_BYTES 5
 
@@ -86,19 +86,19 @@ enum e_op_id {
 
 /* Cronet callbacks. See cronet_c_for_grpc.h for documentation for each. */
 
-static void on_request_headers_sent(cronet_bidirectional_stream *);
+static void on_request_headers_sent(bidirectional_stream *);
 static void on_response_headers_received(
-    cronet_bidirectional_stream *,
-    const cronet_bidirectional_stream_header_array *, const char *);
-static void on_write_completed(cronet_bidirectional_stream *, const char *);
-static void on_read_completed(cronet_bidirectional_stream *, char *, int);
+    bidirectional_stream *,
+    const bidirectional_stream_header_array *, const char *);
+static void on_write_completed(bidirectional_stream *, const char *);
+static void on_read_completed(bidirectional_stream *, char *, int);
 static void on_response_trailers_received(
-    cronet_bidirectional_stream *,
-    const cronet_bidirectional_stream_header_array *);
-static void on_succeeded(cronet_bidirectional_stream *);
-static void on_failed(cronet_bidirectional_stream *, int);
-static void on_canceled(cronet_bidirectional_stream *);
-static cronet_bidirectional_stream_callback cronet_callbacks = {
+    bidirectional_stream *,
+    const bidirectional_stream_header_array *);
+static void on_succeeded(bidirectional_stream *);
+static void on_failed(bidirectional_stream *, int);
+static void on_canceled(bidirectional_stream *);
+static bidirectional_stream_callback cronet_callbacks = {
     on_request_headers_sent,
     on_response_headers_received,
     on_read_completed,
@@ -111,7 +111,7 @@ static cronet_bidirectional_stream_callback cronet_callbacks = {
 /* Cronet transport object */
 struct grpc_cronet_transport {
   grpc_transport base; /* must be first element in this structure */
-  cronet_engine *engine;
+  stream_engine *engine;
   char *host;
 };
 typedef struct grpc_cronet_transport grpc_cronet_transport;
@@ -173,8 +173,8 @@ struct stream_obj {
   grpc_transport_stream_op *curr_op;
   grpc_cronet_transport curr_ct;
   grpc_stream *curr_gs;
-  cronet_bidirectional_stream *cbs;
-  cronet_bidirectional_stream_header_array header_array;
+  bidirectional_stream *cbs;
+  bidirectional_stream_header_array header_array;
 
   /* Stream level state. Some state will be tracked both at stream and stream_op
    * level */
@@ -335,11 +335,11 @@ static void execute_from_storage(stream_obj *s) {
 /*
   Cronet callback
 */
-static void on_failed(cronet_bidirectional_stream *stream, int net_error) {
+static void on_failed(bidirectional_stream *stream, int net_error) {
   CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error);
   stream_obj *s = (stream_obj *)stream->annotation;
   gpr_mu_lock(&s->mu);
-  cronet_bidirectional_stream_destroy(s->cbs);
+  bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_FAILED] = true;
   s->cbs = NULL;
   if (s->header_array.headers) {
@@ -358,11 +358,11 @@ static void on_failed(cronet_bidirectional_stream *stream, int net_error) {
 /*
   Cronet callback
 */
-static void on_canceled(cronet_bidirectional_stream *stream) {
+static void on_canceled(bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
   gpr_mu_lock(&s->mu);
-  cronet_bidirectional_stream_destroy(s->cbs);
+  bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_CANCELED] = true;
   s->cbs = NULL;
   if (s->header_array.headers) {
@@ -381,11 +381,11 @@ static void on_canceled(cronet_bidirectional_stream *stream) {
 /*
   Cronet callback
 */
-static void on_succeeded(cronet_bidirectional_stream *stream) {
+static void on_succeeded(bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
   gpr_mu_lock(&s->mu);
-  cronet_bidirectional_stream_destroy(s->cbs);
+  bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_SUCCEEDED] = true;
   s->cbs = NULL;
   free_read_buffer(s);
@@ -396,7 +396,7 @@ static void on_succeeded(cronet_bidirectional_stream *stream) {
 /*
   Cronet callback
 */
-static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
+static void on_request_headers_sent(bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
   gpr_mu_lock(&s->mu);
@@ -415,8 +415,8 @@ static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
   Cronet callback
 */
 static void on_response_headers_received(
-    cronet_bidirectional_stream *stream,
-    const cronet_bidirectional_stream_header_array *headers,
+    bidirectional_stream *stream,
+    const bidirectional_stream_header_array *headers,
     const char *negotiated_protocol) {
   CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
              headers, negotiated_protocol);
@@ -440,7 +440,7 @@ static void on_response_headers_received(
 /*
   Cronet callback
 */
-static void on_write_completed(cronet_bidirectional_stream *stream,
+static void on_write_completed(bidirectional_stream *stream,
                                const char *data) {
   stream_obj *s = (stream_obj *)stream->annotation;
   CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data);
@@ -457,7 +457,7 @@ static void on_write_completed(cronet_bidirectional_stream *stream,
 /*
   Cronet callback
 */
-static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
+static void on_read_completed(bidirectional_stream *stream, char *data,
                               int count) {
   stream_obj *s = (stream_obj *)stream->annotation;
   CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
@@ -468,9 +468,9 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
     s->state.rs.received_bytes += count;
     s->state.rs.remaining_bytes -= count;
     if (s->state.rs.remaining_bytes > 0) {
-      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+      CRONET_LOG(GPR_DEBUG, "bidirectional_stream_read(%p)", s->cbs);
       s->state.state_op_done[OP_READ_REQ_MADE] = true;
-      cronet_bidirectional_stream_read(
+      bidirectional_stream_read(
           s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
           s->state.rs.remaining_bytes);
       gpr_mu_unlock(&s->mu);
@@ -489,8 +489,8 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
   Cronet callback
 */
 static void on_response_trailers_received(
-    cronet_bidirectional_stream *stream,
-    const cronet_bidirectional_stream_header_array *trailers) {
+    bidirectional_stream *stream,
+    const bidirectional_stream_header_array *trailers) {
   CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream,
              trailers);
   stream_obj *s = (stream_obj *)stream->annotation;
@@ -543,7 +543,7 @@ static void create_grpc_frame(grpc_slice_buffer *write_slice_buffer,
 */
 static void convert_metadata_to_cronet_headers(
     grpc_linked_mdelem *head, const char *host, char **pp_url,
-    cronet_bidirectional_stream_header **pp_headers, size_t *p_num_headers,
+    bidirectional_stream_header **pp_headers, size_t *p_num_headers,
     const char **method) {
   grpc_linked_mdelem *curr = head;
   /* Walk the linked list and get number of header fields */
@@ -554,9 +554,9 @@ static void convert_metadata_to_cronet_headers(
   }
   /* Allocate enough memory. It is freed in the on_request_headers_sent callback
    */
-  cronet_bidirectional_stream_header *headers =
-      (cronet_bidirectional_stream_header *)gpr_malloc(
-          sizeof(cronet_bidirectional_stream_header) * num_headers_available);
+  bidirectional_stream_header *headers =
+      (bidirectional_stream_header *)gpr_malloc(
+          sizeof(bidirectional_stream_header) * num_headers_available);
   *pp_headers = headers;
 
   /* Walk the linked list again, this time copying the header fields.
@@ -788,9 +788,9 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     /* Start new cronet stream. It is destroyed in on_succeeded, on_canceled,
      * on_failed */
     GPR_ASSERT(s->cbs == NULL);
-    s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs,
-                                                &cronet_callbacks);
-    CRONET_LOG(GPR_DEBUG, "%p = cronet_bidirectional_stream_create()", s->cbs);
+    s->cbs = bidirectional_stream_create(s->curr_ct.engine, s->curr_gs,
+                                         &cronet_callbacks);
+    CRONET_LOG(GPR_DEBUG, "%p = bidirectional_stream_create()", s->cbs);
     char *url = NULL;
     const char *method = "POST";
     s->header_array.headers = NULL;
@@ -798,10 +798,10 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url,
         &s->header_array.headers, &s->header_array.count, &method);
     s->header_array.capacity = s->header_array.count;
-    CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_start(%p, %s)", s->cbs,
+    CRONET_LOG(GPR_DEBUG, "bidirectional_stream_start(%p, %s)", s->cbs,
                url);
-    cronet_bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array,
-                                      false);
+    bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array,
+                               false);
     stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true;
     result = ACTION_TAKEN_WITH_CALLBACK;
   } else if (stream_op->recv_initial_metadata &&
@@ -849,11 +849,11 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         size_t write_buffer_size;
         create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
                           &write_buffer_size);
-        CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, %p)",
+        CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, %p)",
                    s->cbs, stream_state->ws.write_buffer);
         stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
-        cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
-                                          (int)write_buffer_size, false);
+        bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
+                                   (int)write_buffer_size, false);
         result = ACTION_TAKEN_WITH_CALLBACK;
       } else {
         result = NO_ACTION_POSSIBLE;
@@ -893,11 +893,11 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
           GPR_ASSERT(stream_state->rs.read_buffer);
           stream_state->rs.remaining_bytes = stream_state->rs.length_field;
           stream_state->rs.received_bytes = 0;
-          CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+          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 */
-          cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
-                                           stream_state->rs.remaining_bytes);
+          bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
+                                    stream_state->rs.remaining_bytes);
           result = ACTION_TAKEN_WITH_CALLBACK;
         } else {
           stream_state->rs.remaining_bytes = 0;
@@ -918,11 +918,11 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         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;
-        CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+        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 */
-        cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
-                                         stream_state->rs.remaining_bytes);
+        bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
+                                  stream_state->rs.remaining_bytes);
         result = ACTION_TAKEN_WITH_CALLBACK;
       } else {
         result = NO_ACTION_POSSIBLE;
@@ -972,10 +972,10 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       result = NO_ACTION_POSSIBLE;
       CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
     } else {
-      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, 0)",
+      CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, 0)",
                  s->cbs);
       stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
-      cronet_bidirectional_stream_write(s->cbs, "", 0, true);
+      bidirectional_stream_write(s->cbs, "", 0, true);
       result = ACTION_TAKEN_WITH_CALLBACK;
     }
     stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true;
@@ -983,9 +983,9 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_CANCEL_ERROR)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_CANCEL_ERROR", oas);
-    CRONET_LOG(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs);
+    CRONET_LOG(GPR_DEBUG, "W: bidirectional_stream_cancel(%p)", s->cbs);
     if (s->cbs) {
-      cronet_bidirectional_stream_cancel(s->cbs);
+      bidirectional_stream_cancel(s->cbs);
     }
     stream_state->state_op_done[OP_CANCEL_ERROR] = true;
     result = ACTION_TAKEN_WITH_CALLBACK;
@@ -1064,9 +1064,9 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
       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 */
-    cronet_bidirectional_stream_header_array header_array;
-    cronet_bidirectional_stream_header *header;
-    cronet_bidirectional_stream cbs;
+    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");
@@ -1074,8 +1074,8 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
     header_array.count = 1;
     header_array.capacity = 1;
     header_array.headers =
-        gpr_malloc(sizeof(cronet_bidirectional_stream_header));
-    header = (cronet_bidirectional_stream_header *)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;
diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
index 2d8f7ac8fb..b9d286c929 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Cronet.h
+++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
@@ -43,13 +43,13 @@
 /**
  * This method should be called before issuing the first RPC. It should be
  * called only once. Create an instance of Cronet engine in your app elsewhere
- * and pass the instance pointer in the cronet_engine parameter. Once set,
+ * and pass the instance pointer in the stream_engine parameter. Once set,
  * all subsequent RPCs will use Cronet transport. The method is not thread
  * safe.
  */
-+(void)useCronetWithEngine:(cronet_engine *)engine;
++(void)useCronetWithEngine:(stream_engine *)engine;
 
-+(cronet_engine *)cronetEngine;
++(stream_engine *)cronetEngine;
 
 +(BOOL)isUsingCronet;
 
diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.m b/src/objective-c/GRPCClient/GRPCCall+Cronet.m
index 76ca1a2537..0e3598fb87 100644
--- a/src/objective-c/GRPCClient/GRPCCall+Cronet.m
+++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.m
@@ -35,16 +35,16 @@
 
 #ifdef GRPC_COMPILE_WITH_CRONET
 static BOOL useCronet = NO;
-static cronet_engine *globalCronetEngine;
+static stream_engine *globalCronetEngine;
 
 @implementation GRPCCall (Cronet)
 
-+ (void)useCronetWithEngine:(cronet_engine *)engine {
++ (void)useCronetWithEngine:(stream_engine *)engine {
   useCronet = YES;
   globalCronetEngine = engine;
 }
 
-+ (cronet_engine *)cronetEngine {
++ (stream_engine *)cronetEngine {
   return globalCronetEngine;
 }
 
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index e49aceefe1..2397c929f7 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -108,7 +108,7 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
 
 #ifdef GRPC_COMPILE_WITH_CRONET
 - (instancetype)initWithHost:(NSString *)host
-                cronetEngine:(cronet_engine *)cronetEngine
+                cronetEngine:(stream_engine *)cronetEngine
                  channelArgs:(NSDictionary *)channelArgs {
   if (!host) {
     [NSException raise:NSInvalidArgumentException format:@"host argument missing"];
@@ -163,7 +163,7 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
 #ifdef GRPC_COMPILE_WITH_CRONET
 + (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
                                  channelArgs:(NSDictionary *)channelArgs {
-  cronet_engine *engine = [GRPCCall cronetEngine];
+  stream_engine *engine = [GRPCCall cronetEngine];
   if (!engine) {
     [NSException raise:NSInvalidArgumentException
                 format:@"cronet_engine is NULL. Set it first."];
diff --git a/third_party/Cronet/bidirectional_stream_c.h b/third_party/Cronet/bidirectional_stream_c.h
new file mode 100644
index 0000000000..ffb235ae87
--- /dev/null
+++ b/third_party/Cronet/bidirectional_stream_c.h
@@ -0,0 +1,246 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_C_H_
+#define COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_C_H_
+
+#if defined(WIN32)
+#define GRPC_SUPPORT_EXPORT
+#else
+#define GRPC_SUPPORT_EXPORT __attribute__((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/* Engine API. */
+
+/* Opaque object representing a Bidirectional stream creating engine. Created
+ * and configured outside of this API to facilitate sharing with other
+ * components */
+typedef struct stream_engine {
+  void* obj;
+  void* annotation;
+} stream_engine;
+
+/* Bidirectional Stream API */
+
+/* Opaque object representing Bidirectional Stream. */
+typedef struct bidirectional_stream {
+  void* obj;
+  void* annotation;
+} bidirectional_stream;
+
+/* A single request or response header element. */
+typedef struct bidirectional_stream_header {
+  const char* key;
+  const char* value;
+} bidirectional_stream_header;
+
+/* Array of request or response headers or trailers. */
+typedef struct bidirectional_stream_header_array {
+  size_t count;
+  size_t capacity;
+  bidirectional_stream_header* headers;
+} bidirectional_stream_header_array;
+
+/* Set of callbacks used to receive callbacks from bidirectional stream. */
+typedef struct bidirectional_stream_callback {
+  /* Invoked when the stream is ready for reading and writing.
+   * Consumer may call bidirectional_stream_read() to start reading data.
+   * Consumer may call bidirectional_stream_write() to start writing
+   * data.
+   */
+  void (*on_stream_ready)(bidirectional_stream* stream);
+
+  /* Invoked when initial response headers are received.
+   * Consumer must call bidirectional_stream_read() to start reading.
+   * Consumer may call bidirectional_stream_write() to start writing or
+   * close the stream. Contents of |headers| is valid for duration of the call.
+   */
+  void (*on_response_headers_received)(
+      bidirectional_stream* stream,
+      const bidirectional_stream_header_array* headers,
+      const char* negotiated_protocol);
+
+  /* Invoked when data is read into the buffer passed to
+   * bidirectional_stream_read(). Only part of the buffer may be
+   * populated. To continue reading, call bidirectional_stream_read().
+   * It may be invoked after on_response_trailers_received()}, if there was
+   * pending read data before trailers were received.
+   *
+   * If |bytes_read| is 0, it means the remote side has signaled that it will
+   * send no more data; future calls to bidirectional_stream_read()
+   * will result in the on_data_read() callback or on_succeded() callback if
+   * bidirectional_stream_write() was invoked with end_of_stream set to
+   * true.
+   */
+  void (*on_read_completed)(bidirectional_stream* stream,
+                            char* data,
+                            int bytes_read);
+
+  /**
+   * Invoked when all data passed to bidirectional_stream_write() is
+   * sent. To continue writing, call bidirectional_stream_write().
+   */
+  void (*on_write_completed)(bidirectional_stream* stream, const char* data);
+
+  /* Invoked when trailers are received before closing the stream. Only invoked
+   * when server sends trailers, which it may not. May be invoked while there is
+   * read data remaining in local buffer. Contents of |trailers| is valid for
+   * duration of the call.
+   */
+  void (*on_response_trailers_received)(
+      bidirectional_stream* stream,
+      const bidirectional_stream_header_array* trailers);
+
+  /**
+   * Invoked when there is no data to be read or written and the stream is
+   * closed successfully remotely and locally. Once invoked, no further callback
+   * methods will be invoked.
+   */
+  void (*on_succeded)(bidirectional_stream* stream);
+
+  /**
+   * Invoked if the stream failed for any reason after
+   * bidirectional_stream_start(). HTTP/2 error codes are
+   * mapped to chrome net error codes. Once invoked, no further callback methods
+   * will be invoked.
+   */
+  void (*on_failed)(bidirectional_stream* stream, int net_error);
+
+  /**
+   * Invoked if the stream was canceled via
+   * bidirectional_stream_cancel(). Once invoked, no further callback
+   * methods will be invoked.
+   */
+  void (*on_canceled)(bidirectional_stream* stream);
+} bidirectional_stream_callback;
+
+/* Creates a new stream object that uses |engine| and |callback|. All stream
+ * tasks are performed asynchronously on the |engine| network thread. |callback|
+ * methods are invoked synchronously on the |engine| network thread, but must
+ * not run tasks on the current thread to prevent blocking networking operations
+ * and causing exceptions during shutdown. The |annotation| is stored in
+ * bidirectional stream for arbitrary use by application.
+ *
+ * Returned |bidirectional_stream*| is owned by the caller, and must be
+ * destroyed using |bidirectional_stream_destroy|.
+ *
+ * Both |calback| and |engine| must remain valid until stream is destroyed.
+ */
+GRPC_SUPPORT_EXPORT
+bidirectional_stream* bidirectional_stream_create(
+    stream_engine* engine,
+    void* annotation,
+    bidirectional_stream_callback* callback);
+
+/* TBD: The following methods return int. Should it be a custom type? */
+
+/* Destroys stream object. Destroy could be called from any thread, including
+ * network thread, but is posted, so |stream| is valid until calling task is
+ * complete.
+ */
+GRPC_SUPPORT_EXPORT
+int bidirectional_stream_destroy(bidirectional_stream* stream);
+
+/**
+ * Disables or enables auto flush. By default, data is flushed after
+ * every bidirectional_stream_write(). If the auto flush is disabled,
+ * the client should explicitly call bidirectional_stream_flush to flush
+ * the data.
+ */
+GRPC_SUPPORT_EXPORT void bidirectional_stream_disable_auto_flush(
+    bidirectional_stream* stream,
+    bool disable_auto_flush);
+
+/**
+ * Delays sending request headers until bidirectional_stream_flush()
+ * is called. This flag is currently only respected when QUIC is negotiated.
+ * When true, QUIC will send request header frame along with data frame(s)
+ * as a single packet when possible.
+ */
+GRPC_SUPPORT_EXPORT
+void bidirectional_stream_delay_request_headers_until_flush(
+    bidirectional_stream* stream,
+    bool delay_headers_until_flush);
+
+/* Starts the stream by sending request to |url| using |method| and |headers|.
+ * If |end_of_stream| is true, then no data is expected to be written. The
+ * |method| is HTTP verb, with PUT having a special meaning to mark idempotent
+ * request, which could use QUIC 0-RTT.
+ */
+GRPC_SUPPORT_EXPORT
+int bidirectional_stream_start(bidirectional_stream* stream,
+                               const char* url,
+                               int priority,
+                               const char* method,
+                               const bidirectional_stream_header_array* headers,
+                               bool end_of_stream);
+
+/* Reads response data into |buffer| of |capacity| length. Must only be called
+ * at most once in response to each invocation of the
+ * on_stream_ready()/on_response_headers_received() and on_read_completed()
+ * methods of the bidirectional_stream_callback.
+ * Each call will result in an invocation of the callback's
+ * on_read_completed() method if data is read, or its on_failed() method if
+ * there's an error. The callback's on_succeeded() method is also invoked if
+ * there is no more data to read and |end_of_stream| was previously sent.
+ */
+GRPC_SUPPORT_EXPORT
+int bidirectional_stream_read(bidirectional_stream* stream,
+                              char* buffer,
+                              int capacity);
+
+/* Writes request data from |buffer| of |buffer_length| length. If auto flush is
+ * disabled, data will be sent only after bidirectional_stream_flush() is
+ * called.
+ * Each call will result in an invocation the callback's on_write_completed()
+ * method if data is sent, or its on_failed() method if there's an error.
+ * The callback's on_succeeded() method is also invoked if |end_of_stream| is
+ * set and all response data has been read.
+ */
+GRPC_SUPPORT_EXPORT
+int bidirectional_stream_write(bidirectional_stream* stream,
+                               const char* buffer,
+                               int buffer_length,
+                               bool end_of_stream);
+
+/**
+ * Flushes pending writes. This method should not be called before invocation of
+ * on_stream_ready() method of the bidirectional_stream_callback.
+ * For each previously called bidirectional_stream_write()
+ * a corresponding on_write_completed() callback will be invoked when the buffer
+ * is sent.
+ */
+GRPC_SUPPORT_EXPORT
+void bidirectional_stream_flush(bidirectional_stream* stream);
+
+/* Cancels the stream. Can be called at any time after
+ * bidirectional_stream_start(). The on_canceled() method of
+ * bidirectional_stream_callback will be invoked when cancelation
+ * is complete and no further callback methods will be invoked. If the
+ * stream has completed or has not started, calling
+ * bidirectional_stream_cancel() has no effect and on_canceled() will not
+ * be invoked. At most one callback method may be invoked after
+ * bidirectional_stream_cancel() has completed.
+ */
+GRPC_SUPPORT_EXPORT
+void bidirectional_stream_cancel(bidirectional_stream* stream);
+
+/* Returns true if the |stream| was successfully started and is now done
+ * (succeeded, canceled, or failed).
+ * Returns false if the |stream| stream is not yet started or is in progress.
+ */
+GRPC_SUPPORT_EXPORT
+bool bidirectional_stream_is_done(bidirectional_stream* stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // COMPONENTS_GRPC_SUPPORT_INCLUDE_BIDIRECTIONAL_STREAM_H_
diff --git a/third_party/objective_c/Cronet/cronet_c_for_grpc.h b/third_party/objective_c/Cronet/cronet_c_for_grpc.h
deleted file mode 100644
index 15a511aebd..0000000000
--- a/third_party/objective_c/Cronet/cronet_c_for_grpc.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
-#define COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-/* Cronet Engine API. */
-
-/* Opaque object representing Cronet Engine. Created and configured outside
- * of this API to facilitate sharing with other components */
-typedef struct cronet_engine { void* obj; } cronet_engine;
-
-void cronet_engine_add_quic_hint(cronet_engine* engine,
-                                 const char* host,
-                                 int port,
-                                 int alternate_port);
-
-/* Cronet Bidirectional Stream API */
-
-/* Opaque object representing Cronet Bidirectional Stream. */
-typedef struct cronet_bidirectional_stream {
-  void* obj;
-  void* annotation;
-} cronet_bidirectional_stream;
-
-/* A single request or response header element. */
-typedef struct cronet_bidirectional_stream_header {
-  const char* key;
-  const char* value;
-} cronet_bidirectional_stream_header;
-
-/* Array of request or response headers or trailers. */
-typedef struct cronet_bidirectional_stream_header_array {
-  size_t count;
-  size_t capacity;
-  cronet_bidirectional_stream_header* headers;
-} cronet_bidirectional_stream_header_array;
-
-/* Set of callbacks used to receive callbacks from bidirectional stream. */
-typedef struct cronet_bidirectional_stream_callback {
-  /* Invoked when request headers are sent. Indicates that stream has initiated
-   * the request. Consumer may call cronet_bidirectional_stream_write() to start
-   * writing data.
-   */
-  void (*on_request_headers_sent)(cronet_bidirectional_stream* stream);
-
-  /* Invoked when initial response headers are received.
-   * Consumer must call cronet_bidirectional_stream_read() to start reading.
-   * Consumer may call cronet_bidirectional_stream_write() to start writing or
-   * close the stream. Contents of |headers| is valid for duration of the call.
-   */
-  void (*on_response_headers_received)(
-      cronet_bidirectional_stream* stream,
-      const cronet_bidirectional_stream_header_array* headers,
-      const char* negotiated_protocol);
-
-  /* Invoked when data is read into the buffer passed to
-   * cronet_bidirectional_stream_read(). Only part of the buffer may be
-   * populated. To continue reading, call cronet_bidirectional_stream_read().
-   * It may be invoked after on_response_trailers_received()}, if there was
-   * pending read data before trailers were received.
-   *
-   * If count is 0, it means the remote side has signaled that it will send no
-   * more data; future calls to cronet_bidirectional_stream_read() will result
-   * in the on_data_read() callback or on_succeded() callback if
-   * cronet_bidirectional_stream_write() was invoked with end_of_stream set to
-   * true.
-   */
-  void (*on_read_completed)(cronet_bidirectional_stream* stream,
-                            char* data,
-                            int count);
-
-  /**
-   * Invoked when all data passed to cronet_bidirectional_stream_write() is
-   * sent.
-   * To continue writing, call cronet_bidirectional_stream_write().
-   */
-  void (*on_write_completed)(cronet_bidirectional_stream* stream,
-                             const char* data);
-
-  /* Invoked when trailers are received before closing the stream. Only invoked
-   * when server sends trailers, which it may not. May be invoked while there is
-   * read data remaining in local buffer. Contents of |trailers| is valid for
-   * duration of the call.
-   */
-  void (*on_response_trailers_received)(
-      cronet_bidirectional_stream* stream,
-      const cronet_bidirectional_stream_header_array* trailers);
-
-  /**
-   * Invoked when there is no data to be read or written and the stream is
-   * closed successfully remotely and locally. Once invoked, no further callback
-   * methods will be invoked.
-   */
-  void (*on_succeded)(cronet_bidirectional_stream* stream);
-
-  /**
-   * Invoked if the stream failed for any reason after
-   * cronet_bidirectional_stream_start(). HTTP/2 error codes are
-   * mapped to chrome net error codes. Once invoked, no further callback methods
-   * will be invoked.
-   */
-  void (*on_failed)(cronet_bidirectional_stream* stream, int net_error);
-
-  /**
-   * Invoked if the stream was canceled via
-   * cronet_bidirectional_stream_cancel(). Once invoked, no further callback
-   * methods will be invoked.
-   */
-  void (*on_canceled)(cronet_bidirectional_stream* stream);
-} cronet_bidirectional_stream_callback;
-
-/* Create a new stream object that uses |engine| and |callback|. All stream
- * tasks are performed asynchronously on the |engine| network thread. |callback|
- * methods are invoked synchronously on the |engine| network thread, but must
- * not run tasks on the current thread to prevent blocking networking operations
- * and causing exceptions during shutdown. The |annotation| is stored in
- * bidirectional stream for arbitrary use by application.
- *
- * Returned |cronet_bidirectional_stream*| is owned by the caller, and must be
- * destroyed using |cronet_bidirectional_stream_destroy|.
- *
- * Both |calback| and |engine| must remain valid until stream is destroyed.
- */
-cronet_bidirectional_stream* cronet_bidirectional_stream_create(
-    cronet_engine* engine,
-    void* annotation,
-    cronet_bidirectional_stream_callback* callback);
-
-/* TBD: The following methods return int. Should it be a custom type? */
-
-/* Destroy stream object. Destroy could be called from any thread, including
- * network thread, but is posted, so |stream| is valid until calling task is
- * complete.
- */
-int cronet_bidirectional_stream_destroy(cronet_bidirectional_stream* stream);
-
-/* Start the stream by sending request to |url| using |method| and |headers|. If
- * |end_of_stream| is true, then no data is expected to be written.
- */
-int cronet_bidirectional_stream_start(
-    cronet_bidirectional_stream* stream,
-    const char* url,
-    int priority,
-    const char* method,
-    const cronet_bidirectional_stream_header_array* headers,
-    bool end_of_stream);
-
-/* Read response data into |buffer| of |capacity| length. Must only be called at
- * most once in response to each invocation of the
- * on_response_headers_received() and on_read_completed() methods of the
- * cronet_bidirectional_stream_callback.
- * Each call will result in an invocation of one of the callback's
- * on_read_completed  method if data is read, its on_succeeded() method if
- * the stream is closed, or its on_failed() method if there's an error.
- */
-int cronet_bidirectional_stream_read(cronet_bidirectional_stream* stream,
-                                     char* buffer,
-                                     int capacity);
-
-/* Read response data into |buffer| of |capacity| length. Must only be called at
- * most once in response to each invocation of the
- * on_response_headers_received() and on_read_completed() methods of the
- * cronet_bidirectional_stream_callback.
- * Each call will result in an invocation of one of the callback's
- * on_read_completed  method if data is read, its on_succeeded() method if
- * the stream is closed, or its on_failed() method if there's an error.
- */
-int cronet_bidirectional_stream_write(cronet_bidirectional_stream* stream,
-                                      const char* buffer,
-                                      int count,
-                                      bool end_of_stream);
-
-/* Cancels the stream. Can be called at any time after
- * cronet_bidirectional_stream_start(). The on_canceled() method of
- * cronet_bidirectional_stream_callback will be invoked when cancelation
- * is complete and no further callback methods will be invoked. If the
- * stream has completed or has not started, calling
- * cronet_bidirectional_stream_cancel() has no effect and on_canceled() will not
- * be  invoked. At most one callback method may be invoked after
- * cronet_bidirectional_stream_cancel() has completed.
- */
-int cronet_bidirectional_stream_cancel(cronet_bidirectional_stream* stream);
-
-/* Returns true if the |stream| was successfully started and is now done
- * (succeeded, canceled, or failed).
- * Returns false if the |stream| stream is not yet started or is in progress.
- */
-bool cronet_bidirectional_stream_is_done(cronet_bidirectional_stream* stream);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 9be07941d7..fc60910259 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -7504,7 +7504,7 @@
       "include/grpc/grpc_cronet.h", 
       "include/grpc/grpc_security.h", 
       "include/grpc/grpc_security_constants.h", 
-      "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+      "third_party/Cronet/bidirectional_stream_c.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
-- 
GitLab


From 0c2fb6a2a428b76c931f3795ce53e0794dbfdccd Mon Sep 17 00:00:00 2001
From: Garrett Casto <gcasto@chromium.org>
Date: Tue, 22 Nov 2016 11:14:39 -0800
Subject: [PATCH 057/344] Fix CoreCronetEnd2EndTests

---
 .../tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
index 4a92cc8e0d..40a18a5aa5 100644
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
@@ -94,7 +94,7 @@ static void process_auth_failure(void *state, grpc_auth_context *ctx,
 
 static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
                                                 grpc_channel_args *client_args,
-                                                cronet_engine *cronetEngine) {
+                                                stream_engine *cronetEngine) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr,
                                                 client_args, NULL);
@@ -124,7 +124,7 @@ static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
 
 static void cronet_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  cronet_engine *cronetEngine = [Cronet getGlobalEngine];
+  stream_engine *cronetEngine = [Cronet getGlobalEngine];
 
   grpc_channel_args *new_client_args = grpc_channel_args_copy(client_args);
   cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine);
-- 
GitLab


From a7f03f64234c496750bac5c72a7d3601e5e2a8ba Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Mon, 28 Nov 2016 11:29:19 -0800
Subject: [PATCH 058/344] Advance objective c version to v1.0.2

---
 gRPC-Core.podspec                                 | 6 ++++--
 gRPC-ProtoRPC.podspec                             | 4 ++--
 gRPC-RxLibrary.podspec                            | 4 ++--
 gRPC.podspec                                      | 2 +-
 src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 7 +++++--
 src/objective-c/GRPCClient/private/GRPCHost.m     | 2 +-
 templates/gRPC-Core.podspec.template              | 6 ++++--
 7 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index b81b2eacda..d49addb1f5 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -35,7 +35,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.0.1'
+  version = '1.0.2'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'http://www.grpc.io'
@@ -44,7 +44,9 @@ Pod::Spec.new do |s|
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "v#{version}",
+    # TODO(mxyan): Change back to "v#{version}" for next release
+    #:tag => "v#{version}",
+    :tag => "objective-c-v#{version}",
     # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
     :submodules => true,
   }
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 61d4b62d39..62eaa2aaf7 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.0.1'
+  version = '1.0.2'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "v#{version}",
+    :tag => "objective-c-v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index d59385c039..2e8fffd2f1 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.0.1'
+  version = '1.0.2'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "v#{version}",
+    :tag => "objective-c-v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
diff --git a/gRPC.podspec b/gRPC.podspec
index 76410b17d2..bbec1ffffa 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.0.1'
+  version = '1.0.2'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'http://www.grpc.io'
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 6e594fd3ed..bcc2bb6126 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -36,7 +36,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.0.1'
+  v = '1.0.2'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
@@ -84,7 +84,10 @@ Pod::Spec.new do |s|
   repo = 'grpc/grpc'
   file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
   s.source = {
-    :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
+    # TODO(mxyan): Change back to "https://github.com/#{repo}/releases/download/v#{v}/#{file}" for
+    # next release
+    # :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
+    :http => "https://github.com/#{repo}/releases/download/objective-c-v#{v}/#{file}",
     # TODO(jcanizales): Add sha1 or sha256
     # :sha1 => '??',
   }
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 4e09b39da5..70a5aad8f3 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 // TODO(jcanizales): Generate the version in a standalone header, from templates. Like
 // templates/src/core/surface/version.c.template .
-#define GRPC_OBJC_VERSION_STRING @"1.0.1"
+#define GRPC_OBJC_VERSION_STRING @"1.0.2"
 
 static NSMutableDictionary *kHostCache;
 
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index f3bb7347b4..6b949b6c6f 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -62,7 +62,7 @@
   %>
   Pod::Spec.new do |s|
     s.name     = 'gRPC-Core'
-    version = '1.0.1'
+    version = '1.0.2'
     s.version  = version
     s.summary  = 'Core cross-platform gRPC library, written in C'
     s.homepage = 'http://www.grpc.io'
@@ -71,7 +71,9 @@
 
     s.source = {
       :git => 'https://github.com/grpc/grpc.git',
-      :tag => "v#{version}",
+      # TODO(mxyan): Change back to "v#{version}" for next release
+      #:tag => "v#{version}",
+      :tag => "objective-c-v#{version}",
       # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
       :submodules => true,
     }
-- 
GitLab


From de30b0ae3688c8956ce520e4a6e67bdabe173490 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Mon, 28 Nov 2016 12:03:07 -0800
Subject: [PATCH 059/344] missing file

---
 gRPC.podspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gRPC.podspec b/gRPC.podspec
index bbec1ffffa..e8b7709449 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "v#{version}",
+    :tag => "objective-c-v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
-- 
GitLab


From 07639b972538dda9bebfad2e0da95d99da42b91f Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Mon, 28 Nov 2016 14:26:11 -0800
Subject: [PATCH 060/344] Drop support for Node 0.12 and io.js 1.0

---
 tools/run_tests/build_artifact_node.bat | 2 +-
 tools/run_tests/build_artifact_node.sh  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/run_tests/build_artifact_node.bat b/tools/run_tests/build_artifact_node.bat
index 57d55ef19e..833cb8171d 100644
--- a/tools/run_tests/build_artifact_node.bat
+++ b/tools/run_tests/build_artifact_node.bat
@@ -27,7 +27,7 @@
 @rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
+set node_versions=1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
 
 set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
 
diff --git a/tools/run_tests/build_artifact_node.sh b/tools/run_tests/build_artifact_node.sh
index 9d06472aa4..6a9caa9ca9 100755
--- a/tools/run_tests/build_artifact_node.sh
+++ b/tools/run_tests/build_artifact_node.sh
@@ -42,7 +42,7 @@ mkdir -p artifacts
 
 npm update
 
-node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
+node_versions=( 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
 
 for version in ${node_versions[@]}
 do
-- 
GitLab


From 6002b8ff63b46afc8abb34081423692e2f02d2b3 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Mon, 28 Nov 2016 17:41:13 -0800
Subject: [PATCH 061/344] add ruby subclasses of bad status for each GPRC
 status code

---
 src/ruby/lib/grpc/errors.rb        | 126 ++++++++++++++++++++++++++++-
 src/ruby/spec/error_sanity_spec.rb |  58 +++++++++++++
 2 files changed, 182 insertions(+), 2 deletions(-)
 create mode 100644 src/ruby/spec/error_sanity_spec.rb

diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 23b2bb7e12..022a14b0a5 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -35,6 +35,13 @@ module GRPC
   # either end of a GRPC connection.  When raised, it indicates that a status
   # error should be returned to the other end of a GRPC connection; when
   # caught it means that this end received a status error.
+  #
+  # There is also subclass of BadStatus in this module for each GRPC status.
+  # E.g., the GRPC::Cancelled class corresponds to status CANCELLED.
+  #
+  # See
+  # https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/status.h
+  # for detailed descriptions of each status code.
   class BadStatus < StandardError
     attr_reader :code, :details, :metadata
 
@@ -57,7 +64,122 @@ module GRPC
     end
   end
 
-  # Cancelled is an exception class that indicates that an rpc was cancelled.
-  class Cancelled < StandardError
+  # GRPC status code corresponding to status OK
+  class Ok < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::OK, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status CANCELLED
+  class Cancelled < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::CANCELLED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status UNKNOWN
+  class Unknown < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::UNKNOWN, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status INVALID_ARGUMENT
+  class InvalidArgument < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::INVALID_ARGUMENT, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status DEADLINE_EXCEEDED
+  class DeadlineExceeded < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::DEADLINE_EXCEEDED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status NOT_FOUND
+  class NotFound < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::NOT_FOUND, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status ALREADY_EXISTS
+  class AlreadyExists < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::ALREADY_EXISTS, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status PERMISSION_DENIED
+  class PermissionDenied < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::PERMISSION_DENIED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status UNAUTHENTICATED
+  class Unauthenticated < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::UNAUTHENTICATED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status RESOURCE_EXHAUSTED
+  class ResourceExhausted < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::RESOURCE_EXHAUSTED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status FAILED_PRECONDITION
+  class FailedPrecondition < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::FAILED_PRECONDITION, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status ABORTED
+  class Aborted < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::ABORTED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status OUT_OF_RANGE
+  class OutOfRange < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::OUT_OF_RANGE, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status UNIMPLEMENTED
+  class Unimplemented < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::UNIMPLEMENTED, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status INTERNAL
+  class Internal < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::INTERNAL, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status UNAVAILABLE
+  class Unavailable < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::UNAVAILABLE, details, metadata)
+    end
+  end
+
+  # GRPC status code corresponding to status DATA_LOSS
+  class DataLoss < BadStatus
+    def initialize(details = 'unknown cause', metadata = {})
+      super(Core::StatusCodes::DATA_LOSS, details, metadata)
+    end
   end
 end
diff --git a/src/ruby/spec/error_sanity_spec.rb b/src/ruby/spec/error_sanity_spec.rb
new file mode 100644
index 0000000000..97712104fe
--- /dev/null
+++ b/src/ruby/spec/error_sanity_spec.rb
@@ -0,0 +1,58 @@
+# 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.
+
+require 'grpc'
+
+StatusCodes = GRPC::Core::StatusCodes
+
+describe StatusCodes do
+  # convert upper snake-case to camel case.
+  # e.g., DEADLINE_EXCEEDED -> DeadlineExceeded
+  def upper_snake_to_camel(name)
+    name.to_s.split('_').map(&:downcase).map(&:capitalize).join('')
+  end
+
+  StatusCodes.constants.each do |status_name|
+    it 'there is a subclass of BadStatus corresponding to StatusCode: ' \
+      "#{name} that has code: #{StatusCodes.const_get(status_name)}" do
+      camel_case = upper_snake_to_camel(status_name)
+      error_class = GRPC.const_get(camel_case)
+      # expect the error class to be a subclass of BadStatus
+      expect(error_class < GRPC::BadStatus)
+
+      error_object = error_class.new
+      # check that the code matches the int value of the error's constant
+      expect(error_object.code).to eq(StatusCodes.const_get(status_name))
+
+      # check default parameters
+      expect(error_object.details).to eq('unknown cause')
+      expect(error_object.metadata).to eq({})
+    end
+  end
+end
-- 
GitLab


From e62605f41e00c3e4652e0a7ad19846d8995a101f Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Tue, 29 Nov 2016 16:31:36 +0000
Subject: [PATCH 062/344] Fix error handling in channel initialization.

---
 src/core/lib/channel/channel_stack_builder.c |  21 ++--
 src/core/lib/surface/channel.c               | 113 +++++++++----------
 test/core/surface/channel_create_test.c      |  12 ++
 3 files changed, 82 insertions(+), 64 deletions(-)

diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index dd11e5bf6b..f54eac06ec 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -259,14 +259,21 @@ grpc_error *grpc_channel_stack_builder_finish(
       destroy_arg == NULL ? *result : destroy_arg, filters, num_filters,
       builder->args, builder->transport, builder->name, channel_stack);
 
-  // run post-initialization functions
-  i = 0;
-  for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
-    if (p->init != NULL) {
-      p->init(channel_stack, grpc_channel_stack_element(channel_stack, i),
-              p->init_arg);
+  if (error != GRPC_ERROR_NONE) {
+    grpc_channel_stack_destroy(exec_ctx, channel_stack);
+    gpr_free(*result);
+    *result = NULL;
+  } else {
+    // run post-initialization functions
+    i = 0;
+    for (filter_node *p = builder->begin.next; p != &builder->end;\
+         p = p->next) {
+      if (p->init != NULL) {
+        p->init(channel_stack, grpc_channel_stack_element(channel_stack, i),
+                p->init_arg);
+      }
+      i++;
     }
-    i++;
   }
 
   grpc_channel_stack_builder_destroy(builder);
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 22bb55c7b4..72e64a2076 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -86,92 +86,91 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                                   const grpc_channel_args *input_args,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport *optional_transport) {
-  bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
-
   grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
   grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
   grpc_channel_stack_builder_set_target(builder, target);
   grpc_channel_stack_builder_set_transport(builder, optional_transport);
-  grpc_channel *channel;
-  grpc_channel_args *args;
   if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
     grpc_channel_stack_builder_destroy(builder);
     return NULL;
   }
-  args = grpc_channel_args_copy(
+  grpc_channel_args *args = grpc_channel_args_copy(
       grpc_channel_stack_builder_get_channel_arguments(builder));
+  grpc_channel *channel;
   grpc_error *error = grpc_channel_stack_builder_finish(
       exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
       (void **)&channel);
   if (error != GRPC_ERROR_NONE) {
-    grpc_channel_stack_destroy(exec_ctx, (grpc_channel_stack *)channel);
-    gpr_free(channel);
-    return NULL;
+    const char* msg = grpc_error_string(error);
+    gpr_log(GPR_ERROR, "channel stack builder failed: %s", msg);
+    grpc_error_free_string(msg);
+    GRPC_ERROR_UNREF(error);
+    goto done;
   }
 
   memset(channel, 0, sizeof(*channel));
   channel->target = gpr_strdup(target);
-  channel->is_client = is_client;
+  channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
   gpr_mu_init(&channel->registered_call_mu);
   channel->registered_calls = NULL;
 
   grpc_compression_options_init(&channel->compression_options);
-  if (args) {
-    for (size_t i = 0; i < args->num_args; i++) {
-      if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
-        if (args->args[i].type != GRPC_ARG_STRING) {
-          gpr_log(GPR_ERROR, "%s ignored: it must be a string",
-                  GRPC_ARG_DEFAULT_AUTHORITY);
-        } else {
-          if (channel->default_authority) {
-            /* setting this takes precedence over anything else */
-            GRPC_MDELEM_UNREF(channel->default_authority);
-          }
-          channel->default_authority = grpc_mdelem_from_strings(
-              ":authority", args->args[i].value.string);
+
+  for (size_t i = 0; i < args->num_args; i++) {
+    if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
+      if (args->args[i].type != GRPC_ARG_STRING) {
+        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
+                GRPC_ARG_DEFAULT_AUTHORITY);
+      } else {
+        if (channel->default_authority) {
+          /* setting this takes precedence over anything else */
+          GRPC_MDELEM_UNREF(channel->default_authority);
         }
-      } else if (0 ==
-                 strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
-        if (args->args[i].type != GRPC_ARG_STRING) {
-          gpr_log(GPR_ERROR, "%s ignored: it must be a string",
+        channel->default_authority = grpc_mdelem_from_strings(
+            ":authority", args->args[i].value.string);
+      }
+    } else if (0 ==
+               strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
+      if (args->args[i].type != GRPC_ARG_STRING) {
+        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
+                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
+      } else {
+        if (channel->default_authority) {
+          /* other ways of setting this (notably ssl) take precedence */
+          gpr_log(GPR_ERROR,
+                  "%s ignored: default host already set some other way",
                   GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
         } else {
-          if (channel->default_authority) {
-            /* other ways of setting this (notably ssl) take precedence */
-            gpr_log(GPR_ERROR,
-                    "%s ignored: default host already set some other way",
-                    GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
-          } else {
-            channel->default_authority = grpc_mdelem_from_strings(
-                ":authority", args->args[i].value.string);
-          }
+          channel->default_authority = grpc_mdelem_from_strings(
+              ":authority", args->args[i].value.string);
         }
-      } else if (0 == strcmp(args->args[i].key,
-                             GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
-        channel->compression_options.default_level.is_set = true;
-        GPR_ASSERT(args->args[i].value.integer >= 0 &&
-                   args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
-        channel->compression_options.default_level.level =
-            (grpc_compression_level)args->args[i].value.integer;
-      } else if (0 == strcmp(args->args[i].key,
-                             GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
-        channel->compression_options.default_algorithm.is_set = true;
-        GPR_ASSERT(args->args[i].value.integer >= 0 &&
-                   args->args[i].value.integer <
-                       GRPC_COMPRESS_ALGORITHMS_COUNT);
-        channel->compression_options.default_algorithm.algorithm =
-            (grpc_compression_algorithm)args->args[i].value.integer;
-      } else if (0 ==
-                 strcmp(args->args[i].key,
-                        GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
-        channel->compression_options.enabled_algorithms_bitset =
-            (uint32_t)args->args[i].value.integer |
-            0x1; /* always support no compression */
       }
+    } else if (0 == strcmp(args->args[i].key,
+                           GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
+      channel->compression_options.default_level.is_set = true;
+      GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                 args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
+      channel->compression_options.default_level.level =
+          (grpc_compression_level)args->args[i].value.integer;
+    } else if (0 == strcmp(args->args[i].key,
+                           GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
+      channel->compression_options.default_algorithm.is_set = true;
+      GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                 args->args[i].value.integer <
+                     GRPC_COMPRESS_ALGORITHMS_COUNT);
+      channel->compression_options.default_algorithm.algorithm =
+          (grpc_compression_algorithm)args->args[i].value.integer;
+    } else if (0 ==
+               strcmp(args->args[i].key,
+                      GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
+      channel->compression_options.enabled_algorithms_bitset =
+          (uint32_t)args->args[i].value.integer |
+          0x1; /* always support no compression */
     }
-    grpc_channel_args_destroy(args);
   }
 
+done:
+  grpc_channel_args_destroy(args);
   return channel;
 }
 
diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c
index ad7970aab9..654e5324d9 100644
--- a/test/core/surface/channel_create_test.c
+++ b/test/core/surface/channel_create_test.c
@@ -31,9 +31,14 @@
  *
  */
 
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
+
 #include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/surface/channel.h"
 #include "test/core/util/test_config.h"
 
 void test_unknown_scheme_target(void) {
@@ -44,6 +49,13 @@ void test_unknown_scheme_target(void) {
 
   chan = grpc_insecure_channel_create("blah://blah", NULL, NULL);
   GPR_ASSERT(chan != NULL);
+
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_channel_element *elem =
+      grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0);
+  GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client"));
+  grpc_exec_ctx_finish(&exec_ctx);
+
   grpc_channel_destroy(chan);
 }
 
-- 
GitLab


From d6c93802fff2dc3db004828a6ea4ff5b25383ee4 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 29 Nov 2016 09:17:57 -0800
Subject: [PATCH 063/344] Update package.json with version compatibility
 changes

---
 package.json                    | 2 +-
 templates/package.json.template | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 5506e9bbdf..6fd799cbab 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,7 @@
     "poisson-process": "^0.2.1"
   },
   "engines": {
-    "node": ">=0.12.0"
+    "node": ">=1.1.0"
   },
   "binary": {
     "module_name": "grpc_node",
diff --git a/templates/package.json.template b/templates/package.json.template
index 81f39d27f5..eb85c06590 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -52,7 +52,7 @@
       "poisson-process": "^0.2.1"
     },
     "engines": {
-      "node": ">=0.12.0"
+      "node": ">=1.1.0"
     },
     "binary": {
       "module_name": "grpc_node",
-- 
GitLab


From 33fdafbf18bc3f80bfddf998facefc6c9dd9f456 Mon Sep 17 00:00:00 2001
From: Garrett Casto <gcasto@chromium.org>
Date: Tue, 29 Nov 2016 11:32:03 -0800
Subject: [PATCH 064/344] clang-format

---
 .../cronet/transport/cronet_transport.c       | 26 +++++++------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 28c4fbe9fe..084532ea83 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -88,13 +88,12 @@ enum e_op_id {
 
 static void on_request_headers_sent(bidirectional_stream *);
 static void on_response_headers_received(
-    bidirectional_stream *,
-    const bidirectional_stream_header_array *, const char *);
+    bidirectional_stream *, const bidirectional_stream_header_array *,
+    const char *);
 static void on_write_completed(bidirectional_stream *, const char *);
 static void on_read_completed(bidirectional_stream *, char *, int);
 static void on_response_trailers_received(
-    bidirectional_stream *,
-    const bidirectional_stream_header_array *);
+    bidirectional_stream *, const bidirectional_stream_header_array *);
 static void on_succeeded(bidirectional_stream *);
 static void on_failed(bidirectional_stream *, int);
 static void on_canceled(bidirectional_stream *);
@@ -440,8 +439,7 @@ static void on_response_headers_received(
 /*
   Cronet callback
 */
-static void on_write_completed(bidirectional_stream *stream,
-                               const char *data) {
+static void on_write_completed(bidirectional_stream *stream, const char *data) {
   stream_obj *s = (stream_obj *)stream->annotation;
   CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data);
   gpr_mu_lock(&s->mu);
@@ -798,10 +796,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url,
         &s->header_array.headers, &s->header_array.count, &method);
     s->header_array.capacity = s->header_array.count;
-    CRONET_LOG(GPR_DEBUG, "bidirectional_stream_start(%p, %s)", s->cbs,
-               url);
-    bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array,
-                               false);
+    CRONET_LOG(GPR_DEBUG, "bidirectional_stream_start(%p, %s)", s->cbs, url);
+    bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array, false);
     stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true;
     result = ACTION_TAKEN_WITH_CALLBACK;
   } else if (stream_op->recv_initial_metadata &&
@@ -849,8 +845,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
         size_t write_buffer_size;
         create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
                           &write_buffer_size);
-        CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, %p)",
-                   s->cbs, stream_state->ws.write_buffer);
+        CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, %p)", s->cbs,
+                   stream_state->ws.write_buffer);
         stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
         bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
                                    (int)write_buffer_size, false);
@@ -972,8 +968,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       result = NO_ACTION_POSSIBLE;
       CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
     } else {
-      CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, 0)",
-                 s->cbs);
+      CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, 0)", s->cbs);
       stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
       bidirectional_stream_write(s->cbs, "", 0, true);
       result = ACTION_TAKEN_WITH_CALLBACK;
@@ -1073,8 +1068,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
     /* 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_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 */
-- 
GitLab


From af37b809aa931856764e766ebe3e9baaaaaa0897 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Tue, 29 Nov 2016 12:28:51 -0800
Subject: [PATCH 065/344] experimental

---
 test/http2_test/http2_base_server.py | 157 +++++++
 test/http2_test/http2_test_server.py | 164 +++++++
 test/http2_test/messages_pb2.py      | 661 +++++++++++++++++++++++++++
 3 files changed, 982 insertions(+)
 create mode 100644 test/http2_test/http2_base_server.py
 create mode 100644 test/http2_test/http2_test_server.py
 create mode 100644 test/http2_test/messages_pb2.py

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
new file mode 100644
index 0000000000..07bd37cae9
--- /dev/null
+++ b/test/http2_test/http2_base_server.py
@@ -0,0 +1,157 @@
+import struct
+import messages_pb2
+import functools
+import argparse
+import logging
+import time
+
+from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.protocol import Protocol, Factory
+from twisted.internet import endpoints, reactor, error, defer
+from h2.connection import H2Connection
+from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged, PingAcknowledged
+from threading import Lock
+
+READ_CHUNK_SIZE = 16384
+GRPC_HEADER_SIZE = 5
+
+class H2ProtocolBaseServer(Protocol):
+  def __init__(self):
+    self._conn = H2Connection(client_side=False)
+    self._recv_buffer = ''
+    self._handlers = {}
+    self._handlers['DataReceived'] = self.on_data_received_default
+    self._handlers['WindowUpdated'] = self.on_window_update_default
+    self._handlers['RequestReceived'] = self.on_request_received_default
+    self._handlers['SendDone'] = self.on_send_done_default
+    self._handlers['ConnectionLost'] = self.on_connection_lost
+    self._handlers['PingAcknowledged'] = self.on_ping_acknowledged_default
+    self._stream_status = {}
+    self._outstanding_pings = 0
+
+  def set_handlers(self, handlers):
+    self._handlers = handlers
+
+  def connectionMade(self):
+    logging.info('Connection Made')
+    self._conn.initiate_connection()
+    self.transport.setTcpNoDelay(True)
+    self.transport.write(self._conn.data_to_send())
+
+  def connectionLost(self, reason):
+    self._handlers['ConnectionLost'](reason)
+
+  def on_connection_lost(self, reason):
+    logging.info('Disconnected %s'%reason)
+    reactor.callFromThread(reactor.stop)
+
+  def dataReceived(self, data):
+    events = self._conn.receive_data(data)
+    if self._conn.data_to_send:
+      self.transport.write(self._conn.data_to_send())
+    for event in events:
+      if isinstance(event, RequestReceived) and self._handlers.has_key('RequestReceived'):
+        logging.info('RequestReceived Event')
+        self._handlers['RequestReceived'](event)
+      elif isinstance(event, DataReceived) and self._handlers.has_key('DataReceived'):
+        logging.info('DataReceived Event')
+        self._handlers['DataReceived'](event)
+      elif isinstance(event, WindowUpdated) and self._handlers.has_key('WindowUpdated'):
+        logging.info('WindowUpdated Event')
+        self._handlers['WindowUpdated'](event)
+      elif isinstance(event, PingAcknowledged) and self._handlers.has_key('PingAcknowledged'):
+        logging.info('PingAcknowledged Event')
+        self._handlers['PingAcknowledged'](event)
+    self.transport.write(self._conn.data_to_send())
+
+  def on_ping_acknowledged_default(self, event):
+    self._outstanding_pings -= 1
+
+  def on_data_received_default(self, event):
+    self._conn.acknowledge_received_data(len(event.data), event.stream_id)
+    self._recv_buffer += event.data
+
+  def on_request_received_default(self, event):
+    self._recv_buffer = ''
+    self._stream_id = event.stream_id
+    self._stream_status[event.stream_id] = True
+    self._conn.send_headers(
+      stream_id=event.stream_id,
+      headers=[
+          (':status', '200'),
+          ('content-type', 'application/grpc'),
+          ('grpc-encoding', 'identity'),
+          ('grpc-accept-encoding', 'identity,deflate,gzip'),
+      ],
+    )
+    self.transport.write(self._conn.data_to_send())
+
+  def on_window_update_default(self, event):
+    pass
+
+  def send_reset_stream(self):
+    self._conn.reset_stream(self._stream_id)
+    self.transport.write(self._conn.data_to_send())
+
+  def setup_send(self, data_to_send):
+    self._send_remaining = len(data_to_send)
+    self._send_offset = 0
+    self._data_to_send = data_to_send
+    self.default_send()
+
+  def default_send(self):
+    while self._send_remaining > 0:
+      lfcw = self._conn.local_flow_control_window(self._stream_id)
+      if lfcw == 0:
+        break
+      chunk_size = min(lfcw, READ_CHUNK_SIZE)
+      bytes_to_send = min(chunk_size, self._send_remaining)
+      logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d'%
+                    (lfcw, self._send_offset, self._send_offset + bytes_to_send,
+                    self._stream_id))
+      data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send]
+      self._conn.send_data(self._stream_id, data, False)
+      self._send_remaining -= bytes_to_send
+      self._send_offset += bytes_to_send
+      if self._send_remaining == 0:
+        self._handlers['SendDone']()
+
+  def default_ping(self):
+    self._outstanding_pings += 1
+    self._conn.ping(b'\x00'*8)
+    self.transport.write(self._conn.data_to_send())
+
+  def on_send_done_default(self):
+    if self._stream_status[self._stream_id]:
+      self._stream_status[self._stream_id] = False
+      self.default_send_trailer()
+
+  def default_send_trailer(self):
+    logging.info('Sending trailer for stream id %d'%self._stream_id)
+    self._conn.send_headers(self._stream_id,
+      headers=[ ('grpc-status', '0') ],
+      end_stream=True
+    )
+    self.transport.write(self._conn.data_to_send())
+
+  @staticmethod
+  def default_response_data(response_size):
+    sresp = messages_pb2.SimpleResponse()
+    sresp.payload.body = b'\x00'*response_size
+    serialized_resp_proto = sresp.SerializeToString()
+    response_data = b'\x00' + struct.pack('i', len(serialized_resp_proto))[::-1] + serialized_resp_proto
+    return response_data
+
+  @staticmethod
+  def parse_received_data(recv_buffer):
+    """ returns a grpc framed string of bytes containing response proto of the size
+    asked in request """
+    grpc_msg_size = struct.unpack('i',recv_buffer[1:5][::-1])[0]
+    if len(recv_buffer) != GRPC_HEADER_SIZE + grpc_msg_size:
+      logging.error('not enough data to decode req proto. size = %d, needed %s'%(len(recv_buffer), 5+grpc_msg_size))
+      return None
+    req_proto_str = recv_buffer[5:5+grpc_msg_size]
+    sr = messages_pb2.SimpleRequest()
+    sr.ParseFromString(req_proto_str)
+    logging.info('Parsed request: response_size=%s'%sr.response_size)
+    return sr
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
new file mode 100644
index 0000000000..be5f1593eb
--- /dev/null
+++ b/test/http2_test/http2_test_server.py
@@ -0,0 +1,164 @@
+"""
+  HTTP2 Test Server. Highly experimental work in progress.
+"""
+import struct
+import messages_pb2
+import argparse
+import logging
+import time
+
+from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.protocol import Protocol, Factory
+from twisted.internet import endpoints, reactor, error, defer
+from h2.connection import H2Connection
+from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged
+from threading import Lock
+import http2_base_server
+
+READ_CHUNK_SIZE = 16384
+GRPC_HEADER_SIZE = 5
+
+class TestcaseRstStreamAfterHeader(object):
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_request_received(self, event):
+    # send initial headers
+    self._base_server.on_request_received_default(event)
+    # send reset stream
+    self._base_server.send_reset_stream()
+
+class TestcaseRstStreamAfterData(object):
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    assert(sr is not None)
+    assert(sr.response_size <= 2048) # so it can fit into one flow control window
+    response_data = self._base_server.default_response_data(sr.response_size)
+    self._ready_to_send = True
+    self._base_server.setup_send(response_data)
+    # send reset stream
+    self._base_server.send_reset_stream()
+
+class TestcaseGoaway(object):
+  """ 
+    Process incoming request normally. After sending trailer response,
+    send GOAWAY with stream id = 1.
+    assert that the next request is made on a different connection.
+  """
+  def __init__(self, iteration):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['WindowUpdated'] = self.on_window_update_default
+    self._base_server._handlers['SendDone'] = self.on_send_done
+    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
+    self._ready_to_send = False
+    self._iteration = iteration
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_connection_lost(self, reason):
+    logging.info('Disconnect received. Count %d'%self._iteration)
+    # _iteration == 2 => Two different connections have been used.
+    if self._iteration == 2:
+      self._base_server.on_connection_lost(reason)
+
+  def on_send_done(self):
+    self._base_server.on_send_done_default()
+    if self._base_server._stream_id == 1:
+      logging.info('Sending GOAWAY for stream 1')
+      self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=1)
+
+  def on_request_received(self, event):
+    self._ready_to_send = False
+    self._base_server.on_request_received_default(event)
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    if sr:
+      time.sleep(1)
+      logging.info('Creating response size = %s'%sr.response_size)
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._ready_to_send = True
+      self._base_server.setup_send(response_data)
+
+  def on_window_update_default(self, event):
+    if self._ready_to_send:
+      self._base_server.default_send()
+
+class TestcasePing(object):
+  """ 
+  """
+  def __init__(self, iteration):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_request_received(self, event):
+    self._base_server.default_ping()
+    self._base_server.on_request_received_default(event)
+    self._base_server.default_ping()
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    logging.info('Creating response size = %s'%sr.response_size)
+    response_data = self._base_server.default_response_data(sr.response_size)
+    self._base_server.default_ping()
+    self._base_server.setup_send(response_data)
+    self._base_server.default_ping()
+
+  def on_connection_lost(self, reason):
+    logging.info('Disconnect received. Ping Count %d'%self._base_server._outstanding_pings)
+    assert(self._base_server._outstanding_pings == 0)
+    self._base_server.on_connection_lost(reason)
+
+class H2Factory(Factory):
+  def __init__(self, testcase):
+    logging.info('In H2Factory')
+    self._num_streams = 0
+    self._testcase = testcase
+
+  def buildProtocol(self, addr):
+    self._num_streams += 1
+    if self._testcase == 'rst_stream_after_header':
+      t = TestcaseRstStreamAfterHeader(self._num_streams)
+    elif self._testcase == 'rst_stream_after_data':
+      t = TestcaseRstStreamAfterData(self._num_streams)
+    elif self._testcase == 'goaway':
+      t = TestcaseGoaway(self._num_streams)
+    elif self._testcase == 'ping':
+      t = TestcasePing(self._num_streams)
+    else:
+      assert(0)
+    return t.get_base_server()
+
+if __name__ == "__main__":
+  logging.basicConfig(format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s", level=logging.INFO)
+  parser = argparse.ArgumentParser()
+  parser.add_argument("test")
+  parser.add_argument("port")
+  args = parser.parse_args()
+  if args.test not in ['rst_stream_after_header', 'rst_stream_after_data', 'goaway', 'ping']:
+    print 'unknown test: ', args.test
+  endpoint = endpoints.TCP4ServerEndpoint(reactor, int(args.port), backlog=128)
+  endpoint.listen(H2Factory(args.test))
+  reactor.run()
diff --git a/test/http2_test/messages_pb2.py b/test/http2_test/messages_pb2.py
new file mode 100644
index 0000000000..86cf5a8970
--- /dev/null
+++ b/test/http2_test/messages_pb2.py
@@ -0,0 +1,661 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: messages.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='messages.proto',
+  package='grpc.testing',
+  syntax='proto3',
+  serialized_pb=_b('\n\x0emessages.proto\x12\x0cgrpc.testing\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"@\n\x07Payload\x12\'\n\x04type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x0c\n\x04\x62ody\x18\x02 \x01(\x0c\"+\n\nEchoStatus\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xce\x02\n\rSimpleRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12\x15\n\rresponse_size\x18\x02 \x01(\x05\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x15\n\rfill_username\x18\x04 \x01(\x08\x12\x18\n\x10\x66ill_oauth_scope\x18\x05 \x01(\x08\x12\x34\n\x13response_compressed\x18\x06 \x01(\x0b\x32\x17.grpc.testing.BoolValue\x12\x31\n\x0fresponse_status\x18\x07 \x01(\x0b\x32\x18.grpc.testing.EchoStatus\x12\x32\n\x11\x65xpect_compressed\x18\x08 \x01(\x0b\x32\x17.grpc.testing.BoolValue\"_\n\x0eSimpleResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x13\n\x0boauth_scope\x18\x03 \x01(\t\"w\n\x19StreamingInputCallRequest\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x32\n\x11\x65xpect_compressed\x18\x02 \x01(\x0b\x32\x17.grpc.testing.BoolValue\"=\n\x1aStreamingInputCallResponse\x12\x1f\n\x17\x61ggregated_payload_size\x18\x01 \x01(\x05\"d\n\x12ResponseParameters\x12\x0c\n\x04size\x18\x01 \x01(\x05\x12\x13\n\x0binterval_us\x18\x02 \x01(\x05\x12+\n\ncompressed\x18\x03 \x01(\x0b\x32\x17.grpc.testing.BoolValue\"\xe8\x01\n\x1aStreamingOutputCallRequest\x12\x30\n\rresponse_type\x18\x01 \x01(\x0e\x32\x19.grpc.testing.PayloadType\x12=\n\x13response_parameters\x18\x02 \x03(\x0b\x32 .grpc.testing.ResponseParameters\x12&\n\x07payload\x18\x03 \x01(\x0b\x32\x15.grpc.testing.Payload\x12\x31\n\x0fresponse_status\x18\x07 \x01(\x0b\x32\x18.grpc.testing.EchoStatus\"E\n\x1bStreamingOutputCallResponse\x12&\n\x07payload\x18\x01 \x01(\x0b\x32\x15.grpc.testing.Payload\"3\n\x0fReconnectParams\x12 \n\x18max_reconnect_backoff_ms\x18\x01 \x01(\x05\"3\n\rReconnectInfo\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nbackoff_ms\x18\x02 \x03(\x05*\x1f\n\x0bPayloadType\x12\x10\n\x0c\x43OMPRESSABLE\x10\x00\x62\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_PAYLOADTYPE = _descriptor.EnumDescriptor(
+  name='PayloadType',
+  full_name='grpc.testing.PayloadType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='COMPRESSABLE', index=0, number=0,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1303,
+  serialized_end=1334,
+)
+_sym_db.RegisterEnumDescriptor(_PAYLOADTYPE)
+
+PayloadType = enum_type_wrapper.EnumTypeWrapper(_PAYLOADTYPE)
+COMPRESSABLE = 0
+
+
+
+_BOOLVALUE = _descriptor.Descriptor(
+  name='BoolValue',
+  full_name='grpc.testing.BoolValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='grpc.testing.BoolValue.value', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=32,
+  serialized_end=58,
+)
+
+
+_PAYLOAD = _descriptor.Descriptor(
+  name='Payload',
+  full_name='grpc.testing.Payload',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='grpc.testing.Payload.type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='body', full_name='grpc.testing.Payload.body', index=1,
+      number=2, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=60,
+  serialized_end=124,
+)
+
+
+_ECHOSTATUS = _descriptor.Descriptor(
+  name='EchoStatus',
+  full_name='grpc.testing.EchoStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='grpc.testing.EchoStatus.code', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='grpc.testing.EchoStatus.message', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=126,
+  serialized_end=169,
+)
+
+
+_SIMPLEREQUEST = _descriptor.Descriptor(
+  name='SimpleRequest',
+  full_name='grpc.testing.SimpleRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='response_type', full_name='grpc.testing.SimpleRequest.response_type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_size', full_name='grpc.testing.SimpleRequest.response_size', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='grpc.testing.SimpleRequest.payload', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fill_username', full_name='grpc.testing.SimpleRequest.fill_username', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fill_oauth_scope', full_name='grpc.testing.SimpleRequest.fill_oauth_scope', index=4,
+      number=5, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_compressed', full_name='grpc.testing.SimpleRequest.response_compressed', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_status', full_name='grpc.testing.SimpleRequest.response_status', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='expect_compressed', full_name='grpc.testing.SimpleRequest.expect_compressed', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=172,
+  serialized_end=506,
+)
+
+
+_SIMPLERESPONSE = _descriptor.Descriptor(
+  name='SimpleResponse',
+  full_name='grpc.testing.SimpleResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='grpc.testing.SimpleResponse.payload', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='grpc.testing.SimpleResponse.username', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oauth_scope', full_name='grpc.testing.SimpleResponse.oauth_scope', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=508,
+  serialized_end=603,
+)
+
+
+_STREAMINGINPUTCALLREQUEST = _descriptor.Descriptor(
+  name='StreamingInputCallRequest',
+  full_name='grpc.testing.StreamingInputCallRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='grpc.testing.StreamingInputCallRequest.payload', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='expect_compressed', full_name='grpc.testing.StreamingInputCallRequest.expect_compressed', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=605,
+  serialized_end=724,
+)
+
+
+_STREAMINGINPUTCALLRESPONSE = _descriptor.Descriptor(
+  name='StreamingInputCallResponse',
+  full_name='grpc.testing.StreamingInputCallResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='aggregated_payload_size', full_name='grpc.testing.StreamingInputCallResponse.aggregated_payload_size', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=726,
+  serialized_end=787,
+)
+
+
+_RESPONSEPARAMETERS = _descriptor.Descriptor(
+  name='ResponseParameters',
+  full_name='grpc.testing.ResponseParameters',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='size', full_name='grpc.testing.ResponseParameters.size', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='interval_us', full_name='grpc.testing.ResponseParameters.interval_us', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='compressed', full_name='grpc.testing.ResponseParameters.compressed', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=789,
+  serialized_end=889,
+)
+
+
+_STREAMINGOUTPUTCALLREQUEST = _descriptor.Descriptor(
+  name='StreamingOutputCallRequest',
+  full_name='grpc.testing.StreamingOutputCallRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='response_type', full_name='grpc.testing.StreamingOutputCallRequest.response_type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_parameters', full_name='grpc.testing.StreamingOutputCallRequest.response_parameters', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='grpc.testing.StreamingOutputCallRequest.payload', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_status', full_name='grpc.testing.StreamingOutputCallRequest.response_status', index=3,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=892,
+  serialized_end=1124,
+)
+
+
+_STREAMINGOUTPUTCALLRESPONSE = _descriptor.Descriptor(
+  name='StreamingOutputCallResponse',
+  full_name='grpc.testing.StreamingOutputCallResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='grpc.testing.StreamingOutputCallResponse.payload', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1126,
+  serialized_end=1195,
+)
+
+
+_RECONNECTPARAMS = _descriptor.Descriptor(
+  name='ReconnectParams',
+  full_name='grpc.testing.ReconnectParams',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='max_reconnect_backoff_ms', full_name='grpc.testing.ReconnectParams.max_reconnect_backoff_ms', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1197,
+  serialized_end=1248,
+)
+
+
+_RECONNECTINFO = _descriptor.Descriptor(
+  name='ReconnectInfo',
+  full_name='grpc.testing.ReconnectInfo',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='passed', full_name='grpc.testing.ReconnectInfo.passed', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='backoff_ms', full_name='grpc.testing.ReconnectInfo.backoff_ms', index=1,
+      number=2, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1250,
+  serialized_end=1301,
+)
+
+_PAYLOAD.fields_by_name['type'].enum_type = _PAYLOADTYPE
+_SIMPLEREQUEST.fields_by_name['response_type'].enum_type = _PAYLOADTYPE
+_SIMPLEREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
+_SIMPLEREQUEST.fields_by_name['response_compressed'].message_type = _BOOLVALUE
+_SIMPLEREQUEST.fields_by_name['response_status'].message_type = _ECHOSTATUS
+_SIMPLEREQUEST.fields_by_name['expect_compressed'].message_type = _BOOLVALUE
+_SIMPLERESPONSE.fields_by_name['payload'].message_type = _PAYLOAD
+_STREAMINGINPUTCALLREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
+_STREAMINGINPUTCALLREQUEST.fields_by_name['expect_compressed'].message_type = _BOOLVALUE
+_RESPONSEPARAMETERS.fields_by_name['compressed'].message_type = _BOOLVALUE
+_STREAMINGOUTPUTCALLREQUEST.fields_by_name['response_type'].enum_type = _PAYLOADTYPE
+_STREAMINGOUTPUTCALLREQUEST.fields_by_name['response_parameters'].message_type = _RESPONSEPARAMETERS
+_STREAMINGOUTPUTCALLREQUEST.fields_by_name['payload'].message_type = _PAYLOAD
+_STREAMINGOUTPUTCALLREQUEST.fields_by_name['response_status'].message_type = _ECHOSTATUS
+_STREAMINGOUTPUTCALLRESPONSE.fields_by_name['payload'].message_type = _PAYLOAD
+DESCRIPTOR.message_types_by_name['BoolValue'] = _BOOLVALUE
+DESCRIPTOR.message_types_by_name['Payload'] = _PAYLOAD
+DESCRIPTOR.message_types_by_name['EchoStatus'] = _ECHOSTATUS
+DESCRIPTOR.message_types_by_name['SimpleRequest'] = _SIMPLEREQUEST
+DESCRIPTOR.message_types_by_name['SimpleResponse'] = _SIMPLERESPONSE
+DESCRIPTOR.message_types_by_name['StreamingInputCallRequest'] = _STREAMINGINPUTCALLREQUEST
+DESCRIPTOR.message_types_by_name['StreamingInputCallResponse'] = _STREAMINGINPUTCALLRESPONSE
+DESCRIPTOR.message_types_by_name['ResponseParameters'] = _RESPONSEPARAMETERS
+DESCRIPTOR.message_types_by_name['StreamingOutputCallRequest'] = _STREAMINGOUTPUTCALLREQUEST
+DESCRIPTOR.message_types_by_name['StreamingOutputCallResponse'] = _STREAMINGOUTPUTCALLRESPONSE
+DESCRIPTOR.message_types_by_name['ReconnectParams'] = _RECONNECTPARAMS
+DESCRIPTOR.message_types_by_name['ReconnectInfo'] = _RECONNECTINFO
+DESCRIPTOR.enum_types_by_name['PayloadType'] = _PAYLOADTYPE
+
+BoolValue = _reflection.GeneratedProtocolMessageType('BoolValue', (_message.Message,), dict(
+  DESCRIPTOR = _BOOLVALUE,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.BoolValue)
+  ))
+_sym_db.RegisterMessage(BoolValue)
+
+Payload = _reflection.GeneratedProtocolMessageType('Payload', (_message.Message,), dict(
+  DESCRIPTOR = _PAYLOAD,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.Payload)
+  ))
+_sym_db.RegisterMessage(Payload)
+
+EchoStatus = _reflection.GeneratedProtocolMessageType('EchoStatus', (_message.Message,), dict(
+  DESCRIPTOR = _ECHOSTATUS,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.EchoStatus)
+  ))
+_sym_db.RegisterMessage(EchoStatus)
+
+SimpleRequest = _reflection.GeneratedProtocolMessageType('SimpleRequest', (_message.Message,), dict(
+  DESCRIPTOR = _SIMPLEREQUEST,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.SimpleRequest)
+  ))
+_sym_db.RegisterMessage(SimpleRequest)
+
+SimpleResponse = _reflection.GeneratedProtocolMessageType('SimpleResponse', (_message.Message,), dict(
+  DESCRIPTOR = _SIMPLERESPONSE,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.SimpleResponse)
+  ))
+_sym_db.RegisterMessage(SimpleResponse)
+
+StreamingInputCallRequest = _reflection.GeneratedProtocolMessageType('StreamingInputCallRequest', (_message.Message,), dict(
+  DESCRIPTOR = _STREAMINGINPUTCALLREQUEST,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamingInputCallRequest)
+  ))
+_sym_db.RegisterMessage(StreamingInputCallRequest)
+
+StreamingInputCallResponse = _reflection.GeneratedProtocolMessageType('StreamingInputCallResponse', (_message.Message,), dict(
+  DESCRIPTOR = _STREAMINGINPUTCALLRESPONSE,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamingInputCallResponse)
+  ))
+_sym_db.RegisterMessage(StreamingInputCallResponse)
+
+ResponseParameters = _reflection.GeneratedProtocolMessageType('ResponseParameters', (_message.Message,), dict(
+  DESCRIPTOR = _RESPONSEPARAMETERS,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.ResponseParameters)
+  ))
+_sym_db.RegisterMessage(ResponseParameters)
+
+StreamingOutputCallRequest = _reflection.GeneratedProtocolMessageType('StreamingOutputCallRequest', (_message.Message,), dict(
+  DESCRIPTOR = _STREAMINGOUTPUTCALLREQUEST,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamingOutputCallRequest)
+  ))
+_sym_db.RegisterMessage(StreamingOutputCallRequest)
+
+StreamingOutputCallResponse = _reflection.GeneratedProtocolMessageType('StreamingOutputCallResponse', (_message.Message,), dict(
+  DESCRIPTOR = _STREAMINGOUTPUTCALLRESPONSE,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamingOutputCallResponse)
+  ))
+_sym_db.RegisterMessage(StreamingOutputCallResponse)
+
+ReconnectParams = _reflection.GeneratedProtocolMessageType('ReconnectParams', (_message.Message,), dict(
+  DESCRIPTOR = _RECONNECTPARAMS,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.ReconnectParams)
+  ))
+_sym_db.RegisterMessage(ReconnectParams)
+
+ReconnectInfo = _reflection.GeneratedProtocolMessageType('ReconnectInfo', (_message.Message,), dict(
+  DESCRIPTOR = _RECONNECTINFO,
+  __module__ = 'messages_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.ReconnectInfo)
+  ))
+_sym_db.RegisterMessage(ReconnectInfo)
+
+
+# @@protoc_insertion_point(module_scope)
-- 
GitLab


From c13e2f5b033567055136dea95d3f1b54ad4f8a2c Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 29 Nov 2016 18:16:57 -0800
Subject: [PATCH 066/344] Node: correctly bubble up errors caused by
 non-serializable writes

---
 src/node/src/client.js | 13 ++++++++++++-
 src/node/src/server.js |  7 ++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/node/src/client.js b/src/node/src/client.js
index f75f951eb8..56aa890779 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -99,7 +99,18 @@ function ClientWritableStream(call, serialize) {
 function _write(chunk, encoding, callback) {
   /* jshint validthis: true */
   var batch = {};
-  var message = this.serialize(chunk);
+  var message;
+  try {
+    message = this.serialize(chunk);
+  } catch (e) {
+    /* Sending this error to the server and emitting it immediately on the
+       client may put the call in a slightly weird state on the client side,
+       but passing an object that causes a serialization failure is a misuse
+       of the API anyway, so that's OK. The primary purpose here is to give the
+       programmer a useful error and to stop the stream properly */
+    this.call.cancelWithStatus(grpc.status.INTERNAL, "Serialization failure");
+    callback(e);
+  }
   if (_.isFinite(encoding)) {
     /* Attach the encoding if it is a finite number. This is the closest we
      * can get to checking that it is valid flags */
diff --git a/src/node/src/server.js b/src/node/src/server.js
index b3b414969a..bd0a5122ad 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -278,7 +278,12 @@ function _write(chunk, encoding, callback) {
         (new Metadata())._getCoreRepresentation();
     this.call.metadataSent = true;
   }
-  var message = this.serialize(chunk);
+  var message;
+  try {
+    message = this.serialize(chunk);
+  } catch (e) {
+    callback(e);
+  }
   if (_.isFinite(encoding)) {
     /* Attach the encoding if it is a finite number. This is the closest we
      * can get to checking that it is valid flags */
-- 
GitLab


From acacd0d6467109e452e7375f662240c26fca004f Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Tue, 29 Nov 2016 23:42:27 -0800
Subject: [PATCH 067/344] add factory method to bad status to create correct
 subclass

---
 src/ruby/lib/grpc/errors.rb        | 43 ++++++++++++++++++++++++++++++
 src/ruby/spec/error_sanity_spec.rb |  8 +++++-
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 022a14b0a5..41c15de1d5 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -45,6 +45,8 @@ module GRPC
   class BadStatus < StandardError
     attr_reader :code, :details, :metadata
 
+    include GRPC::Core::StatusCodes
+
     # @param code [Numeric] the status code
     # @param details [String] the details of the exception
     # @param metadata [Hash] the error's metadata
@@ -62,6 +64,47 @@ module GRPC
     def to_status
       Struct::Status.new(code, details, @metadata)
     end
+
+    def self.new_status_exception(code, details = 'unkown cause', metadata = {})
+      case code
+      when OK
+	Ok.new(details, metadata)
+      when CANCELLED
+	Cancelled.new(details, metadata)
+      when UNKNOWN
+	Unknown.new(details, metadata)
+      when INVALID_ARGUMENT
+	InvalidArgument.new(details, metadata)
+      when DEADLINE_EXCEEDED
+	DeadlineExceeded.new(details, metadata)
+      when NOT_FOUND
+	NotFound.new(details, metadata)
+      when ALREADY_EXISTS
+	AlreadyExists.new(details, metadata)
+      when PERMISSION_DENIED
+	PermissionDenied.new(details, metadata)
+      when UNAUTHENTICATED
+	Unauthenticated.new(details, metadata)
+      when RESOURCE_EXHAUSTED
+	ResourceExhausted.new(details, metadata)
+      when FAILED_PRECONDITION
+	FailedPrecondition.new(details, metadata)
+      when ABORTED
+	Aborted.new(details, metadata)
+      when OUT_OF_RANGE
+	OutOfRange.new(details, metadata)
+      when UNIMPLEMENTED
+	Unimplemented.new(details, metadata)
+      when INTERNAL
+	Internal.new(details, metadata)
+      when UNAVAILABLE 
+	Unavailable.new(details, metadata)
+      when DATA_LOSS
+	DataLoss.new(details, metadata)
+      else
+        fail 'unknown code'
+      end
+    end
   end
 
   # GRPC status code corresponding to status OK
diff --git a/src/ruby/spec/error_sanity_spec.rb b/src/ruby/spec/error_sanity_spec.rb
index 97712104fe..ca2d80e685 100644
--- a/src/ruby/spec/error_sanity_spec.rb
+++ b/src/ruby/spec/error_sanity_spec.rb
@@ -48,11 +48,17 @@ describe StatusCodes do
 
       error_object = error_class.new
       # check that the code matches the int value of the error's constant
-      expect(error_object.code).to eq(StatusCodes.const_get(status_name))
+      status_code = StatusCodes.const_get(status_name)
+      expect(error_object.code).to eq(status_code)
 
       # check default parameters
       expect(error_object.details).to eq('unknown cause')
       expect(error_object.metadata).to eq({})
+
+      # check that the BadStatus factory for creates the correct
+      # exception too
+      from_factory = GRPC::BadStatus.new_status_exception(status_code)
+      expect(from_factory.is_a?(error_class)).to be(true)
     end
   end
 end
-- 
GitLab


From 174aa915bae4b379932e4887e26f2953db52b954 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 30 Nov 2016 08:35:52 -0800
Subject: [PATCH 068/344] change client code to use specific exceptions and
 throw bad status if unkown code

---
 src/ruby/lib/grpc/errors.rb               | 59 +++++++++--------------
 src/ruby/lib/grpc/generic/active_call.rb  |  3 +-
 src/ruby/lib/grpc/generic/service.rb      |  3 +-
 src/ruby/pb/grpc/health/checker.rb        |  4 +-
 src/ruby/pb/test/client.rb                |  7 +--
 src/ruby/spec/error_sanity_spec.rb        |  2 +-
 src/ruby/spec/generic/client_stub_spec.rb |  9 ++--
 src/ruby/spec/generic/rpc_server_spec.rb  |  5 +-
 src/ruby/spec/pb/health/checker_spec.rb   |  8 +--
 9 files changed, 43 insertions(+), 57 deletions(-)

diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 41c15de1d5..f6998e17c4 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -66,43 +66,30 @@ module GRPC
     end
 
     def self.new_status_exception(code, details = 'unkown cause', metadata = {})
-      case code
-      when OK
-	Ok.new(details, metadata)
-      when CANCELLED
-	Cancelled.new(details, metadata)
-      when UNKNOWN
-	Unknown.new(details, metadata)
-      when INVALID_ARGUMENT
-	InvalidArgument.new(details, metadata)
-      when DEADLINE_EXCEEDED
-	DeadlineExceeded.new(details, metadata)
-      when NOT_FOUND
-	NotFound.new(details, metadata)
-      when ALREADY_EXISTS
-	AlreadyExists.new(details, metadata)
-      when PERMISSION_DENIED
-	PermissionDenied.new(details, metadata)
-      when UNAUTHENTICATED
-	Unauthenticated.new(details, metadata)
-      when RESOURCE_EXHAUSTED
-	ResourceExhausted.new(details, metadata)
-      when FAILED_PRECONDITION
-	FailedPrecondition.new(details, metadata)
-      when ABORTED
-	Aborted.new(details, metadata)
-      when OUT_OF_RANGE
-	OutOfRange.new(details, metadata)
-      when UNIMPLEMENTED
-	Unimplemented.new(details, metadata)
-      when INTERNAL
-	Internal.new(details, metadata)
-      when UNAVAILABLE 
-	Unavailable.new(details, metadata)
-      when DATA_LOSS
-	DataLoss.new(details, metadata)
+      codes = {}
+      codes[OK] = Ok
+      codes[CANCELLED] = Cancelled
+      codes[UNKNOWN] = Unknown
+      codes[INVALID_ARGUMENT] = InvalidArgument
+      codes[DEADLINE_EXCEEDED] = DeadlineExceeded
+      codes[NOT_FOUND] = NotFound
+      codes[ALREADY_EXISTS] = AlreadyExists
+      codes[PERMISSION_DENIED] =  PermissionDenied
+      codes[UNAUTHENTICATED] = Unauthenticated
+      codes[RESOURCE_EXHAUSTED] = ResourceExhausted
+      codes[FAILED_PRECONDITION] = FailedPrecondition
+      codes[ABORTED] = Aborted
+      codes[OUT_OF_RANGE] = OutOfRange
+      codes[UNIMPLEMENTED] =  Unimplemented
+      codes[INTERNAL] = Internal
+      codes[UNIMPLEMENTED] =  Unimplemented
+      codes[UNAVAILABLE] =  Unavailable
+      codes[DATA_LOSS] = DataLoss
+
+      if codes[code].nil?
+        BadStatus.new(code, details, metadata)
       else
-        fail 'unknown code'
+        codes[code].new(details, metadata)
       end
     end
   end
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 5787f53463..01797d13e1 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -43,7 +43,8 @@ class Struct
         GRPC.logger.debug("Failing with status #{status}")
         # raise BadStatus, propagating the metadata if present.
         md = status.metadata
-        fail GRPC::BadStatus.new(status.code, status.details, md)
+        fail GRPC::BadStatus.new_status_exception(
+          status.code, status.details, md)
       end
       status
     end
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 7cb9f1cc99..0dbadcc19e 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -111,7 +111,8 @@ module GRPC
                                       marshal_class_method,
                                       unmarshal_class_method)
         define_method(name) do
-          fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
+          fail GRPC::BadStatus.new_status_exception(
+            GRPC::Core::StatusCodes::UNIMPLEMENTED)
         end
       end
 
diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb
index 4bce1744c4..6b2d852ebf 100644
--- a/src/ruby/pb/grpc/health/checker.rb
+++ b/src/ruby/pb/grpc/health/checker.rb
@@ -52,7 +52,9 @@ module Grpc
         @status_mutex.synchronize do
           status = @statuses["#{req.service}"]
         end
-        fail GRPC::BadStatus, StatusCodes::NOT_FOUND if status.nil?
+	if status.nil?
+          fail GRPC::BadStatus.new_status_exception(StatusCodes::NOT_FOUND)
+	end
         HealthCheckResponse.new(status: status)
       end
 
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index b9af160e7a..9ee5cdf9fd 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -338,11 +338,8 @@ class NamedTests
     deadline = GRPC::Core::TimeConsts::from_relative_time(1)
     resps = @stub.full_duplex_call(enum.each_item, deadline: deadline)
     resps.each { } # wait to receive each request (or timeout)
-    fail 'Should have raised GRPC::BadStatus(DEADLINE_EXCEEDED)'
-  rescue GRPC::BadStatus => e
-    assert("#{__callee__}: status was wrong") do
-      e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
-    end
+    fail 'Should have raised GRPC::DeadlineExceeded'
+  rescue GRPC::DeadlineExceeded
   end
 
   def empty_stream
diff --git a/src/ruby/spec/error_sanity_spec.rb b/src/ruby/spec/error_sanity_spec.rb
index ca2d80e685..77e94a8816 100644
--- a/src/ruby/spec/error_sanity_spec.rb
+++ b/src/ruby/spec/error_sanity_spec.rb
@@ -40,7 +40,7 @@ describe StatusCodes do
 
   StatusCodes.constants.each do |status_name|
     it 'there is a subclass of BadStatus corresponding to StatusCode: ' \
-      "#{name} that has code: #{StatusCodes.const_get(status_name)}" do
+      "#{status_name} that has code: #{StatusCodes.const_get(status_name)}" do
       camel_case = upper_snake_to_camel(status_name)
       error_class = GRPC.const_get(camel_case)
       # expect the error class to be a subclass of BadStatus
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 9c4e9cbd07..08a171e299 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -190,15 +190,14 @@ describe 'ClientStub' do
         end
         creds = GRPC::Core::CallCredentials.new(failing_auth)
 
-        error_occured = false
+        unauth_error_occured = false
         begin
           get_response(stub, credentials: creds)
-        rescue GRPC::BadStatus => e
-          error_occured = true
-          expect(e.code).to eq(GRPC::Core::StatusCodes::UNAUTHENTICATED)
+        rescue GRPC::Unauthenticated => e
+          unauth_error_occured = true
           expect(e.details.include?(error_message)).to be true
         end
-        expect(error_occured).to eq(true)
+        expect(unauth_error_occured).to eq(true)
 
         # Kill the server thread so tests can complete
         th.kill
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 31157cf161..1689d2df68 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -414,9 +414,8 @@ describe GRPC::RpcServer do
             stub = SlowStub.new(alt_host, :this_channel_is_insecure)
             begin
               stub.an_rpc(req)
-            rescue GRPC::BadStatus => e
-              one_failed_as_unavailable =
-                e.code == StatusCodes::RESOURCE_EXHAUSTED
+            rescue GRPC::ResourceExhausted
+              one_failed_as_unavailable = true
             end
           end
         end
diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb
index 1b2fa96827..2cc58f845b 100644
--- a/src/ruby/spec/pb/health/checker_spec.rb
+++ b/src/ruby/spec/pb/health/checker_spec.rb
@@ -119,7 +119,7 @@ describe Grpc::Health::Checker do
           subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
-        expect(&blk).to raise_error GRPC::BadStatus, expected_msg
+        expect(&blk).to raise_error GRPC::NotFound, expected_msg
       end
     end
   end
@@ -137,7 +137,7 @@ describe Grpc::Health::Checker do
           subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
-        expect(&blk).to raise_error GRPC::BadStatus, expected_msg
+        expect(&blk).to raise_error GRPC::NotFound, expected_msg
       end
     end
   end
@@ -158,7 +158,7 @@ describe Grpc::Health::Checker do
           subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
-        expect(&blk).to raise_error GRPC::BadStatus, expected_msg
+        expect(&blk).to raise_error GRPC::NotFound, expected_msg
       end
     end
   end
@@ -206,7 +206,7 @@ describe Grpc::Health::Checker do
         stub.check(HCReq.new(service: 'unknown'))
       end
       expected_msg = /#{StatusCodes::NOT_FOUND}/
-      expect(&blk).to raise_error GRPC::BadStatus, expected_msg
+      expect(&blk).to raise_error GRPC::NotFound, expected_msg
       @srv.stop
       t.join
     end
-- 
GitLab


From 72f8e14a8068140fcda53b537253792c4907de5a Mon Sep 17 00:00:00 2001
From: Garrett Casto <gcasto@chromium.org>
Date: Wed, 30 Nov 2016 13:12:39 -0800
Subject: [PATCH 069/344] More clang-format

---
 .../cronet/transport/cronet_api_dummy.c         | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/core/ext/transport/cronet/transport/cronet_api_dummy.c b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
index 1c4253f43f..74327a4214 100644
--- a/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
+++ b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
@@ -56,23 +56,22 @@ int bidirectional_stream_destroy(bidirectional_stream* stream) {
   return 0;
 }
 
-int bidirectional_stream_start(
-    bidirectional_stream* stream, const char* url, int priority,
-    const char* method, const bidirectional_stream_header_array* headers,
-    bool end_of_stream) {
+int bidirectional_stream_start(bidirectional_stream* stream, const char* url,
+                               int priority, const char* method,
+                               const bidirectional_stream_header_array* headers,
+                               bool end_of_stream) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int bidirectional_stream_read(bidirectional_stream* stream,
-                              char* buffer, int capacity) {
+int bidirectional_stream_read(bidirectional_stream* stream, char* buffer,
+                              int capacity) {
   GPR_ASSERT(0);
   return 0;
 }
 
-int bidirectional_stream_write(bidirectional_stream* stream,
-                               const char* buffer, int count,
-                               bool end_of_stream) {
+int bidirectional_stream_write(bidirectional_stream* stream, const char* buffer,
+                               int count, bool end_of_stream) {
   GPR_ASSERT(0);
   return 0;
 }
-- 
GitLab


From 4d01ceea2e471d46d98a02c40f4428d27f8c0ba6 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 30 Nov 2016 13:37:07 -0800
Subject: [PATCH 070/344] Change CronetFramework.podspec version number to
 0.0.4 instead of 1.0.0

---
 src/objective-c/CronetFramework.podspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/objective-c/CronetFramework.podspec b/src/objective-c/CronetFramework.podspec
index 538479b96b..90c7892df1 100644
--- a/src/objective-c/CronetFramework.podspec
+++ b/src/objective-c/CronetFramework.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name         = "CronetFramework"
-  s.version      = "1.0.0"
+  s.version      = "0.0.4"
   s.summary      = "Cronet, precompiled and used as a framework."
   s.homepage     = "http://chromium.org"
   s.license      = {
-- 
GitLab


From 1625d12ea1004e4d051775462e7dbe4906fb4a64 Mon Sep 17 00:00:00 2001
From: Alex Polcyn <apolcyn@google.com>
Date: Wed, 30 Nov 2016 13:51:54 -0800
Subject: [PATCH 071/344] update ruby protbuf dep to 3.1.0

---
 grpc.gemspec                    | 2 +-
 templates/grpc.gemspec.template | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/grpc.gemspec b/grpc.gemspec
index 088b99b1e6..724922ea46 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
   s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
   s.platform      = Gem::Platform::RUBY
 
-  s.add_dependency 'google-protobuf', '~> 3.0.2'
+  s.add_dependency 'google-protobuf', '~> 3.1.0'
   s.add_dependency 'googleauth',      '~> 0.5.1'
 
   s.add_development_dependency 'bundler',            '~> 1.9'
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index 62d61b75c1..82fbb69008 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -29,7 +29,7 @@
     s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
     s.platform      = Gem::Platform::RUBY
 
-    s.add_dependency 'google-protobuf', '~> 3.0.2'
+    s.add_dependency 'google-protobuf', '~> 3.1.0'
     s.add_dependency 'googleauth',      '~> 0.5.1'
 
     s.add_development_dependency 'bundler',            '~> 1.9'
-- 
GitLab


From 16db6e1c040e67a6c491fbe37409e6a37e61200f Mon Sep 17 00:00:00 2001
From: Alex Polcyn <apolcyn@google.com>
Date: Wed, 30 Nov 2016 13:59:59 -0800
Subject: [PATCH 072/344] destroy byte buffer reader after use in ruby recv msg

---
 src/ruby/ext/grpc/rb_byte_buffer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index 61b7c30315..28c6a0fd3a 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -65,5 +65,6 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
                GPR_SLICE_LENGTH(next));
     gpr_slice_unref(next);
   }
+  grpc_byte_buffer_reader_destroy(&reader);
   return rb_string;
 }
-- 
GitLab


From 977f5d4e7dc8bdf21bda2e8b9a7a232f88de8e73 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 30 Nov 2016 14:03:58 -0800
Subject: [PATCH 073/344] clang-format

---
 src/core/lib/channel/channel_stack_builder.c | 2 +-
 src/core/lib/surface/channel.c               | 9 ++++-----
 src/cpp/common/channel_filter.h              | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index f54eac06ec..b959517afb 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -266,7 +266,7 @@ grpc_error *grpc_channel_stack_builder_finish(
   } else {
     // run post-initialization functions
     i = 0;
-    for (filter_node *p = builder->begin.next; p != &builder->end;\
+    for (filter_node *p = builder->begin.next; p != &builder->end;
          p = p->next) {
       if (p->init != NULL) {
         p->init(channel_stack, grpc_channel_stack_element(channel_stack, i),
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 72e64a2076..9405015c50 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -101,7 +101,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
       exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
       (void **)&channel);
   if (error != GRPC_ERROR_NONE) {
-    const char* msg = grpc_error_string(error);
+    const char *msg = grpc_error_string(error);
     gpr_log(GPR_ERROR, "channel stack builder failed: %s", msg);
     grpc_error_free_string(msg);
     GRPC_ERROR_UNREF(error);
@@ -126,8 +126,8 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
           /* setting this takes precedence over anything else */
           GRPC_MDELEM_UNREF(channel->default_authority);
         }
-        channel->default_authority = grpc_mdelem_from_strings(
-            ":authority", args->args[i].value.string);
+        channel->default_authority =
+            grpc_mdelem_from_strings(":authority", args->args[i].value.string);
       }
     } else if (0 ==
                strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -156,8 +156,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                            GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
       channel->compression_options.default_algorithm.is_set = true;
       GPR_ASSERT(args->args[i].value.integer >= 0 &&
-                 args->args[i].value.integer <
-                     GRPC_COMPRESS_ALGORITHMS_COUNT);
+                 args->args[i].value.integer < GRPC_COMPRESS_ALGORITHMS_COUNT);
       channel->compression_options.default_algorithm.algorithm =
           (grpc_compression_algorithm)args->args[i].value.integer;
     } else if (0 ==
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 6bda74b9be..107522ea04 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -287,7 +287,7 @@ class ChannelFilter final {
             ? grpc_transport_get_peer(exec_ctx, args->optional_transport)
             : nullptr;
     // Construct the object in the already-allocated memory.
-    ChannelDataType* channel_data =
+    ChannelDataType *channel_data =
         new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
     return channel_data->Init();
   }
-- 
GitLab


From a9cc625b26ad64918712450a1b706858325766f9 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 30 Nov 2016 14:10:51 -0800
Subject: [PATCH 074/344] Fix stack corruption

---
 .../credentials/google_default/google_default_credentials.c      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index 7bed78daf7..4afeb4a3d2 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -160,6 +160,7 @@ static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
                         grpc_polling_entity_pollset(&detector.pollent),
                         &destroy_closure);
   g_polling_mu = NULL;
+  grpc_exec_ctx_flush(exec_ctx);
 
   gpr_free(grpc_polling_entity_pollset(&detector.pollent));
   grpc_http_response_destroy(&detector.response);
-- 
GitLab


From c00d0f79aa2e61fe0d61a5734fc01745e8edb047 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Wed, 30 Nov 2016 23:16:42 +0000
Subject: [PATCH 075/344] Clarify grpc_call_start_batch error semantics

---
 include/grpc/grpc.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 6f7a67b715..8cb278ff8d 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -197,9 +197,15 @@ GRPCAPI grpc_call *grpc_channel_create_registered_call(
     completion of type 'tag' to the completion queue bound to the call.
     The order of ops specified in the batch has no significance.
     Only one operation of each type can be active at once in any given
-    batch. You must call grpc_completion_queue_next or
-    grpc_completion_queue_pluck on the completion queue associated with 'call'
-    for work to be performed.
+    batch.
+    If a call to grpc_call_start_batch returns GRPC_CALL_OK you must call
+    grpc_completion_queue_next or grpc_completion_queue_pluck on the completion
+    queue associated with 'call' for work to be performed. If a call to
+    grpc_call_start_batch returns any value other than GRPC_CALL_OK it is
+    guaranteed that no state associated with 'call' is changed and it is not
+    appropriate to call grpc_completion_queue_next or
+    grpc_completion_queue_pluck consequent to the failed grpc_call_start_batch
+    call.
     THREAD SAFETY: access to grpc_call_start_batch in multi-threaded environment
     needs to be synchronized. As an optimization, you may synchronize batches
     containing just send operations independently from batches containing just
-- 
GitLab


From 564d3a7aa3db9daffff13c2eacb3fc1157bc4e9d Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Wed, 30 Nov 2016 23:21:17 +0000
Subject: [PATCH 076/344] Lint fixes

---
 src/python/grpcio/grpc/_channel.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 3117dd1cb3..bee32c9629 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -36,8 +36,8 @@ import time
 import grpc
 from grpc import _common
 from grpc import _grpcio_metadata
-from grpc.framework.foundation import callable_util
 from grpc._cython import cygrpc
+from grpc.framework.foundation import callable_util
 
 _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
 
@@ -358,7 +358,7 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
       if self._state.callbacks is None:
         return False
       else:
-        self._state.callbacks.append(lambda: callback())
+        self._state.callbacks.append(callback)
         return True
 
   def initial_metadata(self):
@@ -857,6 +857,7 @@ def _options(options):
 
 
 class Channel(grpc.Channel):
+  """A cygrpc.Channel-backed implementation of grpc.Channel."""
 
   def __init__(self, target, options, credentials):
     """Constructor.
-- 
GitLab


From b292a8502ed00ab5b06e5f5920e0d1a4e1ef9562 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Wed, 30 Nov 2016 23:21:53 +0000
Subject: [PATCH 077/344] Refactor channel call management

The requirement that any created managed call must have operations
performed on it is obstructing proper handling of the case of
applications providing invalid invocation metadata. In such cases the
RPC is "over before it starts" when the very first call to
start_client_batch returns an error.
---
 src/python/grpcio/grpc/_channel.py | 77 ++++++++++++++++--------------
 1 file changed, 41 insertions(+), 36 deletions(-)

diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index bee32c9629..3ac735a4ec 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -435,10 +435,10 @@ def _end_unary_response_blocking(state, with_call, deadline):
 class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
 
   def __init__(
-      self, channel, create_managed_call, method, request_serializer,
+      self, channel, managed_call, method, request_serializer,
       response_deserializer):
     self._channel = channel
-    self._create_managed_call = create_managed_call
+    self._managed_call = managed_call
     self._method = method
     self._request_serializer = request_serializer
     self._response_deserializer = response_deserializer
@@ -490,23 +490,24 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
     if rendezvous:
       return rendezvous
     else:
-      call = self._create_managed_call(
+      call, drive_call = self._managed_call(
           None, 0, self._method, None, deadline_timespec)
       if credentials is not None:
         call.set_credentials(credentials._credentials)
       event_handler = _event_handler(state, call, self._response_deserializer)
       with state.condition:
         call.start_client_batch(cygrpc.Operations(operations), event_handler)
+        drive_call()
       return _Rendezvous(state, call, self._response_deserializer, deadline)
 
 
 class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
 
   def __init__(
-      self, channel, create_managed_call, method, request_serializer,
+      self, channel, managed_call, method, request_serializer,
       response_deserializer):
     self._channel = channel
-    self._create_managed_call = create_managed_call
+    self._managed_call = managed_call
     self._method = method
     self._request_serializer = request_serializer
     self._response_deserializer = response_deserializer
@@ -518,7 +519,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
       raise rendezvous
     else:
       state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
-      call = self._create_managed_call(
+      call, drive_call = self._managed_call(
           None, 0, self._method, None, deadline_timespec)
       if credentials is not None:
         call.set_credentials(credentials._credentials)
@@ -536,16 +537,17 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
             cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
         )
         call.start_client_batch(cygrpc.Operations(operations), event_handler)
+        drive_call()
       return _Rendezvous(state, call, self._response_deserializer, deadline)
 
 
 class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
 
   def __init__(
-      self, channel, create_managed_call, method, request_serializer,
+      self, channel, managed_call, method, request_serializer,
       response_deserializer):
     self._channel = channel
-    self._create_managed_call = create_managed_call
+    self._managed_call = managed_call
     self._method = method
     self._request_serializer = request_serializer
     self._response_deserializer = response_deserializer
@@ -597,7 +599,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
       self, request_iterator, timeout=None, metadata=None, credentials=None):
     deadline, deadline_timespec = _deadline(timeout)
     state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
-    call = self._create_managed_call(
+    call, drive_call = self._managed_call(
         None, 0, self._method, None, deadline_timespec)
     if credentials is not None:
       call.set_credentials(credentials._credentials)
@@ -614,6 +616,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
       call.start_client_batch(cygrpc.Operations(operations), event_handler)
+      drive_call()
       _consume_request_iterator(
           request_iterator, state, call, self._request_serializer)
     return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -622,10 +625,10 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
 class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
 
   def __init__(
-      self, channel, create_managed_call, method, request_serializer,
+      self, channel, managed_call, method, request_serializer,
       response_deserializer):
     self._channel = channel
-    self._create_managed_call = create_managed_call
+    self._managed_call = managed_call
     self._method = method
     self._request_serializer = request_serializer
     self._response_deserializer = response_deserializer
@@ -634,7 +637,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
       self, request_iterator, timeout=None, metadata=None, credentials=None):
     deadline, deadline_timespec = _deadline(timeout)
     state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
-    call = self._create_managed_call(
+    call, drive_call = self._managed_call(
         None, 0, self._method, None, deadline_timespec)
     if credentials is not None:
       call.set_credentials(credentials._credentials)
@@ -650,6 +653,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
       call.start_client_batch(cygrpc.Operations(operations), event_handler)
+      drive_call()
       _consume_request_iterator(
           request_iterator, state, call, self._request_serializer)
     return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -687,16 +691,13 @@ def _run_channel_spin_thread(state):
   channel_spin_thread.start()
 
 
-def _create_channel_managed_call(state):
-  def create_channel_managed_call(parent, flags, method, host, deadline):
-    """Creates a managed cygrpc.Call.
+def _channel_managed_call_management(state):
+  def create(parent, flags, method, host, deadline):
+    """Creates a managed cygrpc.Call and a function to call to drive it.
 
-    Callers of this function must conduct at least one operation on the returned
-    call. The tags associated with operations conducted on the returned call
-    must be no-argument callables that return None to indicate that this channel
-    should continue polling for events associated with the call and return the
-    call itself to indicate that no more events associated with the call will be
-    generated.
+    If operations are successfully added to the returned cygrpc.Call, the
+    returned function must be called. If operations are not successfully added
+    to the returned cygrpc.Call, the returned function must not be called.
 
     Args:
       parent: A cygrpc.Call to be used as the parent of the created call.
@@ -706,18 +707,22 @@ def _create_channel_managed_call(state):
       deadline: A cygrpc.Timespec to be the deadline of the created call.
 
     Returns:
-      A cygrpc.Call with which to conduct an RPC.
+      A cygrpc.Call with which to conduct an RPC and a function to call if
+        operations are successfully started on the call.
     """
-    with state.lock:
-      call = state.channel.create_call(
-          parent, flags, state.completion_queue, method, host, deadline)
-      if state.managed_calls is None:
-        state.managed_calls = set((call,))
-        _run_channel_spin_thread(state)
-      else:
-        state.managed_calls.add(call)
-      return call
-  return create_channel_managed_call
+    call = state.channel.create_call(
+        parent, flags, state.completion_queue, method, host, deadline)
+
+    def drive():
+      with state.lock:
+        if state.managed_calls is None:
+          state.managed_calls = set((call,))
+          _run_channel_spin_thread(state)
+        else:
+          state.managed_calls.add(call)
+
+    return call, drive
+  return create
 
 
 class _ChannelConnectivityState(object):
@@ -881,25 +886,25 @@ class Channel(grpc.Channel):
   def unary_unary(
       self, method, request_serializer=None, response_deserializer=None):
     return _UnaryUnaryMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state),
+        self._channel, _channel_managed_call_management(self._call_state),
         _common.encode(method), request_serializer, response_deserializer)
 
   def unary_stream(
       self, method, request_serializer=None, response_deserializer=None):
     return _UnaryStreamMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state),
+        self._channel, _channel_managed_call_management(self._call_state),
         _common.encode(method), request_serializer, response_deserializer)
 
   def stream_unary(
       self, method, request_serializer=None, response_deserializer=None):
     return _StreamUnaryMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state),
+        self._channel, _channel_managed_call_management(self._call_state),
         _common.encode(method), request_serializer, response_deserializer)
 
   def stream_stream(
       self, method, request_serializer=None, response_deserializer=None):
     return _StreamStreamMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state),
+        self._channel, _channel_managed_call_management(self._call_state),
         _common.encode(method), request_serializer, response_deserializer)
 
   def __del__(self):
-- 
GitLab


From d2537c1aa9deb04937b64d23dcd71456c1eb7729 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 30 Nov 2016 14:34:49 -0800
Subject: [PATCH 078/344] turn on Thread.abort_on_exception in ruby unit tests
 by default

---
 src/ruby/spec/spec_helper.rb | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/ruby/spec/spec_helper.rb b/src/ruby/spec/spec_helper.rb
index c891c1bf5e..c2be0afa72 100644
--- a/src/ruby/spec/spec_helper.rb
+++ b/src/ruby/spec/spec_helper.rb
@@ -67,3 +67,5 @@ RSpec.configure do |config|
 end
 
 RSpec::Expectations.configuration.warn_about_potential_false_positives = false
+
+Thread.abort_on_exception = true
-- 
GitLab


From ff27a7aa4a9322833dcd9c29cda7ab3f1ba84ff2 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 30 Nov 2016 15:34:10 -0800
Subject: [PATCH 079/344] Use version number in Cronet zip file name

---
 src/objective-c/CronetFramework.podspec | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/objective-c/CronetFramework.podspec b/src/objective-c/CronetFramework.podspec
index 90c7892df1..d45b8d8143 100644
--- a/src/objective-c/CronetFramework.podspec
+++ b/src/objective-c/CronetFramework.podspec
@@ -30,7 +30,8 @@
 
 Pod::Spec.new do |s|
   s.name         = "CronetFramework"
-  s.version      = "0.0.4"
+  v = '0.0.4'
+  s.version      = v
   s.summary      = "Cronet, precompiled and used as a framework."
   s.homepage     = "http://chromium.org"
   s.license      = {
@@ -69,7 +70,8 @@ Pod::Spec.new do |s|
   s.vendored_framework = "Cronet.framework"
   s.author             = "The Chromium Authors"
   s.ios.deployment_target = "8.0"
-  s.source       = { :http => 'https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework-1.0.0.zip' }
+  file = 
+  s.source       = { :http => "https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework-v#{v}.zip"}
   s.preserve_paths = "Cronet.framework"
   s.public_header_files = "Cronet.framework/Headers/**/*{.h}"
   s.source_files = "Cronet.framework/Headers/**/*{.h}"
-- 
GitLab


From 80a675005d4545cb50c54bc292339b69f2304b04 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 30 Nov 2016 17:12:54 -0800
Subject: [PATCH 080/344] debug

---
 tools/run_tests/jobset.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index b84eb3b5d7..fa006bbd76 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -52,6 +52,8 @@ _MAX_RESULT_SIZE = 8192
 def sanitized_environment(env):
   sanitized = {}
   for key, value in env.items():
+    print(key)
+    print(value)
     sanitized[str(key).encode()] = str(value).encode()
   return sanitized
 
-- 
GitLab


From dbda92064f3fca42bba45771fd2939ccbcefaefd Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Thu, 1 Dec 2016 10:30:35 -0800
Subject: [PATCH 081/344] Also propagate serialization errors in unary server
 responses

---
 src/node/src/server.js | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/node/src/server.js b/src/node/src/server.js
index bd0a5122ad..51bb99ee53 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -127,7 +127,13 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
         (new Metadata())._getCoreRepresentation();
     call.metadataSent = true;
   }
-  var message = serialize(value);
+  var message;
+  try {
+    message = serialize(value);
+  } catch (e) {
+    e.code = grpc.status.INTERNAL;
+    handleError(e);
+  }
   message.grpcWriteFlags = flags;
   end_batch[grpc.opType.SEND_MESSAGE] = message;
   end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
@@ -282,7 +288,9 @@ function _write(chunk, encoding, callback) {
   try {
     message = this.serialize(chunk);
   } catch (e) {
+    e.code = grpc.status.INTERNAL;
     callback(e);
+    return;
   }
   if (_.isFinite(encoding)) {
     /* Attach the encoding if it is a finite number. This is the closest we
-- 
GitLab


From 323bfa733d8b23c19d48601dd4d9d5f71ab3bc5f Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 1 Dec 2016 10:51:10 -0800
Subject: [PATCH 082/344] Broke up code in multiple modules..

---
 test/http2_test/test_goaway.py           | 51 ++++++++++++++++++++++++
 test/http2_test/test_max_streams.py      | 30 ++++++++++++++
 test/http2_test/test_ping.py             | 36 +++++++++++++++++
 test/http2_test/test_rst_after_data.py   | 23 +++++++++++
 test/http2_test/test_rst_after_header.py | 19 +++++++++
 5 files changed, 159 insertions(+)
 create mode 100644 test/http2_test/test_goaway.py
 create mode 100644 test/http2_test/test_max_streams.py
 create mode 100644 test/http2_test/test_ping.py
 create mode 100644 test/http2_test/test_rst_after_data.py
 create mode 100644 test/http2_test/test_rst_after_header.py

diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
new file mode 100644
index 0000000000..419bd7b3f8
--- /dev/null
+++ b/test/http2_test/test_goaway.py
@@ -0,0 +1,51 @@
+import logging
+import http2_base_server
+
+class TestcaseGoaway(object):
+  """ 
+    This test does the following:
+      Process incoming request normally, i.e. send headers, data and trailers.
+      Then send a GOAWAY frame with the stream id of the processed request.
+      It assert that the next request is made on a different TCP connection.
+  """
+  def __init__(self, iteration):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['WindowUpdated'] = self.on_window_update_default
+    self._base_server._handlers['SendDone'] = self.on_send_done
+    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
+    self._ready_to_send = False
+    self._iteration = iteration
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_connection_lost(self, reason):
+    logging.info('Disconnect received. Count %d'%self._iteration)
+    # _iteration == 2 => Two different connections have been used.
+    if self._iteration == 2:
+      self._base_server.on_connection_lost(reason)
+
+  def on_send_done(self):
+    self._base_server.on_send_done_default()
+    if self._base_server._stream_id == 1:
+      logging.info('Sending GOAWAY for stream 1')
+      self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=1)
+
+  def on_request_received(self, event):
+    self._ready_to_send = False
+    self._base_server.on_request_received_default(event)
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    if sr:
+      logging.info('Creating response size = %s'%sr.response_size)
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._ready_to_send = True
+      self._base_server.setup_send(response_data)
+
+  def on_window_update_default(self, event):
+    if self._ready_to_send:
+      self._base_server.default_send()
diff --git a/test/http2_test/test_max_streams.py b/test/http2_test/test_max_streams.py
new file mode 100644
index 0000000000..a85dde48b5
--- /dev/null
+++ b/test/http2_test/test_max_streams.py
@@ -0,0 +1,30 @@
+import logging
+import http2_base_server
+from hyperframe.frame import SettingsFrame
+
+class TestcaseSettingsMaxStreams(object):
+  """
+    This test sets MAX_CONCURRENT_STREAMS to 1 and asserts that at any point
+    only 1 stream is active.
+  """
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['ConnectionMade'] = self.on_connection_made
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_connection_made(self):
+    logging.info('Connection Made')
+    self._base_server._conn.initiate_connection()
+    self._base_server._conn.update_settings({SettingsFrame.MAX_CONCURRENT_STREAMS: 1})
+    self._base_server.transport.setTcpNoDelay(True)
+    self._base_server.transport.write(self._base_server._conn.data_to_send())
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    logging.info('Creating response size = %s'%sr.response_size)
+    response_data = self._base_server.default_response_data(sr.response_size)
+    self._base_server.setup_send(response_data)
diff --git a/test/http2_test/test_ping.py b/test/http2_test/test_ping.py
new file mode 100644
index 0000000000..bade9df9b1
--- /dev/null
+++ b/test/http2_test/test_ping.py
@@ -0,0 +1,36 @@
+import logging
+import http2_base_server
+
+class TestcasePing(object):
+  """
+    This test injects PING frames before and after header and data. Keeps count
+    of outstanding ping response and asserts when the count is non-zero at the
+    end of the test.
+  """
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_request_received(self, event):
+    self._base_server.default_ping()
+    self._base_server.on_request_received_default(event)
+    self._base_server.default_ping()
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    logging.info('Creating response size = %s'%sr.response_size)
+    response_data = self._base_server.default_response_data(sr.response_size)
+    self._base_server.default_ping()
+    self._base_server.setup_send(response_data)
+    self._base_server.default_ping()
+
+  def on_connection_lost(self, reason):
+    logging.info('Disconnect received. Ping Count %d'%self._base_server._outstanding_pings)
+    assert(self._base_server._outstanding_pings == 0)
+    self._base_server.on_connection_lost(reason)
diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py
new file mode 100644
index 0000000000..ef8d4084d9
--- /dev/null
+++ b/test/http2_test/test_rst_after_data.py
@@ -0,0 +1,23 @@
+import http2_base_server
+
+class TestcaseRstStreamAfterData(object):
+  """
+    In response to an incoming request, this test sends headers, followed by
+    data, followed by a reset stream frame. Client asserts that the RPC failed.
+  """
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    assert(sr is not None)
+    response_data = self._base_server.default_response_data(sr.response_size)
+    self._ready_to_send = True
+    self._base_server.setup_send(response_data)
+    # send reset stream
+    self._base_server.send_reset_stream()
diff --git a/test/http2_test/test_rst_after_header.py b/test/http2_test/test_rst_after_header.py
new file mode 100644
index 0000000000..e9a6b1129c
--- /dev/null
+++ b/test/http2_test/test_rst_after_header.py
@@ -0,0 +1,19 @@
+import http2_base_server
+
+class TestcaseRstStreamAfterHeader(object):
+  """
+    In response to an incoming request, this test sends headers, followed by
+    a reset stream frame. Client asserts that the RPC failed.
+  """
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['RequestReceived'] = self.on_request_received
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_request_received(self, event):
+    # send initial headers
+    self._base_server.on_request_received_default(event)
+    # send reset stream
+    self._base_server.send_reset_stream()
-- 
GitLab


From 28d198008a6da19d28f0c34f7b3a4441f9c9d9ff Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 1 Dec 2016 10:56:52 -0800
Subject: [PATCH 083/344] minor cleanup..

---
 test/http2_test/http2_base_server.py |  19 ++--
 test/http2_test/http2_test_server.py | 149 +++------------------------
 2 files changed, 26 insertions(+), 142 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index 07bd37cae9..91caa74fcc 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -1,16 +1,11 @@
 import struct
 import messages_pb2
-import functools
-import argparse
 import logging
-import time
 
-from twisted.internet.defer import Deferred, inlineCallbacks
-from twisted.internet.protocol import Protocol, Factory
-from twisted.internet import endpoints, reactor, error, defer
+from twisted.internet.protocol import Protocol
+from twisted.internet import reactor
 from h2.connection import H2Connection
 from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged, PingAcknowledged
-from threading import Lock
 
 READ_CHUNK_SIZE = 16384
 GRPC_HEADER_SIZE = 5
@@ -20,6 +15,7 @@ class H2ProtocolBaseServer(Protocol):
     self._conn = H2Connection(client_side=False)
     self._recv_buffer = ''
     self._handlers = {}
+    self._handlers['ConnectionMade'] = self.on_connection_made_default
     self._handlers['DataReceived'] = self.on_data_received_default
     self._handlers['WindowUpdated'] = self.on_window_update_default
     self._handlers['RequestReceived'] = self.on_request_received_default
@@ -33,14 +29,17 @@ class H2ProtocolBaseServer(Protocol):
     self._handlers = handlers
 
   def connectionMade(self):
+    self._handlers['ConnectionMade']()
+
+  def connectionLost(self, reason):
+    self._handlers['ConnectionLost'](reason)
+
+  def on_connection_made_default(self):
     logging.info('Connection Made')
     self._conn.initiate_connection()
     self.transport.setTcpNoDelay(True)
     self.transport.write(self._conn.data_to_send())
 
-  def connectionLost(self, reason):
-    self._handlers['ConnectionLost'](reason)
-
   def on_connection_lost(self, reason):
     logging.info('Disconnected %s'%reason)
     reactor.callFromThread(reactor.stop)
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index be5f1593eb..7ec781d2aa 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -1,135 +1,17 @@
 """
   HTTP2 Test Server. Highly experimental work in progress.
 """
-import struct
-import messages_pb2
 import argparse
 import logging
-import time
 
-from twisted.internet.defer import Deferred, inlineCallbacks
-from twisted.internet.protocol import Protocol, Factory
-from twisted.internet import endpoints, reactor, error, defer
-from h2.connection import H2Connection
-from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged
-from threading import Lock
+from twisted.internet.protocol import Factory
+from twisted.internet import endpoints, reactor
 import http2_base_server
-
-READ_CHUNK_SIZE = 16384
-GRPC_HEADER_SIZE = 5
-
-class TestcaseRstStreamAfterHeader(object):
-  def __init__(self):
-    self._base_server = http2_base_server.H2ProtocolBaseServer()
-    self._base_server._handlers['RequestReceived'] = self.on_request_received
-
-  def get_base_server(self):
-    return self._base_server
-
-  def on_request_received(self, event):
-    # send initial headers
-    self._base_server.on_request_received_default(event)
-    # send reset stream
-    self._base_server.send_reset_stream()
-
-class TestcaseRstStreamAfterData(object):
-  def __init__(self):
-    self._base_server = http2_base_server.H2ProtocolBaseServer()
-    self._base_server._handlers['DataReceived'] = self.on_data_received
-
-  def get_base_server(self):
-    return self._base_server
-
-  def on_data_received(self, event):
-    self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    assert(sr is not None)
-    assert(sr.response_size <= 2048) # so it can fit into one flow control window
-    response_data = self._base_server.default_response_data(sr.response_size)
-    self._ready_to_send = True
-    self._base_server.setup_send(response_data)
-    # send reset stream
-    self._base_server.send_reset_stream()
-
-class TestcaseGoaway(object):
-  """ 
-    Process incoming request normally. After sending trailer response,
-    send GOAWAY with stream id = 1.
-    assert that the next request is made on a different connection.
-  """
-  def __init__(self, iteration):
-    self._base_server = http2_base_server.H2ProtocolBaseServer()
-    self._base_server._handlers['RequestReceived'] = self.on_request_received
-    self._base_server._handlers['DataReceived'] = self.on_data_received
-    self._base_server._handlers['WindowUpdated'] = self.on_window_update_default
-    self._base_server._handlers['SendDone'] = self.on_send_done
-    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
-    self._ready_to_send = False
-    self._iteration = iteration
-
-  def get_base_server(self):
-    return self._base_server
-
-  def on_connection_lost(self, reason):
-    logging.info('Disconnect received. Count %d'%self._iteration)
-    # _iteration == 2 => Two different connections have been used.
-    if self._iteration == 2:
-      self._base_server.on_connection_lost(reason)
-
-  def on_send_done(self):
-    self._base_server.on_send_done_default()
-    if self._base_server._stream_id == 1:
-      logging.info('Sending GOAWAY for stream 1')
-      self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=1)
-
-  def on_request_received(self, event):
-    self._ready_to_send = False
-    self._base_server.on_request_received_default(event)
-
-  def on_data_received(self, event):
-    self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    if sr:
-      time.sleep(1)
-      logging.info('Creating response size = %s'%sr.response_size)
-      response_data = self._base_server.default_response_data(sr.response_size)
-      self._ready_to_send = True
-      self._base_server.setup_send(response_data)
-
-  def on_window_update_default(self, event):
-    if self._ready_to_send:
-      self._base_server.default_send()
-
-class TestcasePing(object):
-  """ 
-  """
-  def __init__(self, iteration):
-    self._base_server = http2_base_server.H2ProtocolBaseServer()
-    self._base_server._handlers['RequestReceived'] = self.on_request_received
-    self._base_server._handlers['DataReceived'] = self.on_data_received
-    self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
-
-  def get_base_server(self):
-    return self._base_server
-
-  def on_request_received(self, event):
-    self._base_server.default_ping()
-    self._base_server.on_request_received_default(event)
-    self._base_server.default_ping()
-
-  def on_data_received(self, event):
-    self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    logging.info('Creating response size = %s'%sr.response_size)
-    response_data = self._base_server.default_response_data(sr.response_size)
-    self._base_server.default_ping()
-    self._base_server.setup_send(response_data)
-    self._base_server.default_ping()
-
-  def on_connection_lost(self, reason):
-    logging.info('Disconnect received. Ping Count %d'%self._base_server._outstanding_pings)
-    assert(self._base_server._outstanding_pings == 0)
-    self._base_server.on_connection_lost(reason)
+import test_rst_after_header
+import test_rst_after_data
+import test_goaway
+import test_ping
+import test_max_streams
 
 class H2Factory(Factory):
   def __init__(self, testcase):
@@ -139,15 +21,18 @@ class H2Factory(Factory):
 
   def buildProtocol(self, addr):
     self._num_streams += 1
-    if self._testcase == 'rst_stream_after_header':
-      t = TestcaseRstStreamAfterHeader(self._num_streams)
-    elif self._testcase == 'rst_stream_after_data':
-      t = TestcaseRstStreamAfterData(self._num_streams)
+    if self._testcase == 'rst_after_header':
+      t = test_rst_after_header.TestcaseRstStreamAfterHeader()
+    elif self._testcase == 'rst_after_data':
+      t = test_rst_after_data.TestcaseRstStreamAfterData()
     elif self._testcase == 'goaway':
-      t = TestcaseGoaway(self._num_streams)
+      t = test_goaway.TestcaseGoaway(self._num_streams)
     elif self._testcase == 'ping':
-      t = TestcasePing(self._num_streams)
+      t = test_ping.TestcasePing()
+    elif self._testcase == 'max_streams':
+      t = TestcaseSettingsMaxStreams(self._num_streams)
     else:
+      logging.error('Unknown test case: %s'%self._testcase)
       assert(0)
     return t.get_base_server()
 
@@ -157,7 +42,7 @@ if __name__ == "__main__":
   parser.add_argument("test")
   parser.add_argument("port")
   args = parser.parse_args()
-  if args.test not in ['rst_stream_after_header', 'rst_stream_after_data', 'goaway', 'ping']:
+  if args.test not in ['rst_after_header', 'rst_after_data', 'goaway', 'ping', 'max_streams']:
     print 'unknown test: ', args.test
   endpoint = endpoints.TCP4ServerEndpoint(reactor, int(args.port), backlog=128)
   endpoint.listen(H2Factory(args.test))
-- 
GitLab


From 45d4561cd0088fc49606a209ab4b8476311c75af Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Thu, 1 Dec 2016 10:59:52 -0800
Subject: [PATCH 084/344] Add missing return

---
 src/node/src/server.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/node/src/server.js b/src/node/src/server.js
index 51bb99ee53..da9c6b2d7f 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -133,6 +133,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
   } catch (e) {
     e.code = grpc.status.INTERNAL;
     handleError(e);
+    return;
   }
   message.grpcWriteFlags = flags;
   end_batch[grpc.opType.SEND_MESSAGE] = message;
-- 
GitLab


From 4350e748e470be92abab9bb1f72ad8eb1ede5486 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 1 Dec 2016 14:24:22 -0800
Subject: [PATCH 085/344] ability to deal with multiple streams in flight.

---
 test/http2_test/http2_base_server.py   | 76 ++++++++++++++++----------
 test/http2_test/test_goaway.py         | 19 +++----
 test/http2_test/test_max_streams.py    |  9 +--
 test/http2_test/test_ping.py           | 13 +++--
 test/http2_test/test_rst_after_data.py | 14 ++---
 5 files changed, 72 insertions(+), 59 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index 91caa74fcc..44fb575c0f 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -6,6 +6,7 @@ from twisted.internet.protocol import Protocol
 from twisted.internet import reactor
 from h2.connection import H2Connection
 from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged, PingAcknowledged
+from h2.exceptions import ProtocolError
 
 READ_CHUNK_SIZE = 16384
 GRPC_HEADER_SIZE = 5
@@ -13,7 +14,7 @@ GRPC_HEADER_SIZE = 5
 class H2ProtocolBaseServer(Protocol):
   def __init__(self):
     self._conn = H2Connection(client_side=False)
-    self._recv_buffer = ''
+    self._recv_buffer = {}
     self._handlers = {}
     self._handlers['ConnectionMade'] = self.on_connection_made_default
     self._handlers['DataReceived'] = self.on_data_received_default
@@ -23,6 +24,7 @@ class H2ProtocolBaseServer(Protocol):
     self._handlers['ConnectionLost'] = self.on_connection_lost
     self._handlers['PingAcknowledged'] = self.on_ping_acknowledged_default
     self._stream_status = {}
+    self._send_remaining = {}
     self._outstanding_pings = 0
 
   def set_handlers(self, handlers):
@@ -45,18 +47,23 @@ class H2ProtocolBaseServer(Protocol):
     reactor.callFromThread(reactor.stop)
 
   def dataReceived(self, data):
-    events = self._conn.receive_data(data)
+    try:
+      events = self._conn.receive_data(data)
+    except ProtocolError:
+      # this try/except block catches exceptions due to race between sending
+      # GOAWAY and processing a response in flight.
+      return
     if self._conn.data_to_send:
       self.transport.write(self._conn.data_to_send())
     for event in events:
       if isinstance(event, RequestReceived) and self._handlers.has_key('RequestReceived'):
-        logging.info('RequestReceived Event')
+        logging.info('RequestReceived Event for stream: %d'%event.stream_id)
         self._handlers['RequestReceived'](event)
       elif isinstance(event, DataReceived) and self._handlers.has_key('DataReceived'):
-        logging.info('DataReceived Event')
+        logging.info('DataReceived Event for stream: %d'%event.stream_id)
         self._handlers['DataReceived'](event)
       elif isinstance(event, WindowUpdated) and self._handlers.has_key('WindowUpdated'):
-        logging.info('WindowUpdated Event')
+        logging.info('WindowUpdated Event for stream: %d'%event.stream_id)
         self._handlers['WindowUpdated'](event)
       elif isinstance(event, PingAcknowledged) and self._handlers.has_key('PingAcknowledged'):
         logging.info('PingAcknowledged Event')
@@ -68,10 +75,10 @@ class H2ProtocolBaseServer(Protocol):
 
   def on_data_received_default(self, event):
     self._conn.acknowledge_received_data(len(event.data), event.stream_id)
-    self._recv_buffer += event.data
+    self._recv_buffer[event.stream_id] += event.data
 
   def on_request_received_default(self, event):
-    self._recv_buffer = ''
+    self._recv_buffer[event.stream_id] = ''
     self._stream_id = event.stream_id
     self._stream_status[event.stream_id] = True
     self._conn.send_headers(
@@ -86,48 +93,57 @@ class H2ProtocolBaseServer(Protocol):
     self.transport.write(self._conn.data_to_send())
 
   def on_window_update_default(self, event):
-    pass
+    # send pending data, if any
+    self.default_send(event.stream_id)
 
   def send_reset_stream(self):
     self._conn.reset_stream(self._stream_id)
     self.transport.write(self._conn.data_to_send())
 
-  def setup_send(self, data_to_send):
-    self._send_remaining = len(data_to_send)
+  def setup_send(self, data_to_send, stream_id):
+    logging.info('Setting up data to send for stream_id: %d'%stream_id)
+    self._send_remaining[stream_id] = len(data_to_send)
     self._send_offset = 0
     self._data_to_send = data_to_send
-    self.default_send()
+    self.default_send(stream_id)
 
-  def default_send(self):
-    while self._send_remaining > 0:
-      lfcw = self._conn.local_flow_control_window(self._stream_id)
+  def default_send(self, stream_id):
+    if not self._send_remaining.has_key(stream_id):
+      # not setup to send data yet
+      return
+
+    while self._send_remaining[stream_id] > 0:
+      if self._stream_status[stream_id] is False:
+        logging.info('Stream %d is closed.'%stream_id)
+        break
+      lfcw = self._conn.local_flow_control_window(stream_id)
       if lfcw == 0:
         break
       chunk_size = min(lfcw, READ_CHUNK_SIZE)
-      bytes_to_send = min(chunk_size, self._send_remaining)
+      bytes_to_send = min(chunk_size, self._send_remaining[stream_id])
       logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d'%
                     (lfcw, self._send_offset, self._send_offset + bytes_to_send,
-                    self._stream_id))
+                    stream_id))
       data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send]
-      self._conn.send_data(self._stream_id, data, False)
-      self._send_remaining -= bytes_to_send
+      self._conn.send_data(stream_id, data, False)
+      self._send_remaining[stream_id] -= bytes_to_send
       self._send_offset += bytes_to_send
-      if self._send_remaining == 0:
-        self._handlers['SendDone']()
+      if self._send_remaining[stream_id] == 0:
+        self._handlers['SendDone'](stream_id)
 
   def default_ping(self):
     self._outstanding_pings += 1
     self._conn.ping(b'\x00'*8)
     self.transport.write(self._conn.data_to_send())
 
-  def on_send_done_default(self):
-    if self._stream_status[self._stream_id]:
-      self._stream_status[self._stream_id] = False
-      self.default_send_trailer()
+  def on_send_done_default(self, stream_id):
+    if self._stream_status[stream_id]:
+      self._stream_status[stream_id] = False
+      self.default_send_trailer(stream_id)
 
-  def default_send_trailer(self):
-    logging.info('Sending trailer for stream id %d'%self._stream_id)
-    self._conn.send_headers(self._stream_id,
+  def default_send_trailer(self, stream_id):
+    logging.info('Sending trailer for stream id %d'%stream_id)
+    self._conn.send_headers(stream_id,
       headers=[ ('grpc-status', '0') ],
       end_stream=True
     )
@@ -141,8 +157,8 @@ class H2ProtocolBaseServer(Protocol):
     response_data = b'\x00' + struct.pack('i', len(serialized_resp_proto))[::-1] + serialized_resp_proto
     return response_data
 
-  @staticmethod
-  def parse_received_data(recv_buffer):
+  def parse_received_data(self, stream_id):
+    recv_buffer = self._recv_buffer[stream_id]
     """ returns a grpc framed string of bytes containing response proto of the size
     asked in request """
     grpc_msg_size = struct.unpack('i',recv_buffer[1:5][::-1])[0]
@@ -152,5 +168,5 @@ class H2ProtocolBaseServer(Protocol):
     req_proto_str = recv_buffer[5:5+grpc_msg_size]
     sr = messages_pb2.SimpleRequest()
     sr.ParseFromString(req_proto_str)
-    logging.info('Parsed request: response_size=%s'%sr.response_size)
+    logging.info('Parsed request for stream %d: response_size=%s'%(stream_id, sr.response_size))
     return sr
diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
index 419bd7b3f8..7dd7cb7948 100644
--- a/test/http2_test/test_goaway.py
+++ b/test/http2_test/test_goaway.py
@@ -12,7 +12,6 @@ class TestcaseGoaway(object):
     self._base_server = http2_base_server.H2ProtocolBaseServer()
     self._base_server._handlers['RequestReceived'] = self.on_request_received
     self._base_server._handlers['DataReceived'] = self.on_data_received
-    self._base_server._handlers['WindowUpdated'] = self.on_window_update_default
     self._base_server._handlers['SendDone'] = self.on_send_done
     self._base_server._handlers['ConnectionLost'] = self.on_connection_lost
     self._ready_to_send = False
@@ -27,11 +26,11 @@ class TestcaseGoaway(object):
     if self._iteration == 2:
       self._base_server.on_connection_lost(reason)
 
-  def on_send_done(self):
-    self._base_server.on_send_done_default()
-    if self._base_server._stream_id == 1:
-      logging.info('Sending GOAWAY for stream 1')
-      self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=1)
+  def on_send_done(self, stream_id):
+    self._base_server.on_send_done_default(stream_id)
+    logging.info('Sending GOAWAY for stream %d:'%stream_id)
+    self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=stream_id)
+    self._base_server._stream_status[stream_id] = False
 
   def on_request_received(self, event):
     self._ready_to_send = False
@@ -39,13 +38,9 @@ class TestcaseGoaway(object):
 
   def on_data_received(self, event):
     self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
+    sr = self._base_server.parse_received_data(event.stream_id)
     if sr:
       logging.info('Creating response size = %s'%sr.response_size)
       response_data = self._base_server.default_response_data(sr.response_size)
       self._ready_to_send = True
-      self._base_server.setup_send(response_data)
-
-  def on_window_update_default(self, event):
-    if self._ready_to_send:
-      self._base_server.default_send()
+      self._base_server.setup_send(response_data, event.stream_id)
diff --git a/test/http2_test/test_max_streams.py b/test/http2_test/test_max_streams.py
index a85dde48b5..deb26770c3 100644
--- a/test/http2_test/test_max_streams.py
+++ b/test/http2_test/test_max_streams.py
@@ -24,7 +24,8 @@ class TestcaseSettingsMaxStreams(object):
 
   def on_data_received(self, event):
     self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    logging.info('Creating response size = %s'%sr.response_size)
-    response_data = self._base_server.default_response_data(sr.response_size)
-    self._base_server.setup_send(response_data)
+    sr = self._base_server.parse_received_data(event.stream_id)
+    if sr:
+      logging.info('Creating response of size = %s'%sr.response_size)
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._base_server.setup_send(response_data, event.stream_id)
diff --git a/test/http2_test/test_ping.py b/test/http2_test/test_ping.py
index bade9df9b1..2e6dadbc07 100644
--- a/test/http2_test/test_ping.py
+++ b/test/http2_test/test_ping.py
@@ -23,12 +23,13 @@ class TestcasePing(object):
 
   def on_data_received(self, event):
     self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    logging.info('Creating response size = %s'%sr.response_size)
-    response_data = self._base_server.default_response_data(sr.response_size)
-    self._base_server.default_ping()
-    self._base_server.setup_send(response_data)
-    self._base_server.default_ping()
+    sr = self._base_server.parse_received_data(event.stream_id)
+    if sr:
+      logging.info('Creating response size = %s'%sr.response_size)
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._base_server.default_ping()
+      self._base_server.setup_send(response_data, event.stream_id)
+      self._base_server.default_ping()
 
   def on_connection_lost(self, reason):
     logging.info('Disconnect received. Ping Count %d'%self._base_server._outstanding_pings)
diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py
index ef8d4084d9..c4ff56c889 100644
--- a/test/http2_test/test_rst_after_data.py
+++ b/test/http2_test/test_rst_after_data.py
@@ -14,10 +14,10 @@ class TestcaseRstStreamAfterData(object):
 
   def on_data_received(self, event):
     self._base_server.on_data_received_default(event)
-    sr = self._base_server.parse_received_data(self._base_server._recv_buffer)
-    assert(sr is not None)
-    response_data = self._base_server.default_response_data(sr.response_size)
-    self._ready_to_send = True
-    self._base_server.setup_send(response_data)
-    # send reset stream
-    self._base_server.send_reset_stream()
+    sr = self._base_server.parse_received_data(event.stream_id)
+    if sr:
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._ready_to_send = True
+      self._base_server.setup_send(response_data, event.stream_id)
+      # send reset stream
+      self._base_server.send_reset_stream()
-- 
GitLab


From ecc32885f097ece2c46187166c496e3dd2d70229 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 1 Dec 2016 15:22:50 -0800
Subject: [PATCH 086/344] WIP

---
 test/http2_test/http2_base_server.py | 11 ++++++-----
 test/http2_test/http2_test_server.py |  1 +
 test/http2_test/test_goaway.py       |  4 +++-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index 44fb575c0f..cbc26b11b1 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -113,9 +113,6 @@ class H2ProtocolBaseServer(Protocol):
       return
 
     while self._send_remaining[stream_id] > 0:
-      if self._stream_status[stream_id] is False:
-        logging.info('Stream %d is closed.'%stream_id)
-        break
       lfcw = self._conn.local_flow_control_window(stream_id)
       if lfcw == 0:
         break
@@ -125,7 +122,11 @@ class H2ProtocolBaseServer(Protocol):
                     (lfcw, self._send_offset, self._send_offset + bytes_to_send,
                     stream_id))
       data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send]
-      self._conn.send_data(stream_id, data, False)
+      try:
+        self._conn.send_data(stream_id, data, False)
+      except ProtocolError:
+        logging.info('Stream %d is closed'%stream_id)
+        break
       self._send_remaining[stream_id] -= bytes_to_send
       self._send_offset += bytes_to_send
       if self._send_remaining[stream_id] == 0:
@@ -163,7 +164,7 @@ class H2ProtocolBaseServer(Protocol):
     asked in request """
     grpc_msg_size = struct.unpack('i',recv_buffer[1:5][::-1])[0]
     if len(recv_buffer) != GRPC_HEADER_SIZE + grpc_msg_size:
-      logging.error('not enough data to decode req proto. size = %d, needed %s'%(len(recv_buffer), 5+grpc_msg_size))
+      #logging.error('not enough data to decode req proto. size = %d, needed %s'%(len(recv_buffer), 5+grpc_msg_size))
       return None
     req_proto_str = recv_buffer[5:5+grpc_msg_size]
     sr = messages_pb2.SimpleRequest()
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 7ec781d2aa..35308c4787 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -21,6 +21,7 @@ class H2Factory(Factory):
 
   def buildProtocol(self, addr):
     self._num_streams += 1
+    logging.info('New Connection: %d'%self._num_streams)
     if self._testcase == 'rst_after_header':
       t = test_rst_after_header.TestcaseRstStreamAfterHeader()
     elif self._testcase == 'rst_after_data':
diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
index 7dd7cb7948..4c46cab8f9 100644
--- a/test/http2_test/test_goaway.py
+++ b/test/http2_test/test_goaway.py
@@ -1,4 +1,5 @@
 import logging
+import time
 import http2_base_server
 
 class TestcaseGoaway(object):
@@ -23,11 +24,12 @@ class TestcaseGoaway(object):
   def on_connection_lost(self, reason):
     logging.info('Disconnect received. Count %d'%self._iteration)
     # _iteration == 2 => Two different connections have been used.
-    if self._iteration == 2:
+    if self._iteration == 200:
       self._base_server.on_connection_lost(reason)
 
   def on_send_done(self, stream_id):
     self._base_server.on_send_done_default(stream_id)
+    time.sleep(1)
     logging.info('Sending GOAWAY for stream %d:'%stream_id)
     self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=stream_id)
     self._base_server._stream_status[stream_id] = False
-- 
GitLab


From 5b7070a15b7cd13115a15a619d447792d99d78a6 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 1 Dec 2016 16:56:07 -0800
Subject: [PATCH 087/344] bugfix in rst_after_data

---
 test/http2_test/http2_test_server.py   | 2 +-
 test/http2_test/test_rst_after_data.py | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 35308c4787..c74fc4b1fb 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -31,7 +31,7 @@ class H2Factory(Factory):
     elif self._testcase == 'ping':
       t = test_ping.TestcasePing()
     elif self._testcase == 'max_streams':
-      t = TestcaseSettingsMaxStreams(self._num_streams)
+      t = test_max_streams.TestcaseSettingsMaxStreams()
     else:
       logging.error('Unknown test case: %s'%self._testcase)
       assert(0)
diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py
index c4ff56c889..30163c2ceb 100644
--- a/test/http2_test/test_rst_after_data.py
+++ b/test/http2_test/test_rst_after_data.py
@@ -8,6 +8,7 @@ class TestcaseRstStreamAfterData(object):
   def __init__(self):
     self._base_server = http2_base_server.H2ProtocolBaseServer()
     self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['SendDone'] = self.on_send_done
 
   def get_base_server(self):
     return self._base_server
@@ -20,4 +21,7 @@ class TestcaseRstStreamAfterData(object):
       self._ready_to_send = True
       self._base_server.setup_send(response_data, event.stream_id)
       # send reset stream
-      self._base_server.send_reset_stream()
+
+  def on_send_done(self, stream_id):
+    self._base_server.send_reset_stream()
+    self._base_server._stream_status[stream_id] = False
-- 
GitLab


From a16ea7f9b129d34edbdb867e720d4a2ea71e9a7f Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Fri, 2 Dec 2016 10:17:03 -0800
Subject: [PATCH 088/344] added new test (rst_during_data)

---
 test/http2_test/http2_test_server.py    | 41 +++++++++++++++----------
 test/http2_test/test_goaway.py          |  2 +-
 test/http2_test/test_rst_after_data.py  |  1 +
 test/http2_test/test_rst_during_data.py | 30 ++++++++++++++++++
 4 files changed, 56 insertions(+), 18 deletions(-)
 create mode 100644 test/http2_test/test_rst_during_data.py

diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index c74fc4b1fb..5270ee4255 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -9,10 +9,20 @@ from twisted.internet import endpoints, reactor
 import http2_base_server
 import test_rst_after_header
 import test_rst_after_data
+import test_rst_during_data
 import test_goaway
 import test_ping
 import test_max_streams
 
+test_case_mappings = {
+  'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader,
+  'rst_after_data': test_rst_after_data.TestcaseRstStreamAfterData,
+  'rst_during_data': test_rst_during_data.TestcaseRstStreamDuringData,
+  'goaway': test_goaway.TestcaseGoaway,
+  'ping': test_ping.TestcasePing,
+  'max_streams': test_max_streams.TestcaseSettingsMaxStreams,
+}
+
 class H2Factory(Factory):
   def __init__(self, testcase):
     logging.info('In H2Factory')
@@ -22,20 +32,16 @@ class H2Factory(Factory):
   def buildProtocol(self, addr):
     self._num_streams += 1
     logging.info('New Connection: %d'%self._num_streams)
-    if self._testcase == 'rst_after_header':
-      t = test_rst_after_header.TestcaseRstStreamAfterHeader()
-    elif self._testcase == 'rst_after_data':
-      t = test_rst_after_data.TestcaseRstStreamAfterData()
-    elif self._testcase == 'goaway':
-      t = test_goaway.TestcaseGoaway(self._num_streams)
-    elif self._testcase == 'ping':
-      t = test_ping.TestcasePing()
-    elif self._testcase == 'max_streams':
-      t = test_max_streams.TestcaseSettingsMaxStreams()
-    else:
+    if not test_case_mappings.has_key(self._testcase):
       logging.error('Unknown test case: %s'%self._testcase)
       assert(0)
-    return t.get_base_server()
+    else:
+      t = test_case_mappings[self._testcase]
+
+    if self._testcase == 'goaway':
+      return t(self._num_streams).get_base_server()
+    else:
+      return t().get_base_server()
 
 if __name__ == "__main__":
   logging.basicConfig(format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s", level=logging.INFO)
@@ -43,8 +49,9 @@ if __name__ == "__main__":
   parser.add_argument("test")
   parser.add_argument("port")
   args = parser.parse_args()
-  if args.test not in ['rst_after_header', 'rst_after_data', 'goaway', 'ping', 'max_streams']:
-    print 'unknown test: ', args.test
-  endpoint = endpoints.TCP4ServerEndpoint(reactor, int(args.port), backlog=128)
-  endpoint.listen(H2Factory(args.test))
-  reactor.run()
+  if args.test not in test_case_mappings.keys():
+    logging.error('unknown test: %s'%args.test)
+  else:
+    endpoint = endpoints.TCP4ServerEndpoint(reactor, int(args.port), backlog=128)
+    endpoint.listen(H2Factory(args.test))
+    reactor.run()
diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
index 4c46cab8f9..7a915402b2 100644
--- a/test/http2_test/test_goaway.py
+++ b/test/http2_test/test_goaway.py
@@ -24,7 +24,7 @@ class TestcaseGoaway(object):
   def on_connection_lost(self, reason):
     logging.info('Disconnect received. Count %d'%self._iteration)
     # _iteration == 2 => Two different connections have been used.
-    if self._iteration == 200:
+    if self._iteration == 2:
       self._base_server.on_connection_lost(reason)
 
   def on_send_done(self, stream_id):
diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py
index 30163c2ceb..f7927cbcd3 100644
--- a/test/http2_test/test_rst_after_data.py
+++ b/test/http2_test/test_rst_after_data.py
@@ -4,6 +4,7 @@ class TestcaseRstStreamAfterData(object):
   """
     In response to an incoming request, this test sends headers, followed by
     data, followed by a reset stream frame. Client asserts that the RPC failed.
+    Client needs to deliver the complete message to the application layer.
   """
   def __init__(self):
     self._base_server = http2_base_server.H2ProtocolBaseServer()
diff --git a/test/http2_test/test_rst_during_data.py b/test/http2_test/test_rst_during_data.py
new file mode 100644
index 0000000000..105c9403bb
--- /dev/null
+++ b/test/http2_test/test_rst_during_data.py
@@ -0,0 +1,30 @@
+import http2_base_server
+
+class TestcaseRstStreamDuringData(object):
+  """
+    In response to an incoming request, this test sends headers, followed by
+    some data, followed by a reset stream frame. Client asserts that the RPC
+    failed and does not deliver the message to the application.
+  """
+  def __init__(self):
+    self._base_server = http2_base_server.H2ProtocolBaseServer()
+    self._base_server._handlers['DataReceived'] = self.on_data_received
+    self._base_server._handlers['SendDone'] = self.on_send_done
+
+  def get_base_server(self):
+    return self._base_server
+
+  def on_data_received(self, event):
+    self._base_server.on_data_received_default(event)
+    sr = self._base_server.parse_received_data(event.stream_id)
+    if sr:
+      response_data = self._base_server.default_response_data(sr.response_size)
+      self._ready_to_send = True
+      response_len = len(response_data)
+      truncated_response_data = response_data[0:response_len/2]
+      self._base_server.setup_send(truncated_response_data, event.stream_id)
+      # send reset stream
+
+  def on_send_done(self, stream_id):
+    self._base_server.send_reset_stream()
+    self._base_server._stream_status[stream_id] = False
-- 
GitLab


From f0f787d117a20156eeda8dbd6e96398fe4d443a7 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Mon, 5 Dec 2016 09:41:18 -0800
Subject: [PATCH 089/344] Fix Ruby compilation problems on MinGW

---
 Makefile                                |  72 +++++++-------
 Rakefile                                |   2 +-
 src/core/ext/census/tracing.c           |  19 ++--
 src/core/lib/iomgr/tcp_server_windows.c |   6 +-
 templates/Makefile.template             |   8 +-
 templates/Rakefile.template             | 126 ++++++++++++++++++++++++
 6 files changed, 183 insertions(+), 50 deletions(-)
 create mode 100644 templates/Rakefile.template

diff --git a/Makefile b/Makefile
index 87b152514b..248770673a 100644
--- a/Makefile
+++ b/Makefile
@@ -2327,7 +2327,7 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
 install-shared_c: shared_c strip-shared_c install-pkg-config_c
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2336,7 +2336,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2345,7 +2345,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet-imp.a $(prefix)/lib/libgrpc_cronet-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2354,7 +2354,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2371,7 +2371,7 @@ endif
 install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-config_cxx
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2380,7 +2380,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet-imp.a $(prefix)/lib/libgrpc++_cronet-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2389,7 +2389,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection-imp.a $(prefix)/lib/libgrpc++_reflection-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2398,7 +2398,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2415,7 +2415,7 @@ endif
 install-shared_csharp: shared_csharp strip-shared_csharp
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2584,11 +2584,11 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.2 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -2902,11 +2902,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3171,11 +3171,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(L
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3663,11 +3663,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3926,11 +3926,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC+
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4296,11 +4296,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(L
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4419,11 +4419,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP):
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4809,11 +4809,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -5299,11 +5299,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHA
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
 endif
 endif
 
diff --git a/Rakefile b/Rakefile
index cfd4181d7e..8a88b4401f 100755
--- a/Rakefile
+++ b/Rakefile
@@ -83,7 +83,7 @@ task 'dlls' do
   env += 'EMBED_ZLIB=true '
   env += 'BUILDDIR=/tmp '
   env += "V=#{verbose} "
-  out = '/tmp/libs/opt/grpc-1.dll'
+  out = '/tmp/libs/opt/grpc-2.dll'
 
   w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' }
   w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' }
diff --git a/src/core/ext/census/tracing.c b/src/core/ext/census/tracing.c
index 8f0e12296d..536ba98f64 100644
--- a/src/core/ext/census/tracing.c
+++ b/src/core/ext/census/tracing.c
@@ -33,17 +33,24 @@
 
 //#include "src/core/ext/census/tracing.h"
 
+#include <stdlib.h>
+
 #include <grpc/census.h>
 
 /* TODO(aveitch): These are all placeholder implementations. */
 
-// int census_trace_mask(const census_context *context) {
-//   return CENSUS_TRACE_MASK_NONE;
-// }
+int census_trace_mask(const census_context *context) {
+  abort();
+  return CENSUS_TRACE_MASK_NONE;
+}
 
-// void census_set_trace_mask(int trace_mask) {}
+void census_set_trace_mask(int trace_mask) {
+  abort();
+}
 
-// void census_trace_print(census_context *context, uint32_t type,
-//                         const char *buffer, size_t n) {}
+void census_trace_print(census_context *context, uint32_t type,
+                        const char *buffer, size_t n) {
+  abort();
+}
 
 // void SetTracerParams(const Params& params);
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index b8a391c059..40d1746730 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -239,7 +239,7 @@ static grpc_error *prepare_socket(SOCKET sock,
     error = GRPC_WSA_ERROR(WSAGetLastError(), "getsockname");
     goto failure;
   }
-  sockname_temp.len = sockname_temp_len;
+  sockname_temp.len = (size_t)sockname_temp_len;
 
   *port = grpc_sockaddr_get_port(&sockname_temp);
   return GRPC_ERROR_NONE;
@@ -375,7 +375,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
       int peer_name_len = (int)peer_name.len;
       err =
           getpeername(sock, (struct sockaddr *)peer_name.addr, &peer_name_len);
-      peer_name.len = peer_name_len;
+      peer_name.len = (size_t)peer_name_len;
       if (!err) {
         peer_name_string = grpc_sockaddr_to_uri(&peer_name);
       } else {
@@ -493,7 +493,7 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
       if (0 == getsockname(sp->socket->socket,
                            (struct sockaddr *)sockname_temp.addr,
                            &sockname_temp_len)) {
-        sockname_temp.len = sockname_temp_len;
+        sockname_temp.len = (size_t)sockname_temp_len;
         *port = grpc_sockaddr_get_port(&sockname_temp);
         if (*port > 0) {
           allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 109de33c31..d58d4fce41 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1293,7 +1293,7 @@
   % if not lib.get('external_deps', None):
   	$(E) "[INSTALL] Installing $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})"
   	$(Q) $(INSTALL) -d $(prefix)/lib
-  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]})
+  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})
   ifeq ($(SYSTEM),MINGW32)
   	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
   else ifneq ($(SYSTEM),Darwin)
@@ -1552,11 +1552,11 @@
   	$(E) "[LD]      Linking $@"
   	$(Q) mkdir -p `dirname $@`
   ifeq ($(SYSTEM),Darwin)
-  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
+  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   else
   	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.core_version.major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
-  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
-  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
+  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
+  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
   endif
   endif
   % endif
diff --git a/templates/Rakefile.template b/templates/Rakefile.template
new file mode 100644
index 0000000000..2ab505b7c1
--- /dev/null
+++ b/templates/Rakefile.template
@@ -0,0 +1,126 @@
+%YAML 1.2
+--- |
+  # -*- ruby -*-
+  require 'rake/extensiontask'
+  require 'rspec/core/rake_task'
+  require 'rubocop/rake_task'
+  require 'bundler/gem_tasks'
+  require 'fileutils'
+
+  load 'tools/distrib/docker_for_windows.rb'
+
+  # Add rubocop style checking tasks
+  RuboCop::RakeTask.new(:rubocop) do |task|
+    task.options = ['-c', 'src/ruby/.rubocop.yml']
+    task.patterns = ['src/ruby/{lib,spec}/**/*.rb']
+  end
+
+  spec = Gem::Specification.load('grpc.gemspec')
+
+  Gem::PackageTask.new(spec) do |pkg|
+  end
+
+  # Add the extension compiler task
+  Rake::ExtensionTask.new('grpc_c', spec) do |ext|
+    ext.source_pattern = '**/*.{c,h}'
+    ext.ext_dir = File.join('src', 'ruby', 'ext', 'grpc')
+    ext.lib_dir = File.join('src', 'ruby', 'lib', 'grpc')
+    ext.cross_compile = true
+    ext.cross_platform = [
+      'x86-mingw32', 'x64-mingw32',
+      'x86_64-linux', 'x86-linux',
+      'universal-darwin'
+    ]
+    ext.cross_compiling do |spec|
+      spec.files = %w( etc/roots.pem grpc_c.32.ruby grpc_c.64.ruby )
+      spec.files += Dir.glob('src/ruby/bin/**/*')
+      spec.files += Dir.glob('src/ruby/ext/**/*')
+      spec.files += Dir.glob('src/ruby/lib/**/*')
+      spec.files += Dir.glob('src/ruby/pb/**/*')
+    end
+  end
+
+  # Define the test suites
+  SPEC_SUITES = [
+    { id: :wrapper, title: 'wrapper layer', files: %w(src/ruby/spec/*.rb) },
+    { id: :idiomatic, title: 'idiomatic layer', dir: %w(src/ruby/spec/generic),
+      tags: ['~bidi', '~server'] },
+    { id: :bidi, title: 'bidi tests', dir: %w(src/ruby/spec/generic),
+      tag: 'bidi' },
+    { id: :server, title: 'rpc server thread tests', dir: %w(src/ruby/spec/generic),
+      tag: 'server' },
+    { id: :pb, title: 'protobuf service tests', dir: %w(src/ruby/spec/pb) }
+  ]
+  namespace :suite do
+    SPEC_SUITES.each do |suite|
+      desc "Run all specs in the #{suite[:title]} spec suite"
+      RSpec::Core::RakeTask.new(suite[:id]) do |t|
+        ENV['COVERAGE_NAME'] = suite[:id].to_s
+        spec_files = []
+        suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
+
+        if suite[:dir]
+          suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
+        end
+        helper = 'src/ruby/spec/spec_helper.rb'
+        spec_files << helper unless spec_files.include?(helper)
+
+        t.pattern = spec_files
+        t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
+        if suite[:tags]
+          t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
+        end
+      end
+    end
+  end
+
+  desc 'Build the Windows gRPC DLLs for Ruby'
+  task 'dlls' do
+    grpc_config = ENV['GRPC_CONFIG'] || 'opt'
+    verbose = ENV['V'] || '0'
+
+    env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result" '
+    env += 'LDFLAGS=-static '
+    env += 'SYSTEM=MINGW32 '
+    env += 'EMBED_ZLIB=true '
+    env += 'BUILDDIR=/tmp '
+    env += "V=#{verbose} "
+    out = '/tmp/libs/opt/grpc-${settings.core_version.major}.dll'
+
+    w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' }
+    w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' }
+
+    [ w64, w32 ].each do |opt|
+      env_comp = "CC=#{opt[:cross]}-gcc "
+      env_comp += "LD=#{opt[:cross]}-gcc "
+      docker_for_windows "#{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}"
+    end
+
+  end
+
+  desc 'Build the native gem file under rake_compiler_dock'
+  task 'gem:native' do
+    verbose = ENV['V'] || '0'
+
+    grpc_config = ENV['GRPC_CONFIG'] || 'opt'
+
+    if RUBY_PLATFORM =~ /darwin/
+      FileUtils.touch 'grpc_c.32.ruby'
+      FileUtils.touch 'grpc_c.64.ruby'
+      system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
+    else
+      Rake::Task['dlls'].execute
+      docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
+    end
+  end
+
+  # Define dependencies between the suites.
+  task 'suite:wrapper' => [:compile, :rubocop]
+  task 'suite:idiomatic' => 'suite:wrapper'
+  task 'suite:bidi' => 'suite:wrapper'
+  task 'suite:server' => 'suite:wrapper'
+  task 'suite:pb' => 'suite:server'
+
+  desc 'Compiles the gRPC extension then runs all the tests'
+  task all: ['suite:idiomatic', 'suite:bidi', 'suite:pb', 'suite:server']
+  task default: :all
-- 
GitLab


From 116901598f05690168e18e6cd73c6422089006b8 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Mon, 5 Dec 2016 09:42:15 -0800
Subject: [PATCH 090/344] Clang format

---
 src/core/ext/census/tracing.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/core/ext/census/tracing.c b/src/core/ext/census/tracing.c
index 536ba98f64..51508b00ef 100644
--- a/src/core/ext/census/tracing.c
+++ b/src/core/ext/census/tracing.c
@@ -44,9 +44,7 @@ int census_trace_mask(const census_context *context) {
   return CENSUS_TRACE_MASK_NONE;
 }
 
-void census_set_trace_mask(int trace_mask) {
-  abort();
-}
+void census_set_trace_mask(int trace_mask) { abort(); }
 
 void census_trace_print(census_context *context, uint32_t type,
                         const char *buffer, size_t n) {
-- 
GitLab


From a868c0424e492cfa135390dacb76c30c525dd794 Mon Sep 17 00:00:00 2001
From: Alex Polcyn <apolcyn@google.com>
Date: Mon, 5 Dec 2016 18:49:08 +0000
Subject: [PATCH 091/344] keep old behavior to not destroy ruby server if not
 instantiated

---
 src/ruby/ext/grpc/rb_server.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 6783fd3f88..55c745965b 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -67,17 +67,19 @@ static void destroy_server(grpc_rb_server *server, gpr_timespec deadline) {
   grpc_event ev;
   // This can be started by app or implicitly by GC. Avoid a race between these.
   if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
-    grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
-    ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
-    if (ev.type == GRPC_QUEUE_TIMEOUT) {
-      grpc_server_cancel_all_calls(server->wrapped);
-      rb_completion_queue_pluck(server->queue, NULL,
-                                gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+    if (server->wrapped != NULL) {
+      grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
+      ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
+      if (ev.type == GRPC_QUEUE_TIMEOUT) {
+        grpc_server_cancel_all_calls(server->wrapped);
+        rb_completion_queue_pluck(server->queue, NULL,
+                                  gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+      }
+      grpc_server_destroy(server->wrapped);
+      grpc_rb_completion_queue_destroy(server->queue);
+      server->wrapped = NULL;
+      server->queue = NULL;
     }
-    grpc_server_destroy(server->wrapped);
-    grpc_rb_completion_queue_destroy(server->queue);
-    server->wrapped = NULL;
-    server->queue = NULL;
   }
 }
 
-- 
GitLab


From 804c9e90fc4e7d11294fec69801ff7bc99134d3c Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Mon, 5 Dec 2016 12:19:57 -0800
Subject: [PATCH 092/344] Add Electron tests to portability test matrix

---
 tools/dockerfile/test/node_jessie_x64/Dockerfile | 7 +++++++
 tools/run_tests/build_node_electron.sh           | 1 +
 tools/run_tests/pre_build_node_electron.sh       | 2 ++
 tools/run_tests/run_node_electron.sh             | 1 +
 tools/run_tests/run_tests_matrix.py              | 9 +++++++++
 5 files changed, 20 insertions(+)

diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile
index d9a7501829..120ea59ae2 100644
--- a/tools/dockerfile/test/node_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile
@@ -42,12 +42,18 @@ RUN apt-get update && apt-get install -y \
   git \
   golang \
   gyp \
+  libasound2 \
   lcov \
   libc6 \
   libc6-dbg \
   libc6-dev \
+  libgconf-2-4 \
   libgtest-dev \
+  libgtk2.0-0 \
+  libnss3 \
   libtool \
+  libxss1\
+  libxtst6 \
   make \
   perl \
   strace \
@@ -57,6 +63,7 @@ RUN apt-get update && apt-get install -y \
   telnet \
   unzip \
   wget \
+  xvfb \
   zip && apt-get clean
 
 #================
diff --git a/tools/run_tests/build_node_electron.sh b/tools/run_tests/build_node_electron.sh
index 4e7c3e4789..1c95c513b3 100755
--- a/tools/run_tests/build_node_electron.sh
+++ b/tools/run_tests/build_node_electron.sh
@@ -42,4 +42,5 @@ export npm_config_target=$ELECTRON_VERSION
 export npm_config_disturl=https://atom.io/download/atom-shell
 export npm_config_runtime=electron
 export npm_config_build_from_source=true
+mkdir -p ~/.electron-gyp
 HOME=~/.electron-gyp npm install --unsafe-perm
diff --git a/tools/run_tests/pre_build_node_electron.sh b/tools/run_tests/pre_build_node_electron.sh
index d8d9df4ddb..95c56aa509 100755
--- a/tools/run_tests/pre_build_node_electron.sh
+++ b/tools/run_tests/pre_build_node_electron.sh
@@ -34,4 +34,6 @@ ELECTRON_VERSION=$1
 nvm install 6
 set -ex
 
+npm install xvfb-maybe
+
 npm install electron@$ELECTRON_VERSION
diff --git a/tools/run_tests/run_node_electron.sh b/tools/run_tests/run_node_electron.sh
index 7f8a824df2..1999ffb0fa 100755
--- a/tools/run_tests/run_node_electron.sh
+++ b/tools/run_tests/run_node_electron.sh
@@ -40,5 +40,6 @@ test_directory='src/node/test'
 timeout=8000
 
 JUNIT_REPORT_PATH=src/node/report.xml JUNIT_REPORT_STACK=1 \
+  ./node_modules/.bin/xvfb-maybe \
   ./node_modules/.bin/electron-mocha --timeout $timeout \
   --reporter mocha-jenkins-reporter $test_directory
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 989bc7eb21..d03e34766e 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -230,6 +230,15 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                               labels=['portability'],
                               extra_args=extra_args,
                               inner_jobs=inner_jobs)
+
+  test_jobs += _generate_jobs(languages=['node'],
+                              configs=['dbg'],
+                              platforms=['linux'],
+                              arch='default',
+                              compiler='electron1.3',
+                              labels=['portability'],
+                              extra_args=extra_args,
+                              inner_jobs=inner_jobs)
   return test_jobs
 
 
-- 
GitLab


From a0804ef0d2fe1661eb7511e6800cca6e68b13e68 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Mon, 5 Dec 2016 15:54:56 -0800
Subject: [PATCH 093/344] Fix test runner failures for Python on Windows

---
 tools/run_tests/run_tests.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index cd49dfa907..0424cf3d6f 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -435,8 +435,8 @@ class PythonLanguage(object):
     return [self.config.job_spec(
         config.run,
         timeout_seconds=5*60,
-        environ=dict(environment.items() +
-                     [('GRPC_PYTHON_TESTRUNNER_FILTER', suite_name)]),
+        environ=dict(list(environment.items()) +
+                     [('GRPC_PYTHON_TESTRUNNER_FILTER', str(suite_name))]),
         shortname='%s.test.%s' % (config.name, suite_name),)
         for suite_name in tests_json
         for config in self.pythons]
-- 
GitLab


From 88e3e7ad901524fea59cb8ab761226f4f7d72c08 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 15:10:24 -0800
Subject: [PATCH 094/344] port cronet

---
 .../ext/transport/cronet/transport/cronet_transport.c     | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index a4c110101e..c8f2e34ccc 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -418,6 +418,7 @@ static void on_response_headers_received(
     cronet_bidirectional_stream *stream,
     const cronet_bidirectional_stream_header_array *headers,
     const char *negotiated_protocol) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
              headers, negotiated_protocol);
   stream_obj *s = (stream_obj *)stream->annotation;
@@ -428,12 +429,13 @@ static void on_response_headers_received(
   for (size_t i = 0; i < headers->count; i++) {
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.initial_metadata,
-        grpc_mdelem_from_metadata_strings(
+        grpc_mdelem_from_metadata_strings(&exec_ctx,
             grpc_mdstr_from_string(headers->headers[i].key),
             grpc_mdstr_from_string(headers->headers[i].value)));
   }
   s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
   gpr_mu_unlock(&s->mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   execute_from_storage(s);
 }
 
@@ -491,6 +493,7 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
 static void on_response_trailers_received(
     cronet_bidirectional_stream *stream,
     const cronet_bidirectional_stream_header_array *trailers) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream,
              trailers);
   stream_obj *s = (stream_obj *)stream->annotation;
@@ -504,13 +507,14 @@ static void on_response_trailers_received(
                trailers->headers[i].value);
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.trailing_metadata,
-        grpc_mdelem_from_metadata_strings(
+        grpc_mdelem_from_metadata_strings(&exec_ctx,
             grpc_mdstr_from_string(trailers->headers[i].key),
             grpc_mdstr_from_string(trailers->headers[i].value)));
     s->state.rs.trailing_metadata_valid = true;
   }
   s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
   gpr_mu_unlock(&s->mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   execute_from_storage(s);
 }
 
-- 
GitLab


From b6821f68b208871c41f888e33425e05657cf5c78 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 15:10:42 -0800
Subject: [PATCH 095/344] clang-format

---
 .../client_channel/http_connect_handshaker.c  |  2 +-
 .../client/secure/secure_channel_create.c     |  4 +--
 .../server/secure/server_secure_chttp2.c      |  4 +--
 .../cronet/transport/cronet_transport.c       |  8 +++---
 .../lib/http/httpcli_security_connector.c     | 12 +++++----
 .../security/transport/security_connector.c   | 27 ++++++++++++-------
 .../security/transport/security_handshaker.c  |  3 ++-
 7 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 520e79fdf6..76e2c627ef 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -97,7 +97,7 @@ static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
 // Set args fields to NULL, saving the endpoint and read buffer for
 // later destruction.
 static void cleanup_args_for_failure_locked(
-    grpc_exec_ctx *exec_ctx, http_connect_handshaker* handshaker) {
+    grpc_exec_ctx* exec_ctx, http_connect_handshaker* handshaker) {
   handshaker->endpoint_to_destroy = handshaker->args->endpoint;
   handshaker->args->endpoint = NULL;
   handshaker->read_buffer_to_destroy = handshaker->args->read_buffer;
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 880fa28c22..a39f73e90f 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -137,8 +137,8 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   grpc_channel_security_connector *security_connector;
   grpc_channel_args *new_args_from_connector;
   if (grpc_channel_credentials_create_security_connector(
-          &exec_ctx, creds, target, args, &security_connector, &new_args_from_connector) !=
-      GRPC_SECURITY_OK) {
+          &exec_ctx, creds, target, args, &security_connector,
+          &new_args_from_connector) != GRPC_SECURITY_OK) {
     grpc_exec_ctx_finish(&exec_ctx);
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index df80407c5d..a08fb2a18e 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -67,8 +67,8 @@ static void server_security_handshaker_factory_destroy(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf) {
   server_security_handshaker_factory *handshaker_factory =
       (server_security_handshaker_factory *)hf;
-  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &handshaker_factory->security_connector->base,
-                                "server");
+  GRPC_SECURITY_CONNECTOR_UNREF(
+      exec_ctx, &handshaker_factory->security_connector->base, "server");
   gpr_free(hf);
 }
 
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index c8f2e34ccc..f9dae9e302 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -429,8 +429,8 @@ static void on_response_headers_received(
   for (size_t i = 0; i < headers->count; i++) {
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.initial_metadata,
-        grpc_mdelem_from_metadata_strings(&exec_ctx,
-            grpc_mdstr_from_string(headers->headers[i].key),
+        grpc_mdelem_from_metadata_strings(
+            &exec_ctx, grpc_mdstr_from_string(headers->headers[i].key),
             grpc_mdstr_from_string(headers->headers[i].value)));
   }
   s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
@@ -507,8 +507,8 @@ static void on_response_trailers_received(
                trailers->headers[i].value);
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.trailing_metadata,
-        grpc_mdelem_from_metadata_strings(&exec_ctx,
-            grpc_mdstr_from_string(trailers->headers[i].key),
+        grpc_mdelem_from_metadata_strings(
+            &exec_ctx, grpc_mdstr_from_string(trailers->headers[i].key),
             grpc_mdstr_from_string(trailers->headers[i].value)));
     s->state.rs.trailing_metadata_valid = true;
   }
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index c7c3b5df81..0a456ccc09 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -50,7 +50,8 @@ typedef struct {
   char *secure_peer_name;
 } grpc_httpcli_ssl_channel_security_connector;
 
-static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) {
+static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_httpcli_ssl_channel_security_connector *c =
       (grpc_httpcli_ssl_channel_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
@@ -103,8 +104,9 @@ static grpc_security_connector_vtable httpcli_ssl_vtable = {
     httpcli_ssl_destroy, httpcli_ssl_check_peer};
 
 static grpc_security_status httpcli_ssl_channel_security_connector_create(
-    grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *secure_peer_name, grpc_channel_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
+    size_t pem_root_certs_size, const char *secure_peer_name,
+    grpc_channel_security_connector **sc) {
   tsi_result result = TSI_OK;
   grpc_httpcli_ssl_channel_security_connector *c;
 
@@ -183,14 +185,14 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
   c->arg = arg;
   c->handshake_mgr = grpc_handshake_manager_create();
   GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
-               exec_ctx,  pem_root_certs, pem_root_certs_size, host, &sc) ==
+                 exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
              GRPC_SECURITY_OK);
   grpc_channel_security_connector_create_handshakers(exec_ctx, sc,
                                                      c->handshake_mgr);
   grpc_handshake_manager_do_handshake(
       exec_ctx, c->handshake_mgr, tcp, NULL /* channel_args */, deadline,
       NULL /* acceptor */, on_handshake_done, c /* user_data */);
-  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx,&sc->base, "httpcli");
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "httpcli");
 }
 
 const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake};
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index fc34442a63..d9c2361ae0 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -171,7 +171,8 @@ grpc_security_connector *grpc_security_connector_ref(
 }
 
 #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
-void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc,
                                    const char *file, int line,
                                    const char *reason) {
   if (sc == NULL) return;
@@ -179,7 +180,8 @@ void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx, grpc_security_connec
           "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
           (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
 #else
-void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) {
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc) {
   if (sc == NULL) return;
 #endif
   if (gpr_unref(&sc->refcount)) sc->vtable->destroy(exec_ctx, sc);
@@ -232,13 +234,17 @@ grpc_security_connector *grpc_find_security_connector_in_args(
 
 /* -- Fake implementation. -- */
 
-static void fake_channel_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) {
+static void fake_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_security_connector *sc) {
   grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
   grpc_call_credentials_unref(exec_ctx, c->request_metadata_creds);
   gpr_free(sc);
 }
 
-static void fake_server_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) { gpr_free(sc); }
+static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
+  gpr_free(sc);
+}
 
 static void fake_check_peer(grpc_exec_ctx *exec_ctx,
                             grpc_security_connector *sc, tsi_peer peer,
@@ -346,7 +352,8 @@ typedef struct {
   tsi_ssl_handshaker_factory *handshaker_factory;
 } grpc_ssl_server_security_connector;
 
-static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) {
+static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_ssl_channel_security_connector *c =
       (grpc_ssl_channel_security_connector *)sc;
   grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
@@ -358,7 +365,8 @@ static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector
   gpr_free(sc);
 }
 
-static void ssl_server_destroy(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc) {
+static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_security_connector *sc) {
   grpc_ssl_server_security_connector *c =
       (grpc_ssl_server_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
@@ -661,8 +669,8 @@ size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
   return GRPC_SLICE_LENGTH(default_pem_root_certs);
 }
 
-grpc_security_status grpc_ssl_channel_security_connector_create(grpc_exec_ctx *exec_ctx,
-    grpc_call_credentials *request_metadata_creds,
+grpc_security_status grpc_ssl_channel_security_connector_create(
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
@@ -739,7 +747,8 @@ error:
 }
 
 grpc_security_status grpc_ssl_server_security_connector_create(
-grpc_exec_ctx *exec_ctx,    const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+    grpc_server_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index c46e7e0f87..4a5bbb5402 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -100,7 +100,8 @@ static void security_handshaker_unref(grpc_exec_ctx *exec_ctx,
 
 // Set args fields to NULL, saving the endpoint and read buffer for
 // later destruction.
-static void cleanup_args_for_failure_locked(grpc_exec_ctx *exec_ctx, security_handshaker *h) {
+static void cleanup_args_for_failure_locked(grpc_exec_ctx *exec_ctx,
+                                            security_handshaker *h) {
   h->endpoint_to_destroy = h->args->endpoint;
   h->args->endpoint = NULL;
   h->read_buffer_to_destroy = h->args->read_buffer;
-- 
GitLab


From bd6c1c03ebbf5d7818de42edfd9f42dafae9a2df Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 17:35:57 -0800
Subject: [PATCH 096/344] add copyright

---
 .../run_tests/sanity/core_banned_functions.py | 31 ++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index cf88c42d46..afac10bf80 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -1,4 +1,33 @@
-#!/usr/bin/python
+#!/usr/bin/env python2.7
+
+# Copyright 2016, 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.
 
 import os
 import sys
-- 
GitLab


From 25910a2896254c2ec866bee77f5c32a3acff5810 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 17:39:45 -0800
Subject: [PATCH 097/344] Fix compilation

---
 test/cpp/common/channel_arguments_test.cc | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 60d3215265..190d32ce06 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -37,7 +37,11 @@
 #include <grpc/grpc.h>
 #include <grpc/support/useful.h>
 #include <gtest/gtest.h>
+
+extern "C" {
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/socket_mutator.h"
+}
 
 namespace grpc {
 namespace testing {
@@ -228,7 +232,11 @@ TEST_F(ChannelArgumentsTest, SetSocketMutator) {
   EXPECT_FALSE(HasArg(arg0));
 
   // arg0 is destroyed by grpc_socket_mutator_to_arg(mutator1)
-  arg1.value.pointer.vtable->destroy(arg1.value.pointer.p);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    arg1.value.pointer.vtable->destroy(&exec_ctx, arg1.value.pointer.p);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
-- 
GitLab


From 6822a7a4f647d54468e7042d0e1d1265db4e900f Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 19:28:52 -0800
Subject: [PATCH 098/344] Make core_banned_functions.py pass again

---
 .../ext/client_channel/http_connect_handshaker.c    | 11 +++++++----
 .../ext/transport/chttp2/client/chttp2_connector.c  |  3 ++-
 .../ext/transport/chttp2/server/chttp2_server.c     |  3 ++-
 src/core/lib/channel/http_client_filter.c           |  2 +-
 src/core/lib/http/httpcli_security_connector.c      |  3 ++-
 src/core/lib/iomgr/tcp_uv.c                         |  2 +-
 .../lib/security/transport/security_handshaker.c    | 13 +++++++------
 7 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 76e2c627ef..1e198cba97 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/http/format_request.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/env.h"
 
 typedef struct http_connect_handshaker {
@@ -82,12 +83,13 @@ static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
       grpc_endpoint_destroy(exec_ctx, handshaker->endpoint_to_destroy);
     }
     if (handshaker->read_buffer_to_destroy != NULL) {
-      grpc_slice_buffer_destroy(handshaker->read_buffer_to_destroy);
+      grpc_slice_buffer_destroy_internal(exec_ctx,
+                                         handshaker->read_buffer_to_destroy);
       gpr_free(handshaker->read_buffer_to_destroy);
     }
     gpr_free(handshaker->proxy_server);
     gpr_free(handshaker->server_name);
-    grpc_slice_buffer_destroy(&handshaker->write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
     grpc_http_parser_destroy(&handshaker->http_parser);
     grpc_http_response_destroy(&handshaker->http_response);
     gpr_free(handshaker);
@@ -193,7 +195,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
                                &handshaker->args->read_buffer->slices[i + 1],
                                handshaker->args->read_buffer->count - i - 1);
         grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer);
-        grpc_slice_buffer_destroy(&tmp_buffer);
+        grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
         break;
       }
     }
@@ -210,7 +212,8 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
   // complete (e.g., handling chunked transfer encoding or looking
   // at the Content-Length: header).
   if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
-    grpc_slice_buffer_reset_and_unref(handshaker->args->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               handshaker->args->read_buffer);
     grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
                        handshaker->args->read_buffer,
                        &handshaker->response_read_closure);
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 9927646b7a..f311b14f2b 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -48,6 +48,7 @@
 #include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 typedef struct {
   grpc_connector base;
@@ -127,7 +128,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
       grpc_endpoint_shutdown(exec_ctx, args->endpoint);
       grpc_endpoint_destroy(exec_ctx, args->endpoint);
       grpc_channel_args_destroy(exec_ctx, args->args);
-      grpc_slice_buffer_destroy(args->read_buffer);
+      grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
       gpr_free(args->read_buffer);
     } else {
       error = GRPC_ERROR_REF(error);
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index 4a182146bf..4319454407 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -50,6 +50,7 @@
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/server.h"
 
@@ -149,7 +150,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
       grpc_endpoint_shutdown(exec_ctx, args->endpoint);
       grpc_endpoint_destroy(exec_ctx, args->endpoint);
       grpc_channel_args_destroy(exec_ctx, args->args);
-      grpc_slice_buffer_destroy(args->read_buffer);
+      grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
       gpr_free(args->read_buffer);
     }
   } else {
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 3af999ec53..81310741ac 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -111,7 +111,7 @@ static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data,
     grpc_slice pct_decoded_msg =
         grpc_permissive_percent_decode_slice(md->value->slice);
     if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) {
-      grpc_slice_unref(pct_decoded_msg);
+      grpc_slice_unref_internal(exec_ctx, pct_decoded_msg);
       return md;
     } else {
       return grpc_mdelem_from_metadata_strings(
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 0a456ccc09..414383f8ca 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/security/transport/security_handshaker.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/tsi/ssl_transport_security.h"
 
@@ -158,7 +159,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
     c->func(exec_ctx, c->arg, NULL);
   } else {
     grpc_channel_args_destroy(exec_ctx, args->args);
-    grpc_slice_buffer_destroy(args->read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
     gpr_free(args->read_buffer);
     c->func(exec_ctx, c->arg, args->endpoint);
   }
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 6e2ad1dbe9..257a4778c8 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -181,7 +181,7 @@ static void uv_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   GPR_ASSERT(tcp->read_cb == NULL);
   tcp->read_cb = cb;
   tcp->read_slices = read_slices;
-  grpc_slice_buffer_reset_and_unref(read_slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx,read_slices);
   TCP_REF(tcp, "read");
   // TODO(murgatroid99): figure out what the return value here means
   status =
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 4a5bbb5402..e96c480044 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
 
@@ -86,12 +87,12 @@ static void security_handshaker_unref(grpc_exec_ctx *exec_ctx,
       grpc_endpoint_destroy(exec_ctx, h->endpoint_to_destroy);
     }
     if (h->read_buffer_to_destroy != NULL) {
-      grpc_slice_buffer_destroy(h->read_buffer_to_destroy);
+      grpc_slice_buffer_destroy_internal(exec_ctx, h->read_buffer_to_destroy);
       gpr_free(h->read_buffer_to_destroy);
     }
     gpr_free(h->handshake_buffer);
-    grpc_slice_buffer_destroy(&h->left_overs);
-    grpc_slice_buffer_destroy(&h->outgoing);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->left_overs);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing);
     GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
     GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, h->connector, "handshake");
     gpr_free(h);
@@ -163,7 +164,7 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
   h->left_overs.length = 0;
   // Clear out the read buffer before it gets passed to the transport,
   // since any excess bytes were already copied to h->left_overs.
-  grpc_slice_buffer_reset_and_unref(h->args->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer);
   // Add auth context to channel args.
   grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context);
   grpc_channel_args *tmp_args = h->args->args;
@@ -216,7 +217,7 @@ static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx,
   // Send data.
   grpc_slice to_send =
       grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
-  grpc_slice_buffer_reset_and_unref(&h->outgoing);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing);
   grpc_slice_buffer_add(&h->outgoing, to_send);
   grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
                       &h->on_handshake_data_sent_to_peer);
@@ -285,7 +286,7 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
           grpc_slice_split_tail(&h->args->read_buffer->slices[i],
                                 consumed_slice_size));
       /* split_tail above increments refcount. */
-      grpc_slice_unref(h->args->read_buffer->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, h->args->read_buffer->slices[i]);
     }
     grpc_slice_buffer_addn(
         &h->left_overs, &h->args->read_buffer->slices[i + 1],
-- 
GitLab


From 30d50fed6d05f6ee28e579bd08c0145d59476e88 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 19:34:32 -0800
Subject: [PATCH 099/344] Fix build

---
 BUILD                                                        | 5 +++++
 build.yaml                                                   | 1 +
 gRPC-Core.podspec                                            | 2 ++
 grpc.gemspec                                                 | 1 +
 package.xml                                                  | 1 +
 tools/doxygen/Doxyfile.core.internal                         | 1 +
 tools/run_tests/sources_and_headers.json                     | 2 ++
 vsprojects/vcxproj/grpc/grpc.vcxproj                         | 1 +
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters                 | 3 +++
 vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj     | 1 +
 .../vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters    | 3 +++
 vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj       | 1 +
 .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters      | 3 +++
 13 files changed, 25 insertions(+)

diff --git a/BUILD b/BUILD
index 72fc965fff..2349019a06 100644
--- a/BUILD
+++ b/BUILD
@@ -231,6 +231,7 @@ cc_library(
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -670,6 +671,7 @@ cc_library(
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -1062,6 +1064,7 @@ cc_library(
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -1625,6 +1628,7 @@ cc_library(
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -2654,6 +2658,7 @@ objc_library(
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
diff --git a/build.yaml b/build.yaml
index d8792a9d70..51ee141f12 100644
--- a/build.yaml
+++ b/build.yaml
@@ -238,6 +238,7 @@ filegroups:
   - src/core/lib/json/json_reader.h
   - src/core/lib/json/json_writer.h
   - src/core/lib/slice/percent_encoding.h
+  - src/core/lib/slice/slice_internal.h
   - src/core/lib/slice/slice_string_helpers.h
   - src/core/lib/surface/api_trace.h
   - src/core/lib/surface/call.h
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 89e99c30b3..cdda52f07c 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -321,6 +321,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/json/json_reader.h',
                       'src/core/lib/json/json_writer.h',
                       'src/core/lib/slice/percent_encoding.h',
+                      'src/core/lib/slice/slice_internal.h',
                       'src/core/lib/slice/slice_string_helpers.h',
                       'src/core/lib/surface/api_trace.h',
                       'src/core/lib/surface/call.h',
@@ -728,6 +729,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/json/json_reader.h',
                               'src/core/lib/json/json_writer.h',
                               'src/core/lib/slice/percent_encoding.h',
+                              'src/core/lib/slice/slice_internal.h',
                               'src/core/lib/slice/slice_string_helpers.h',
                               'src/core/lib/surface/api_trace.h',
                               'src/core/lib/surface/call.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 592336840a..a3e4cbe4b0 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -240,6 +240,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/json/json_reader.h )
   s.files += %w( src/core/lib/json/json_writer.h )
   s.files += %w( src/core/lib/slice/percent_encoding.h )
+  s.files += %w( src/core/lib/slice/slice_internal.h )
   s.files += %w( src/core/lib/slice/slice_string_helpers.h )
   s.files += %w( src/core/lib/surface/api_trace.h )
   s.files += %w( src/core/lib/surface/call.h )
diff --git a/package.xml b/package.xml
index f75ea6898e..5f28ac8a01 100644
--- a/package.xml
+++ b/package.xml
@@ -248,6 +248,7 @@
     <file baseinstalldir="/" name="src/core/lib/json/json_reader.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_writer.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 156228fe36..6581cba3d5 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -863,6 +863,7 @@ src/core/lib/json/json_common.h \
 src/core/lib/json/json_reader.h \
 src/core/lib/json/json_writer.h \
 src/core/lib/slice/percent_encoding.h \
+src/core/lib/slice/slice_internal.h \
 src/core/lib/slice/slice_string_helpers.h \
 src/core/lib/surface/api_trace.h \
 src/core/lib/surface/call.h \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 8d8a3c2e79..6fedc9e68d 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6749,6 +6749,7 @@
       "src/core/lib/json/json_reader.h", 
       "src/core/lib/json/json_writer.h", 
       "src/core/lib/slice/percent_encoding.h", 
+      "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.h", 
       "src/core/lib/surface/api_trace.h", 
       "src/core/lib/surface/call.h", 
@@ -6942,6 +6943,7 @@
       "src/core/lib/slice/percent_encoding.h", 
       "src/core/lib/slice/slice.c", 
       "src/core/lib/slice/slice_buffer.c", 
+      "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.c", 
       "src/core/lib/slice/slice_string_helpers.h", 
       "src/core/lib/surface/alarm.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index cae2ea51db..cf66c85f3f 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -372,6 +372,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 9e465ea7ef..78997973ca 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -959,6 +959,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index a16850d448..4f9234a20b 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -265,6 +265,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 18076e75d9..cf5c8dbda8 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -749,6 +749,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index bfcf8f4bd8..367b23cd1a 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -362,6 +362,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 8edfcd7a55..32c2bd7355 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -872,6 +872,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
-- 
GitLab


From 588337691eb1ac61d1d0a670a6ea4bb75cbf6f3d Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 19:36:23 -0800
Subject: [PATCH 100/344] Fix function names

---
 src/core/lib/iomgr/tcp_client_uv.c | 6 +++---
 src/core/lib/iomgr/tcp_server_uv.c | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index b07f9ceffa..5f2ccfee76 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -59,7 +59,7 @@ typedef struct grpc_uv_tcp_connect {
 
 static void uv_tcp_connect_cleanup(grpc_exec_ctx *exec_ctx,
                                    grpc_uv_tcp_connect *connect) {
-  grpc_resource_quota_internal_unref(exec_ctx, connect->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, connect->resource_quota);
   gpr_free(connect);
 }
 
@@ -128,8 +128,8 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
   if (channel_args != NULL) {
     for (size_t i = 0; i < channel_args->num_args; i++) {
       if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index b5b9b92a20..050bb9e141 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -89,11 +89,11 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -136,7 +136,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
     gpr_free(sp->handle);
     gpr_free(sp);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
   gpr_free(s);
 }
 
-- 
GitLab


From fede4d4198c5d211b8042d29a6f86ff7cafcf666 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 6 Dec 2016 20:20:10 -0800
Subject: [PATCH 101/344] Fix windows

---
 src/core/lib/iomgr/tcp_windows.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 56fdaa5d82..8b3b44aaaa 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -53,6 +53,7 @@
 #include "src/core/lib/iomgr/socket_windows.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 #if defined(__MSYS__) && defined(GPR_ARCH_64)
 /* Nasty workaround for nasty bug when using the 64 bits msys compiler
-- 
GitLab


From ab7b2d82e989840f299c136f7062d8c6548ec5e1 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 7 Dec 2016 07:26:34 -0800
Subject: [PATCH 102/344] clang-format

---
 src/core/lib/iomgr/tcp_uv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 257a4778c8..f3510bc780 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -181,7 +181,7 @@ static void uv_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   GPR_ASSERT(tcp->read_cb == NULL);
   tcp->read_cb = cb;
   tcp->read_slices = read_slices;
-  grpc_slice_buffer_reset_and_unref_internal(exec_ctx,read_slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
   TCP_REF(tcp, "read");
   // TODO(murgatroid99): figure out what the return value here means
   status =
-- 
GitLab


From 123d0dbd614f6d6626295dec93764549e0e650ff Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Wed, 7 Dec 2016 09:37:24 -0800
Subject: [PATCH 103/344] bug fix

---
 src/objective-c/CronetFramework.podspec | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/objective-c/CronetFramework.podspec b/src/objective-c/CronetFramework.podspec
index d45b8d8143..509358dada 100644
--- a/src/objective-c/CronetFramework.podspec
+++ b/src/objective-c/CronetFramework.podspec
@@ -70,7 +70,6 @@ Pod::Spec.new do |s|
   s.vendored_framework = "Cronet.framework"
   s.author             = "The Chromium Authors"
   s.ios.deployment_target = "8.0"
-  file = 
   s.source       = { :http => "https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework-v#{v}.zip"}
   s.preserve_paths = "Cronet.framework"
   s.public_header_files = "Cronet.framework/Headers/**/*{.h}"
-- 
GitLab


From 53360f2d1c89b3b69c06ace8e865515a031da1c4 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 12 Jul 2016 14:02:12 +0200
Subject: [PATCH 104/344] Backport Python features to 1.0.x

Backports per-object grpc_init/deinit and separated-file grpc protoc
codegen (#7538, #8246, #8920).
---
 src/compiler/python_generator.cc              | 768 +++++++++++-------
 src/compiler/python_generator.h               |   5 +-
 .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi  |   2 +
 .../grpc/_cython/_cygrpc/channel.pyx.pxi      |   2 +
 .../_cython/_cygrpc/completion_queue.pyx.pxi  |   2 +
 .../grpc/_cython/_cygrpc/credentials.pyx.pxi  |  14 +
 .../grpc/_cython/_cygrpc/records.pyx.pxi      |  12 +
 .../grpc/_cython/_cygrpc/server.pyx.pxi       |   2 +
 src/python/grpcio/grpc/_cython/cygrpc.pyx     |   4 -
 src/python/grpcio_health_checking/.gitignore  |   1 +
 src/python/grpcio_tests/.gitignore            |   1 +
 .../protoc_plugin/_split_definitions_test.py  | 304 +++++++
 .../protos/invocation_testing/__init__.py     |  30 +
 .../protos/invocation_testing/same.proto      |  39 +
 .../split_messages/__init__.py                |  30 +
 .../split_messages/messages.proto             |  35 +
 .../split_services/__init__.py                |  30 +
 .../split_services/services.proto             |  38 +
 src/python/grpcio_tests/tests/tests.json      |  40 +-
 19 files changed, 1026 insertions(+), 333 deletions(-)
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/same.proto
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/messages.proto
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
 create mode 100644 src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/services.proto

diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 0e7b9fbf4d..b0a60092ab 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -35,6 +35,8 @@
 #include <cassert>
 #include <cctype>
 #include <cstring>
+#include <fstream>
+#include <iostream>
 #include <map>
 #include <memory>
 #include <ostream>
@@ -66,64 +68,11 @@ using std::vector;
 
 namespace grpc_python_generator {
 
-GeneratorConfiguration::GeneratorConfiguration()
-    : grpc_package_root("grpc"), beta_package_root("grpc.beta") {}
-
-PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
-    : config_(config) {}
-
-PythonGrpcGenerator::~PythonGrpcGenerator() {}
-
-bool PythonGrpcGenerator::Generate(
-    const FileDescriptor* file, const grpc::string& parameter,
-    GeneratorContext* context, grpc::string* error) const {
-  // Get output file name.
-  grpc::string file_name;
-  static const int proto_suffix_length = strlen(".proto");
-  if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
-      file->name().find_last_of(".proto") == file->name().size() - 1) {
-    file_name = file->name().substr(
-        0, file->name().size() - proto_suffix_length) + "_pb2.py";
-  } else {
-    *error = "Invalid proto file name. Proto file must end with .proto";
-    return false;
-  }
-
-  std::unique_ptr<ZeroCopyOutputStream> output(
-      context->OpenForInsert(file_name, "module_scope"));
-  CodedOutputStream coded_out(output.get());
-  bool success = false;
-  grpc::string code = "";
-  tie(success, code) = grpc_python_generator::GetServices(file, config_);
-  if (success) {
-    coded_out.WriteRaw(code.data(), code.size());
-    return true;
-  } else {
-    return false;
-  }
-}
-
 namespace {
-//////////////////////////////////
-// BEGIN FORMATTING BOILERPLATE //
-//////////////////////////////////
-
-// Converts an initializer list of the form { key0, value0, key1, value1, ... }
-// into a map of key* to value*. Is merely a readability helper for later code.
-map<grpc::string, grpc::string> ListToDict(
-    const initializer_list<grpc::string>& values) {
-  assert(values.size() % 2 == 0);
-  map<grpc::string, grpc::string> value_map;
-  auto value_iter = values.begin();
-  for (unsigned i = 0; i < values.size()/2; ++i) {
-    grpc::string key = *value_iter;
-    ++value_iter;
-    grpc::string value = *value_iter;
-    value_map[key] = value;
-    ++value_iter;
-  }
-  return value_map;
-}
+
+typedef vector<const Descriptor*> DescriptorVector;
+typedef map<grpc::string, grpc::string> StringMap;
+typedef vector<grpc::string> StringVector;
 
 // Provides RAII indentation handling. Use as:
 // {
@@ -138,18 +87,12 @@ class IndentScope {
     printer_->Indent();
   }
 
-  ~IndentScope() {
-    printer_->Outdent();
-  }
+  ~IndentScope() { printer_->Outdent(); }
 
  private:
   Printer* printer_;
 };
 
-////////////////////////////////
-// END FORMATTING BOILERPLATE //
-////////////////////////////////
-
 // TODO(https://github.com/google/protobuf/issues/888):
 // Export `ModuleName` from protobuf's
 // `src/google/protobuf/compiler/python/python_generator.cc` file.
@@ -173,27 +116,80 @@ grpc::string ModuleAlias(const grpc::string& filename) {
   return module_name;
 }
 
+// Tucks all generator state in an anonymous namespace away from
+// PythonGrpcGenerator and the header file, mostly to encourage future changes
+// to not require updates to the grpcio-tools C++ code part. Assumes that it is
+// only ever used from a single thread.
+struct PrivateGenerator {
+  const GeneratorConfiguration& config;
+  const FileDescriptor* file;
+
+  bool generate_in_pb2_grpc;
+
+  Printer* out;
+
+  PrivateGenerator(const GeneratorConfiguration& config,
+                   const FileDescriptor* file);
+
+  std::pair<bool, grpc::string> GetGrpcServices();
 
-bool GetModuleAndMessagePath(const Descriptor* type,
-                             const ServiceDescriptor* service,
-                             grpc::string* out) {
+ private:
+  bool PrintPreamble();
+  bool PrintBetaPreamble();
+  bool PrintGAServices();
+  bool PrintBetaServices();
+
+  bool PrintAddServicerToServer(
+      const grpc::string& package_qualified_service_name,
+      const ServiceDescriptor* service);
+  bool PrintServicer(const ServiceDescriptor* service);
+  bool PrintStub(const grpc::string& package_qualified_service_name,
+                 const ServiceDescriptor* service);
+
+  bool PrintBetaServicer(const ServiceDescriptor* service);
+  bool PrintBetaServerFactory(
+      const grpc::string& package_qualified_service_name,
+      const ServiceDescriptor* service);
+  bool PrintBetaStub(const ServiceDescriptor* service);
+  bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
+                            const ServiceDescriptor* service);
+
+  // Get all comments (leading, leading_detached, trailing) and print them as a
+  // docstring. Any leading space of a line will be removed, but the line
+  // wrapping will not be changed.
+  template <typename DescriptorType>
+  void PrintAllComments(const DescriptorType* descriptor);
+
+  bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out);
+};
+
+PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config,
+                                   const FileDescriptor* file)
+    : config(config), file(file) {}
+
+bool PrivateGenerator::GetModuleAndMessagePath(const Descriptor* type,
+                                               grpc::string* out) {
   const Descriptor* path_elem_type = type;
-  vector<const Descriptor*> message_path;
+  DescriptorVector message_path;
   do {
     message_path.push_back(path_elem_type);
     path_elem_type = path_elem_type->containing_type();
-  } while (path_elem_type); // implicit nullptr comparison; don't be explicit
+  } while (path_elem_type);  // implicit nullptr comparison; don't be explicit
   grpc::string file_name = type->file()->name();
   static const int proto_suffix_length = strlen(".proto");
   if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
         file_name.find_last_of(".proto") == file_name.size() - 1)) {
     return false;
   }
-  grpc::string service_file_name = service->file()->name();
-  grpc::string module = service_file_name == file_name ?
-          "" : ModuleAlias(file_name) + ".";
+  grpc::string generator_file_name = file->name();
+  grpc::string module;
+  if (generator_file_name != file_name || generate_in_pb2_grpc) {
+    module = ModuleAlias(file_name) + ".";
+  } else {
+    module = "";
+  }
   grpc::string message_type;
-  for (auto path_iter = message_path.rbegin();
+  for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin();
        path_iter != message_path.rend(); ++path_iter) {
     message_type += (*path_iter)->name() + ".";
   }
@@ -203,53 +199,53 @@ bool GetModuleAndMessagePath(const Descriptor* type,
   return true;
 }
 
-// Get all comments (leading, leading_detached, trailing) and print them as a
-// docstring. Any leading space of a line will be removed, but the line wrapping
-// will not be changed.
 template <typename DescriptorType>
-static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
-  std::vector<grpc::string> comments;
-  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
+void PrivateGenerator::PrintAllComments(const DescriptorType* descriptor) {
+  StringVector comments;
+  grpc_generator::GetComment(
+      descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments);
+  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING,
                              &comments);
-  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING,
-                             &comments);
-  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
+  grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING,
                              &comments);
   if (comments.empty()) {
     return;
   }
-  printer->Print("\"\"\"");
-  for (auto it = comments.begin(); it != comments.end(); ++it) {
+  out->Print("\"\"\"");
+  for (StringVector::iterator it = comments.begin(); it != comments.end();
+       ++it) {
     size_t start_pos = it->find_first_not_of(' ');
     if (start_pos != grpc::string::npos) {
-      printer->Print(it->c_str() + start_pos);
+      out->Print(it->c_str() + start_pos);
     }
-    printer->Print("\n");
+    out->Print("\n");
   }
-  printer->Print("\"\"\"\n");
+  out->Print("\"\"\"\n");
 }
 
-bool PrintBetaServicer(const ServiceDescriptor* service,
-                       Printer* out) {
+bool PrivateGenerator::PrintBetaServicer(const ServiceDescriptor* service) {
   out->Print("\n\n");
   out->Print("class Beta$Service$Servicer(object):\n", "Service",
              service->name());
   {
     IndentScope raii_class_indent(out);
-    out->Print("\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
-    "\nIt is recommended to use the GA API (classes and functions in this\n"
-    "file not marked beta) for all further purposes. This class was generated\n"
-     "only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.\"\"\"\n");
-    PrintAllComments(service, out);
+    out->Print(
+        "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+        "\nIt is recommended to use the GA API (classes and functions in this\n"
+        "file not marked beta) for all further purposes. This class was "
+        "generated\n"
+        "only to ease transition from grpcio<0.15.0 to "
+        "grpcio>=0.15.0.\"\"\"\n");
+    PrintAllComments(service);
     for (int i = 0; i < service->method_count(); ++i) {
-      auto meth = service->method(i);
-      grpc::string arg_name = meth->client_streaming() ?
-          "request_iterator" : "request";
-      out->Print("def $Method$(self, $ArgName$, context):\n",
-                 "Method", meth->name(), "ArgName", arg_name);
+      const MethodDescriptor* method = service->method(i);
+      grpc::string arg_name =
+          method->client_streaming() ? "request_iterator" : "request";
+      out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
+                 method->name(), "ArgName", arg_name);
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(meth, out);
+        PrintAllComments(method);
         out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
       }
     }
@@ -257,52 +253,61 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
   return true;
 }
 
-bool PrintBetaStub(const ServiceDescriptor* service,
-                   Printer* out) {
+bool PrivateGenerator::PrintBetaStub(const ServiceDescriptor* service) {
   out->Print("\n\n");
   out->Print("class Beta$Service$Stub(object):\n", "Service", service->name());
   {
     IndentScope raii_class_indent(out);
-    out->Print("\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
-    "\nIt is recommended to use the GA API (classes and functions in this\n"
-    "file not marked beta) for all further purposes. This class was generated\n"
-     "only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.\"\"\"\n");
-    PrintAllComments(service, out);
+    out->Print(
+        "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+        "\nIt is recommended to use the GA API (classes and functions in this\n"
+        "file not marked beta) for all further purposes. This class was "
+        "generated\n"
+        "only to ease transition from grpcio<0.15.0 to "
+        "grpcio>=0.15.0.\"\"\"\n");
+    PrintAllComments(service);
     for (int i = 0; i < service->method_count(); ++i) {
-      const MethodDescriptor* meth = service->method(i);
-      grpc::string arg_name = meth->client_streaming() ?
-          "request_iterator" : "request";
-      auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
-      out->Print(methdict, "def $Method$(self, $ArgName$, timeout, metadata=None, with_call=False, protocol_options=None):\n");
+      const MethodDescriptor* method = service->method(i);
+      grpc::string arg_name =
+          method->client_streaming() ? "request_iterator" : "request";
+      StringMap method_dict;
+      method_dict["Method"] = method->name();
+      method_dict["ArgName"] = arg_name;
+      out->Print(method_dict,
+                 "def $Method$(self, $ArgName$, timeout, metadata=None, "
+                 "with_call=False, protocol_options=None):\n");
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(meth, out);
+        PrintAllComments(method);
         out->Print("raise NotImplementedError()\n");
       }
-      if (!meth->server_streaming()) {
-        out->Print(methdict, "$Method$.future = None\n");
+      if (!method->server_streaming()) {
+        out->Print(method_dict, "$Method$.future = None\n");
       }
     }
   }
   return true;
 }
 
-bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
-                            const ServiceDescriptor* service, Printer* out) {
+bool PrivateGenerator::PrintBetaServerFactory(
+    const grpc::string& package_qualified_service_name,
+    const ServiceDescriptor* service) {
   out->Print("\n\n");
-  out->Print("def beta_create_$Service$_server(servicer, pool=None, "
-             "pool_size=None, default_timeout=None, maximum_timeout=None):\n",
-             "Service", service->name());
+  out->Print(
+      "def beta_create_$Service$_server(servicer, pool=None, "
+      "pool_size=None, default_timeout=None, maximum_timeout=None):\n",
+      "Service", service->name());
   {
     IndentScope raii_create_server_indent(out);
-    out->Print("\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
-    "\nIt is recommended to use the GA API (classes and functions in this\n"
-    "file not marked beta) for all further purposes. This function was\n"
-    "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
-    "\"\"\"\n");
-    map<grpc::string, grpc::string> method_implementation_constructors;
-    map<grpc::string, grpc::string> input_message_modules_and_classes;
-    map<grpc::string, grpc::string> output_message_modules_and_classes;
+    out->Print(
+        "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+        "\nIt is recommended to use the GA API (classes and functions in this\n"
+        "file not marked beta) for all further purposes. This function was\n"
+        "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
+        "\"\"\"\n");
+    StringMap method_implementation_constructors;
+    StringMap input_message_modules_and_classes;
+    StringMap output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
       const MethodDescriptor* method = service->method(i);
       const grpc::string method_implementation_constructor =
@@ -310,12 +315,12 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
           grpc::string(method->server_streaming() ? "stream_" : "unary_") +
           "inline";
       grpc::string input_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->input_type(), service,
+      if (!GetModuleAndMessagePath(method->input_type(),
                                    &input_message_module_and_class)) {
         return false;
       }
       grpc::string output_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->output_type(), service,
+      if (!GetModuleAndMessagePath(method->output_type(),
                                    &output_message_module_and_class)) {
         return false;
       }
@@ -327,94 +332,99 @@ bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
           make_pair(method->name(), output_message_module_and_class));
     }
     out->Print("request_deserializers = {\n");
-    for (auto name_and_input_module_class_pair =
-           input_message_modules_and_classes.begin();
+    for (StringMap::iterator name_and_input_module_class_pair =
+             input_message_modules_and_classes.begin();
          name_and_input_module_class_pair !=
-           input_message_modules_and_classes.end();
+         input_message_modules_and_classes.end();
          name_and_input_module_class_pair++) {
       IndentScope raii_indent(out);
-      out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-                 "$InputTypeModuleAndClass$.FromString,\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name,
-                 "MethodName", name_and_input_module_class_pair->first,
-                 "InputTypeModuleAndClass",
-                 name_and_input_module_class_pair->second);
+      out->Print(
+          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+          "$InputTypeModuleAndClass$.FromString,\n",
+          "PackageQualifiedServiceName", package_qualified_service_name,
+          "MethodName", name_and_input_module_class_pair->first,
+          "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
     }
     out->Print("}\n");
     out->Print("response_serializers = {\n");
-    for (auto name_and_output_module_class_pair =
-           output_message_modules_and_classes.begin();
+    for (StringMap::iterator name_and_output_module_class_pair =
+             output_message_modules_and_classes.begin();
          name_and_output_module_class_pair !=
-           output_message_modules_and_classes.end();
+         output_message_modules_and_classes.end();
          name_and_output_module_class_pair++) {
       IndentScope raii_indent(out);
-      out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-                 "$OutputTypeModuleAndClass$.SerializeToString,\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name,
-                 "MethodName", name_and_output_module_class_pair->first,
-                 "OutputTypeModuleAndClass",
-                 name_and_output_module_class_pair->second);
+      out->Print(
+          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+          "$OutputTypeModuleAndClass$.SerializeToString,\n",
+          "PackageQualifiedServiceName", package_qualified_service_name,
+          "MethodName", name_and_output_module_class_pair->first,
+          "OutputTypeModuleAndClass",
+          name_and_output_module_class_pair->second);
     }
     out->Print("}\n");
     out->Print("method_implementations = {\n");
-    for (auto name_and_implementation_constructor =
-           method_implementation_constructors.begin();
-	 name_and_implementation_constructor !=
-	   method_implementation_constructors.end();
-	 name_and_implementation_constructor++) {
+    for (StringMap::iterator name_and_implementation_constructor =
+             method_implementation_constructors.begin();
+         name_and_implementation_constructor !=
+         method_implementation_constructors.end();
+         name_and_implementation_constructor++) {
       IndentScope raii_descriptions_indent(out);
       const grpc::string method_name =
           name_and_implementation_constructor->first;
-      out->Print("(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
-                 "face_utilities.$Constructor$(servicer.$Method$),\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name,
-                 "Method", name_and_implementation_constructor->first,
-                 "Constructor", name_and_implementation_constructor->second);
+      out->Print(
+          "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
+          "face_utilities.$Constructor$(servicer.$Method$),\n",
+          "PackageQualifiedServiceName", package_qualified_service_name,
+          "Method", name_and_implementation_constructor->first, "Constructor",
+          name_and_implementation_constructor->second);
     }
     out->Print("}\n");
-    out->Print("server_options = beta_implementations.server_options("
-               "request_deserializers=request_deserializers, "
-               "response_serializers=response_serializers, "
-               "thread_pool=pool, thread_pool_size=pool_size, "
-               "default_timeout=default_timeout, "
-               "maximum_timeout=maximum_timeout)\n");
-    out->Print("return beta_implementations.server(method_implementations, "
-               "options=server_options)\n");
+    out->Print(
+        "server_options = beta_implementations.server_options("
+        "request_deserializers=request_deserializers, "
+        "response_serializers=response_serializers, "
+        "thread_pool=pool, thread_pool_size=pool_size, "
+        "default_timeout=default_timeout, "
+        "maximum_timeout=maximum_timeout)\n");
+    out->Print(
+        "return beta_implementations.server(method_implementations, "
+        "options=server_options)\n");
   }
   return true;
 }
 
-bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
-                          const ServiceDescriptor* service, Printer* out) {
-  map<grpc::string, grpc::string> dict = ListToDict({
-        "Service", service->name(),
-      });
+bool PrivateGenerator::PrintBetaStubFactory(
+    const grpc::string& package_qualified_service_name,
+    const ServiceDescriptor* service) {
+  StringMap dict;
+  dict["Service"] = service->name();
   out->Print("\n\n");
-  out->Print(dict, "def beta_create_$Service$_stub(channel, host=None,"
+  out->Print(dict,
+             "def beta_create_$Service$_stub(channel, host=None,"
              " metadata_transformer=None, pool=None, pool_size=None):\n");
   {
     IndentScope raii_create_server_indent(out);
-    out->Print("\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
-    "\nIt is recommended to use the GA API (classes and functions in this\n"
-    "file not marked beta) for all further purposes. This function was\n"
-    "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
-    "\"\"\"\n");
-    map<grpc::string, grpc::string> method_cardinalities;
-    map<grpc::string, grpc::string> input_message_modules_and_classes;
-    map<grpc::string, grpc::string> output_message_modules_and_classes;
+    out->Print(
+        "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+        "\nIt is recommended to use the GA API (classes and functions in this\n"
+        "file not marked beta) for all further purposes. This function was\n"
+        "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
+        "\"\"\"\n");
+    StringMap method_cardinalities;
+    StringMap input_message_modules_and_classes;
+    StringMap output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
       const MethodDescriptor* method = service->method(i);
       const grpc::string method_cardinality =
-          grpc::string(method->client_streaming() ? "STREAM" : "UNARY") +
-          "_" +
+          grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + "_" +
           grpc::string(method->server_streaming() ? "STREAM" : "UNARY");
       grpc::string input_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->input_type(), service,
+      if (!GetModuleAndMessagePath(method->input_type(),
                                    &input_message_module_and_class)) {
         return false;
       }
       grpc::string output_message_module_and_class;
-      if (!GetModuleAndMessagePath(method->output_type(), service,
+      if (!GetModuleAndMessagePath(method->output_type(),
                                    &output_message_module_and_class)) {
         return false;
       }
@@ -426,65 +436,70 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
           make_pair(method->name(), output_message_module_and_class));
     }
     out->Print("request_serializers = {\n");
-    for (auto name_and_input_module_class_pair =
-           input_message_modules_and_classes.begin();
+    for (StringMap::iterator name_and_input_module_class_pair =
+             input_message_modules_and_classes.begin();
          name_and_input_module_class_pair !=
-           input_message_modules_and_classes.end();
+         input_message_modules_and_classes.end();
          name_and_input_module_class_pair++) {
       IndentScope raii_indent(out);
-      out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-                 "$InputTypeModuleAndClass$.SerializeToString,\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name,
-                 "MethodName", name_and_input_module_class_pair->first,
-                 "InputTypeModuleAndClass",
-                 name_and_input_module_class_pair->second);
+      out->Print(
+          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+          "$InputTypeModuleAndClass$.SerializeToString,\n",
+          "PackageQualifiedServiceName", package_qualified_service_name,
+          "MethodName", name_and_input_module_class_pair->first,
+          "InputTypeModuleAndClass", name_and_input_module_class_pair->second);
     }
     out->Print("}\n");
     out->Print("response_deserializers = {\n");
-    for (auto name_and_output_module_class_pair =
-           output_message_modules_and_classes.begin();
+    for (StringMap::iterator name_and_output_module_class_pair =
+             output_message_modules_and_classes.begin();
          name_and_output_module_class_pair !=
-           output_message_modules_and_classes.end();
+         output_message_modules_and_classes.end();
          name_and_output_module_class_pair++) {
       IndentScope raii_indent(out);
-      out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
-                 "$OutputTypeModuleAndClass$.FromString,\n",
-                 "PackageQualifiedServiceName", package_qualified_service_name,
-                 "MethodName", name_and_output_module_class_pair->first,
-                 "OutputTypeModuleAndClass",
-                 name_and_output_module_class_pair->second);
+      out->Print(
+          "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+          "$OutputTypeModuleAndClass$.FromString,\n",
+          "PackageQualifiedServiceName", package_qualified_service_name,
+          "MethodName", name_and_output_module_class_pair->first,
+          "OutputTypeModuleAndClass",
+          name_and_output_module_class_pair->second);
     }
     out->Print("}\n");
     out->Print("cardinalities = {\n");
-    for (auto name_and_cardinality = method_cardinalities.begin();
+    for (StringMap::iterator name_and_cardinality =
+             method_cardinalities.begin();
          name_and_cardinality != method_cardinalities.end();
          name_and_cardinality++) {
       IndentScope raii_descriptions_indent(out);
       out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n",
-                 "Method", name_and_cardinality->first,
-                 "Cardinality", name_and_cardinality->second);
+                 "Method", name_and_cardinality->first, "Cardinality",
+                 name_and_cardinality->second);
     }
     out->Print("}\n");
-    out->Print("stub_options = beta_implementations.stub_options("
-               "host=host, metadata_transformer=metadata_transformer, "
-               "request_serializers=request_serializers, "
-               "response_deserializers=response_deserializers, "
-               "thread_pool=pool, thread_pool_size=pool_size)\n");
     out->Print(
-        "return beta_implementations.dynamic_stub(channel, \'$PackageQualifiedServiceName$\', "
+        "stub_options = beta_implementations.stub_options("
+        "host=host, metadata_transformer=metadata_transformer, "
+        "request_serializers=request_serializers, "
+        "response_deserializers=response_deserializers, "
+        "thread_pool=pool, thread_pool_size=pool_size)\n");
+    out->Print(
+        "return beta_implementations.dynamic_stub(channel, "
+        "\'$PackageQualifiedServiceName$\', "
         "cardinalities, options=stub_options)\n",
         "PackageQualifiedServiceName", package_qualified_service_name);
   }
   return true;
 }
 
-bool PrintStub(const grpc::string& package_qualified_service_name,
-               const ServiceDescriptor* service, Printer* out) {
+bool PrivateGenerator::PrintStub(
+    const grpc::string& package_qualified_service_name,
+    const ServiceDescriptor* service) {
   out->Print("\n\n");
   out->Print("class $Service$Stub(object):\n", "Service", service->name());
   {
     IndentScope raii_class_indent(out);
-    PrintAllComments(service, out);
+    PrintAllComments(service);
     out->Print("\n");
     out->Print("def __init__(self, channel):\n");
     {
@@ -494,65 +509,63 @@ bool PrintStub(const grpc::string& package_qualified_service_name,
       out->Print("Args:\n");
       {
         IndentScope raii_args_indent(out);
-	out->Print("channel: A grpc.Channel.\n");
+        out->Print("channel: A grpc.Channel.\n");
       }
       out->Print("\"\"\"\n");
       for (int i = 0; i < service->method_count(); ++i) {
-        auto method = service->method(i);
-	auto multi_callable_constructor =
-	    grpc::string(method->client_streaming() ? "stream" : "unary") +
-	    "_" +
-	    grpc::string(method->server_streaming() ? "stream" : "unary");
-	grpc::string request_module_and_class;
-	if (!GetModuleAndMessagePath(method->input_type(), service,
-				     &request_module_and_class)) {
-	  return false;
-	}
-	grpc::string response_module_and_class;
-	if (!GetModuleAndMessagePath(method->output_type(), service,
-				     &response_module_and_class)) {
+        const MethodDescriptor* method = service->method(i);
+        grpc::string multi_callable_constructor =
+            grpc::string(method->client_streaming() ? "stream" : "unary") +
+            "_" + grpc::string(method->server_streaming() ? "stream" : "unary");
+        grpc::string request_module_and_class;
+        if (!GetModuleAndMessagePath(method->input_type(),
+                                     &request_module_and_class)) {
+          return false;
+        }
+        grpc::string response_module_and_class;
+        if (!GetModuleAndMessagePath(method->output_type(),
+                                     &response_module_and_class)) {
           return false;
-	}
-	out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n",
-		   "Method", method->name(),
-		   "MultiCallableConstructor", multi_callable_constructor);
-	{
+        }
+        out->Print("self.$Method$ = channel.$MultiCallableConstructor$(\n",
+                   "Method", method->name(), "MultiCallableConstructor",
+                   multi_callable_constructor);
+        {
           IndentScope raii_first_attribute_indent(out);
           IndentScope raii_second_attribute_indent(out);
-	  out->Print(
-	      "'/$PackageQualifiedService$/$Method$',\n",
-	      "PackageQualifiedService", package_qualified_service_name,
-	      "Method", method->name());
-	  out->Print(
-	      "request_serializer=$RequestModuleAndClass$.SerializeToString,\n",
-	      "RequestModuleAndClass", request_module_and_class);
-	  out->Print(
+          out->Print("'/$PackageQualifiedService$/$Method$',\n",
+                     "PackageQualifiedService", package_qualified_service_name,
+                     "Method", method->name());
+          out->Print(
+              "request_serializer=$RequestModuleAndClass$.SerializeToString,\n",
+              "RequestModuleAndClass", request_module_and_class);
+          out->Print(
               "response_deserializer=$ResponseModuleAndClass$.FromString,\n",
-	      "ResponseModuleAndClass", response_module_and_class);
-	  out->Print(")\n");
-	}
+              "ResponseModuleAndClass", response_module_and_class);
+          out->Print(")\n");
+        }
       }
     }
   }
   return true;
 }
 
-bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
+bool PrivateGenerator::PrintServicer(const ServiceDescriptor* service) {
   out->Print("\n\n");
   out->Print("class $Service$Servicer(object):\n", "Service", service->name());
   {
     IndentScope raii_class_indent(out);
-    PrintAllComments(service, out);
+    PrintAllComments(service);
     for (int i = 0; i < service->method_count(); ++i) {
-      auto method = service->method(i);
-      grpc::string arg_name = method->client_streaming() ?
-	  "request_iterator" : "request";
+      const MethodDescriptor* method = service->method(i);
+      grpc::string arg_name =
+          method->client_streaming() ? "request_iterator" : "request";
       out->Print("\n");
-      out->Print("def $Method$(self, $ArgName$, context):\n",
-                 "Method", method->name(), "ArgName", arg_name);
+      out->Print("def $Method$(self, $ArgName$, context):\n", "Method",
+                 method->name(), "ArgName", arg_name);
       {
         IndentScope raii_method_indent(out);
-        PrintAllComments(method, out);
+        PrintAllComments(method);
         out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
         out->Print("context.set_details('Method not implemented!')\n");
         out->Print("raise NotImplementedError('Method not implemented!')\n");
@@ -562,11 +575,12 @@ bool PrintServicer(const ServiceDescriptor* service, Printer* out) {
   return true;
 }
 
-bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name,
-			      const ServiceDescriptor* service, Printer* out) {
+bool PrivateGenerator::PrintAddServicerToServer(
+    const grpc::string& package_qualified_service_name,
+    const ServiceDescriptor* service) {
   out->Print("\n\n");
   out->Print("def add_$Service$Servicer_to_server(servicer, server):\n",
-	     "Service", service->name());
+             "Service", service->name());
   {
     IndentScope raii_class_indent(out);
     out->Print("rpc_method_handlers = {\n");
@@ -574,35 +588,38 @@ bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name
       IndentScope raii_dict_first_indent(out);
       IndentScope raii_dict_second_indent(out);
       for (int i = 0; i < service->method_count(); ++i) {
-        auto method = service->method(i);
-	auto method_handler_constructor =
+        const MethodDescriptor* method = service->method(i);
+        grpc::string method_handler_constructor =
             grpc::string(method->client_streaming() ? "stream" : "unary") +
-	    "_" +
+            "_" +
             grpc::string(method->server_streaming() ? "stream" : "unary") +
             "_rpc_method_handler";
-	grpc::string request_module_and_class;
-	if (!GetModuleAndMessagePath(method->input_type(), service,
-				     &request_module_and_class)) {
-	  return false;
-	}
-	grpc::string response_module_and_class;
-	if (!GetModuleAndMessagePath(method->output_type(), service,
-				     &response_module_and_class)) {
+        grpc::string request_module_and_class;
+        if (!GetModuleAndMessagePath(method->input_type(),
+                                     &request_module_and_class)) {
           return false;
-	}
-        out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n",
-		   "Method", method->name(),
-		   "MethodHandlerConstructor", method_handler_constructor);
-	{
+        }
+        grpc::string response_module_and_class;
+        if (!GetModuleAndMessagePath(method->output_type(),
+                                     &response_module_and_class)) {
+          return false;
+        }
+        out->Print("'$Method$': grpc.$MethodHandlerConstructor$(\n", "Method",
+                   method->name(), "MethodHandlerConstructor",
+                   method_handler_constructor);
+        {
           IndentScope raii_call_first_indent(out);
-	  IndentScope raii_call_second_indent(out);
-	  out->Print("servicer.$Method$,\n", "Method", method->name());
-	  out->Print("request_deserializer=$RequestModuleAndClass$.FromString,\n",
-		     "RequestModuleAndClass", request_module_and_class);
-	  out->Print("response_serializer=$ResponseModuleAndClass$.SerializeToString,\n",
-		     "ResponseModuleAndClass", response_module_and_class);
-	}
-	out->Print("),\n");
+          IndentScope raii_call_second_indent(out);
+          out->Print("servicer.$Method$,\n", "Method", method->name());
+          out->Print(
+              "request_deserializer=$RequestModuleAndClass$.FromString,\n",
+              "RequestModuleAndClass", request_module_and_class);
+          out->Print(
+              "response_serializer=$ResponseModuleAndClass$.SerializeToString,"
+              "\n",
+              "ResponseModuleAndClass", response_module_and_class);
+        }
+        out->Print("),\n");
       }
     }
     out->Print("}\n");
@@ -611,56 +628,193 @@ bool PrintAddServicerToServer(const grpc::string& package_qualified_service_name
       IndentScope raii_call_first_indent(out);
       IndentScope raii_call_second_indent(out);
       out->Print("'$PackageQualifiedServiceName$', rpc_method_handlers)\n",
-		 "PackageQualifiedServiceName", package_qualified_service_name);
+                 "PackageQualifiedServiceName", package_qualified_service_name);
     }
     out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
   }
   return true;
 }
 
-bool PrintPreamble(const FileDescriptor* file,
-                   const GeneratorConfiguration& config, Printer* out) {
-  out->Print("import $Package$\n", "Package", config.grpc_package_root);
+bool PrivateGenerator::PrintBetaPreamble() {
   out->Print("from $Package$ import implementations as beta_implementations\n",
              "Package", config.beta_package_root);
-  out->Print("from $Package$ import interfaces as beta_interfaces\n",
-             "Package", config.beta_package_root);
+  out->Print("from $Package$ import interfaces as beta_interfaces\n", "Package",
+             config.beta_package_root);
+  return true;
+}
+
+bool PrivateGenerator::PrintPreamble() {
+  out->Print("import $Package$\n", "Package", config.grpc_package_root);
   out->Print("from grpc.framework.common import cardinality\n");
-  out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n");
+  out->Print(
+      "from grpc.framework.interfaces.face import utilities as "
+      "face_utilities\n");
+  if (generate_in_pb2_grpc) {
+    out->Print("\n");
+    for (int i = 0; i < file->service_count(); ++i) {
+      const ServiceDescriptor* service = file->service(i);
+      for (int j = 0; j < service->method_count(); ++j) {
+        const MethodDescriptor* method = service->method(j);
+        const Descriptor* types[2] = {method->input_type(),
+                                      method->output_type()};
+        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);
+          out->Print("import $ModuleName$ as $ModuleAlias$\n", "ModuleName",
+                     module_name, "ModuleAlias", module_alias);
+        }
+      }
+    }
+  }
   return true;
 }
 
-}  // namespace
+bool PrivateGenerator::PrintGAServices() {
+  grpc::string package = file->package();
+  if (!package.empty()) {
+    package = package.append(".");
+  }
+  for (int i = 0; i < file->service_count(); ++i) {
+    const ServiceDescriptor* service = file->service(i);
+    grpc::string package_qualified_service_name = package + service->name();
+    if (!(PrintStub(package_qualified_service_name, service) &&
+          PrintServicer(service) &&
+          PrintAddServicerToServer(package_qualified_service_name, service))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool PrivateGenerator::PrintBetaServices() {
+  grpc::string package = file->package();
+  if (!package.empty()) {
+    package = package.append(".");
+  }
+  for (int i = 0; i < file->service_count(); ++i) {
+    const ServiceDescriptor* service = file->service(i);
+    grpc::string package_qualified_service_name = package + service->name();
+    if (!(PrintBetaServicer(service) && PrintBetaStub(service) &&
+          PrintBetaServerFactory(package_qualified_service_name, service) &&
+          PrintBetaStubFactory(package_qualified_service_name, service))) {
+      return false;
+    }
+  }
+  return true;
+}
 
-pair<bool, grpc::string> GetServices(const FileDescriptor* file,
-                                     const GeneratorConfiguration& config) {
+pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
   grpc::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
     StringOutputStream output_stream(&output);
-    Printer out(&output_stream, '$');
-    if (!PrintPreamble(file, config, &out)) {
-      return make_pair(false, "");
-    }
-    auto package = file->package();
-    if (!package.empty()) {
-      package = package.append(".");
-    }
-    for (int i = 0; i < file->service_count(); ++i) {
-      auto service = file->service(i);
-      auto package_qualified_service_name = package + service->name();
-      if (!(PrintStub(package_qualified_service_name, service, &out) &&
-	    PrintServicer(service, &out) &&
-	    PrintAddServicerToServer(package_qualified_service_name, service, &out) &&
-	    PrintBetaServicer(service, &out) &&
-            PrintBetaStub(service, &out) &&
-            PrintBetaServerFactory(package_qualified_service_name, service, &out) &&
-            PrintBetaStubFactory(package_qualified_service_name, service, &out))) {
+    Printer out_printer(&output_stream, '$');
+    out = &out_printer;
+
+    if (generate_in_pb2_grpc) {
+      if (!PrintPreamble()) {
+        return make_pair(false, "");
+      }
+      if (!PrintGAServices()) {
         return make_pair(false, "");
       }
+    } else {
+      out->Print("try:\n");
+      {
+        IndentScope raii_dict_try_indent(out);
+        out->Print(
+            "# THESE ELEMENTS WILL BE DEPRECATED.\n"
+            "# Please use the generated *_pb2_grpc.py files instead.\n");
+        if (!PrintPreamble()) {
+          return make_pair(false, "");
+        }
+        if (!PrintBetaPreamble()) {
+          return make_pair(false, "");
+        }
+        if (!PrintGAServices()) {
+          return make_pair(false, "");
+        }
+        if (!PrintBetaServices()) {
+          return make_pair(false, "");
+        }
+      }
+      out->Print("except ImportError:\n");
+      {
+        IndentScope raii_dict_except_indent(out);
+        out->Print("pass");
+      }
     }
   }
   return make_pair(true, std::move(output));
 }
 
+}  // namespace
+
+GeneratorConfiguration::GeneratorConfiguration()
+    : grpc_package_root("grpc"), beta_package_root("grpc.beta") {}
+
+PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
+    : config_(config) {}
+
+PythonGrpcGenerator::~PythonGrpcGenerator() {}
+
+static bool GenerateGrpc(GeneratorContext* context, PrivateGenerator& generator,
+                         grpc::string file_name, bool generate_in_pb2_grpc) {
+  bool success;
+  std::unique_ptr<ZeroCopyOutputStream> output;
+  std::unique_ptr<CodedOutputStream> coded_output;
+  grpc::string grpc_code;
+
+  if (generate_in_pb2_grpc) {
+    output.reset(context->Open(file_name));
+    generator.generate_in_pb2_grpc = true;
+  } else {
+    output.reset(context->OpenForInsert(file_name, "module_scope"));
+    generator.generate_in_pb2_grpc = false;
+  }
+
+  coded_output.reset(new CodedOutputStream(output.get()));
+  tie(success, grpc_code) = generator.GetGrpcServices();
+
+  if (success) {
+    coded_output->WriteRaw(grpc_code.data(), grpc_code.size());
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
+                                   const grpc::string& parameter,
+                                   GeneratorContext* context,
+                                   grpc::string* error) const {
+  // Get output file name.
+  grpc::string pb2_file_name;
+  grpc::string pb2_grpc_file_name;
+  static const int proto_suffix_length = strlen(".proto");
+  if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
+      file->name().find_last_of(".proto") == file->name().size() - 1) {
+    grpc::string base =
+        file->name().substr(0, file->name().size() - proto_suffix_length);
+    pb2_file_name = base + "_pb2.py";
+    pb2_grpc_file_name = base + "_pb2_grpc.py";
+  } else {
+    *error = "Invalid proto file name. Proto file must end with .proto";
+    return false;
+  }
+
+  PrivateGenerator generator(config_, file);
+  if (parameter == "grpc_2_0") {
+    return GenerateGrpc(context, generator, pb2_grpc_file_name, true);
+  } else if (parameter == "") {
+    return GenerateGrpc(context, generator, pb2_grpc_file_name, true) &&
+           GenerateGrpc(context, generator, pb2_file_name, false);
+  } else {
+    *error = "Invalid parameter '" + parameter + "'.";
+    return false;
+  }
+}
+
 }  // namespace grpc_python_generator
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index 7ed99eff0b..6a95255d40 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -57,14 +57,11 @@ class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
                 const grpc::string& parameter,
                 grpc::protobuf::compiler::GeneratorContext* context,
                 grpc::string* error) const;
+
  private:
   GeneratorConfiguration config_;
 };
 
-std::pair<bool, grpc::string> GetServices(
-    const grpc::protobuf::FileDescriptor* file,
-    const GeneratorConfiguration& config);
-
 }  // namespace grpc_python_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index ba60986143..cc3bd7a067 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -34,6 +34,7 @@ cdef class Call:
 
   def __cinit__(self):
     # Create an *empty* call
+    grpc_init()
     self.c_call = NULL
     self.references = []
 
@@ -106,6 +107,7 @@ cdef class Call:
   def __dealloc__(self):
     if self.c_call != NULL:
       grpc_call_destroy(self.c_call)
+    grpc_shutdown()
 
   # The object *should* always be valid from Python. Used for debugging.
   @property
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index 5416401431..3df937eb14 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -34,6 +34,7 @@ cdef class Channel:
 
   def __cinit__(self, bytes target, ChannelArgs arguments=None,
                 ChannelCredentials channel_credentials=None):
+    grpc_init()
     cdef grpc_channel_args *c_arguments = NULL
     cdef char *c_target = NULL
     self.c_channel = NULL
@@ -103,3 +104,4 @@ cdef class Channel:
   def __dealloc__(self):
     if self.c_channel != NULL:
       grpc_channel_destroy(self.c_channel)
+    grpc_shutdown()
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index 5955021ceb..a258ba4063 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -38,6 +38,7 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200
 cdef class CompletionQueue:
 
   def __cinit__(self):
+    grpc_init()
     with nogil:
       self.c_completion_queue = grpc_completion_queue_create(NULL)
     self.is_shutting_down = False
@@ -129,3 +130,4 @@ cdef class CompletionQueue:
             self.c_completion_queue, c_deadline, NULL)
         self._interpret_event(event)
       grpc_completion_queue_destroy(self.c_completion_queue)
+    grpc_shutdown()
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 035ac49a8b..04872b9c09 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -33,6 +33,7 @@ cimport cpython
 cdef class ChannelCredentials:
 
   def __cinit__(self):
+    grpc_init()
     self.c_credentials = NULL
     self.c_ssl_pem_key_cert_pair.private_key = NULL
     self.c_ssl_pem_key_cert_pair.certificate_chain = NULL
@@ -47,11 +48,13 @@ cdef class ChannelCredentials:
   def __dealloc__(self):
     if self.c_credentials != NULL:
       grpc_channel_credentials_release(self.c_credentials)
+    grpc_shutdown()
 
 
 cdef class CallCredentials:
 
   def __cinit__(self):
+    grpc_init()
     self.c_credentials = NULL
     self.references = []
 
@@ -64,17 +67,20 @@ cdef class CallCredentials:
   def __dealloc__(self):
     if self.c_credentials != NULL:
       grpc_call_credentials_release(self.c_credentials)
+    grpc_shutdown()
 
 
 cdef class ServerCredentials:
 
   def __cinit__(self):
+    grpc_init()
     self.c_credentials = NULL
     self.references = []
 
   def __dealloc__(self):
     if self.c_credentials != NULL:
       grpc_server_credentials_release(self.c_credentials)
+    grpc_shutdown()
 
 
 cdef class CredentialsMetadataPlugin:
@@ -90,6 +96,7 @@ cdef class CredentialsMetadataPlugin:
         successful).
       name (bytes): Plugin name.
     """
+    grpc_init()
     if not callable(plugin_callback):
       raise ValueError('expected callable plugin_callback')
     self.plugin_callback = plugin_callback
@@ -105,10 +112,14 @@ cdef class CredentialsMetadataPlugin:
     cpython.Py_INCREF(self)
     return result
 
+  def __dealloc__(self):
+    grpc_shutdown()
+
 
 cdef class AuthMetadataContext:
 
   def __cinit__(self):
+    grpc_init()
     self.context.service_url = NULL
     self.context.method_name = NULL
 
@@ -120,6 +131,9 @@ cdef class AuthMetadataContext:
   def method_name(self):
     return self.context.method_name
 
+  def __dealloc__(self):
+    grpc_shutdown()
+
 
 cdef void plugin_get_metadata(
     void *state, grpc_auth_metadata_context context,
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index 54b3d00dfc..834a44123d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -176,12 +176,14 @@ cdef class Timespec:
 cdef class CallDetails:
 
   def __cinit__(self):
+    grpc_init()
     with nogil:
       grpc_call_details_init(&self.c_details)
 
   def __dealloc__(self):
     with nogil:
       grpc_call_details_destroy(&self.c_details)
+    grpc_shutdown()
 
   @property
   def method(self):
@@ -232,6 +234,7 @@ cdef class Event:
 cdef class ByteBuffer:
 
   def __cinit__(self, bytes data):
+    grpc_init()
     if data is None:
       self.c_byte_buffer = NULL
       return
@@ -288,6 +291,7 @@ cdef class ByteBuffer:
   def __dealloc__(self):
     if self.c_byte_buffer != NULL:
       grpc_byte_buffer_destroy(self.c_byte_buffer)
+    grpc_shutdown()
 
 
 cdef class SslPemKeyCertPair:
@@ -319,6 +323,7 @@ cdef class ChannelArg:
 cdef class ChannelArgs:
 
   def __cinit__(self, args):
+    grpc_init()
     self.args = list(args)
     for arg in self.args:
       if not isinstance(arg, ChannelArg):
@@ -333,6 +338,7 @@ cdef class ChannelArgs:
   def __dealloc__(self):
     with nogil:
       gpr_free(self.c_args.arguments)
+    grpc_shutdown()
 
   def __len__(self):
     # self.args is never stale; it's only updated from this file
@@ -399,6 +405,7 @@ cdef class _MetadataIterator:
 cdef class Metadata:
 
   def __cinit__(self, metadata):
+    grpc_init()
     self.metadata = list(metadata)
     for metadatum in metadata:
       if not isinstance(metadatum, Metadatum):
@@ -420,6 +427,7 @@ cdef class Metadata:
     # it'd be nice if that were documented somewhere...)
     # TODO(atash): document this in the C core
     grpc_metadata_array_destroy(&self.c_metadata_array)
+    grpc_shutdown()
 
   def __len__(self):
     return self.c_metadata_array.count
@@ -437,6 +445,7 @@ cdef class Metadata:
 cdef class Operation:
 
   def __cinit__(self):
+    grpc_init()
     self.references = []
     self._received_status_details = NULL
     self._received_status_details_capacity = 0
@@ -529,6 +538,7 @@ cdef class Operation:
     # This means that we need to clean up after receive_status_on_client.
     if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT:
       gpr_free(self._received_status_details)
+    grpc_shutdown()
 
 def operation_send_initial_metadata(Metadata metadata, int flags):
   cdef Operation op = Operation()
@@ -645,6 +655,7 @@ cdef class _OperationsIterator:
 cdef class Operations:
 
   def __cinit__(self, operations):
+    grpc_init()
     self.operations = list(operations)  # normalize iterable
     self.c_ops = NULL
     self.c_nops = 0
@@ -667,6 +678,7 @@ cdef class Operations:
   def __dealloc__(self):
     with nogil:
       gpr_free(self.c_ops)
+    grpc_shutdown()
 
   def __iter__(self):
     return _OperationsIterator(self)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 4f2d51b03f..ca2b831114 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -35,6 +35,7 @@ import time
 cdef class Server:
 
   def __cinit__(self, ChannelArgs arguments=None):
+    grpc_init()
     cdef grpc_channel_args *c_arguments = NULL
     self.references = []
     self.registered_completion_queues = []
@@ -172,3 +173,4 @@ cdef class Server:
         while not self.is_shutdown:
           time.sleep(0)
       grpc_server_destroy(self.c_server)
+    grpc_shutdown()
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index a9520b9c0f..08089994a9 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -55,12 +55,8 @@ cdef extern from "Python.h":
 
 
 def _initialize():
-  grpc_init()
   grpc_set_ssl_roots_override_callback(
           <grpc_ssl_roots_override_callback>ssl_roots_override_callback)
 
-  if Py_AtExit(grpc_shutdown) != 0:
-    raise ImportError('failed to register gRPC library shutdown callbacks')
-
 
 _initialize()
diff --git a/src/python/grpcio_health_checking/.gitignore b/src/python/grpcio_health_checking/.gitignore
index 85af466886..432c3194f0 100644
--- a/src/python/grpcio_health_checking/.gitignore
+++ b/src/python/grpcio_health_checking/.gitignore
@@ -1,5 +1,6 @@
 *.proto
 *_pb2.py
+*_pb2_grpc.py
 build/
 grpcio_health_checking.egg-info/
 dist/
diff --git a/src/python/grpcio_tests/.gitignore b/src/python/grpcio_tests/.gitignore
index fc620135dc..dcba283a8c 100644
--- a/src/python/grpcio_tests/.gitignore
+++ b/src/python/grpcio_tests/.gitignore
@@ -1,4 +1,5 @@
 proto/
 src/
 *_pb2.py
+*_pb2_grpc.py
 *.egg-info/
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
new file mode 100644
index 0000000000..64fd97256e
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
@@ -0,0 +1,304 @@
+# Copyright 2016, 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.
+
+import collections
+from concurrent import futures
+import contextlib
+import distutils.spawn
+import errno
+import importlib
+import os
+import os.path
+import pkgutil
+import shutil
+import subprocess
+import sys
+import tempfile
+import threading
+import unittest
+
+import grpc
+from grpc.tools import protoc
+from tests.unit.framework.common import test_constants
+
+_MESSAGES_IMPORT = b'import "messages.proto";'
+
+@contextlib.contextmanager
+def _system_path(path):
+  old_system_path = sys.path[:]
+  sys.path = sys.path[0:1] + path + sys.path[1:]
+  yield
+  sys.path = old_system_path
+
+
+class DummySplitServicer(object):
+
+  def __init__(self, request_class, response_class):
+    self.request_class = request_class
+    self.response_class = response_class
+
+  def Call(self, request, context):
+    return self.response_class()
+
+
+class SeparateTestMixin(object):
+
+  def testImportAttributes(self):
+    with _system_path([self.python_out_directory]):
+      pb2 = importlib.import_module(self.pb2_import)
+    pb2.Request
+    pb2.Response
+    if self.should_find_services_in_pb2:
+      pb2.TestServiceServicer
+    else:
+      with self.assertRaises(AttributeError):
+        pb2.TestServiceServicer
+
+    with _system_path([self.grpc_python_out_directory]):
+      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+    pb2_grpc.TestServiceServicer
+    with self.assertRaises(AttributeError):
+      pb2_grpc.Request
+    with self.assertRaises(AttributeError):
+      pb2_grpc.Response
+
+  def testCall(self):
+    with _system_path([self.python_out_directory]):
+      pb2 = importlib.import_module(self.pb2_import)
+    with _system_path([self.grpc_python_out_directory]):
+      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+    server = grpc.server(
+        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+    pb2_grpc.add_TestServiceServicer_to_server(
+        DummySplitServicer(
+            pb2.Request, pb2.Response), server)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = grpc.insecure_channel('localhost:{}'.format(port))
+    stub = pb2_grpc.TestServiceStub(channel)
+    request = pb2.Request()
+    expected_response = pb2.Response()
+    response = stub.Call(request)
+    self.assertEqual(expected_response, response)
+
+
+class CommonTestMixin(object):
+
+  def testImportAttributes(self):
+    with _system_path([self.python_out_directory]):
+      pb2 = importlib.import_module(self.pb2_import)
+    pb2.Request
+    pb2.Response
+    if self.should_find_services_in_pb2:
+      pb2.TestServiceServicer
+    else:
+      with self.assertRaises(AttributeError):
+        pb2.TestServiceServicer
+
+    with _system_path([self.grpc_python_out_directory]):
+      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+    pb2_grpc.TestServiceServicer
+    with self.assertRaises(AttributeError):
+      pb2_grpc.Request
+    with self.assertRaises(AttributeError):
+      pb2_grpc.Response
+
+  def testCall(self):
+    with _system_path([self.python_out_directory]):
+      pb2 = importlib.import_module(self.pb2_import)
+    with _system_path([self.grpc_python_out_directory]):
+      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+    server = grpc.server(
+        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+    pb2_grpc.add_TestServiceServicer_to_server(
+        DummySplitServicer(
+            pb2.Request, pb2.Response), server)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = grpc.insecure_channel('localhost:{}'.format(port))
+    stub = pb2_grpc.TestServiceStub(channel)
+    request = pb2.Request()
+    expected_response = pb2.Response()
+    response = stub.Call(request)
+    self.assertEqual(expected_response, response)
+
+
+class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
+
+  def setUp(self):
+    same_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
+    self.directory = tempfile.mkdtemp(suffix='same_separate', dir='.')
+    self.proto_directory = os.path.join(self.directory, 'proto_path')
+    self.python_out_directory = os.path.join(self.directory, 'python_out')
+    self.grpc_python_out_directory = os.path.join(self.directory, 'grpc_python_out')
+    os.makedirs(self.proto_directory)
+    os.makedirs(self.python_out_directory)
+    os.makedirs(self.grpc_python_out_directory)
+    same_proto_file = os.path.join(self.proto_directory, 'same_separate.proto')
+    open(same_proto_file, 'wb').write(same_proto_contents)
+    protoc_result = protoc.main([
+        '',
+        '--proto_path={}'.format(self.proto_directory),
+        '--python_out={}'.format(self.python_out_directory),
+        '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
+        same_proto_file,
+    ])
+    if protoc_result != 0:
+      raise Exception("unexpected protoc error")
+    open(os.path.join(self.grpc_python_out_directory, '__init__.py'), 'w').write('')
+    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
+    self.pb2_import = 'same_separate_pb2'
+    self.pb2_grpc_import = 'same_separate_pb2_grpc'
+    self.should_find_services_in_pb2 = False
+
+  def tearDown(self):
+    shutil.rmtree(self.directory)
+
+
+class SameCommonTest(unittest.TestCase, CommonTestMixin):
+
+  def setUp(self):
+    same_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
+    self.directory = tempfile.mkdtemp(suffix='same_common', dir='.')
+    self.proto_directory = os.path.join(self.directory, 'proto_path')
+    self.python_out_directory = os.path.join(self.directory, 'python_out')
+    self.grpc_python_out_directory = self.python_out_directory
+    os.makedirs(self.proto_directory)
+    os.makedirs(self.python_out_directory)
+    same_proto_file = os.path.join(self.proto_directory, 'same_common.proto')
+    open(same_proto_file, 'wb').write(same_proto_contents)
+    protoc_result = protoc.main([
+        '',
+        '--proto_path={}'.format(self.proto_directory),
+        '--python_out={}'.format(self.python_out_directory),
+        '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+        same_proto_file,
+    ])
+    if protoc_result != 0:
+      raise Exception("unexpected protoc error")
+    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
+    self.pb2_import = 'same_common_pb2'
+    self.pb2_grpc_import = 'same_common_pb2_grpc'
+    self.should_find_services_in_pb2 = True
+
+  def tearDown(self):
+    shutil.rmtree(self.directory)
+
+
+class SplitCommonTest(unittest.TestCase, CommonTestMixin):
+
+  def setUp(self):
+    services_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing.split_services',
+        'services.proto')
+    messages_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing.split_messages',
+        'messages.proto')
+    self.directory = tempfile.mkdtemp(suffix='split_common', dir='.')
+    self.proto_directory = os.path.join(self.directory, 'proto_path')
+    self.python_out_directory = os.path.join(self.directory, 'python_out')
+    self.grpc_python_out_directory = self.python_out_directory
+    os.makedirs(self.proto_directory)
+    os.makedirs(self.python_out_directory)
+    services_proto_file = os.path.join(self.proto_directory,
+                                       'split_common_services.proto')
+    messages_proto_file = os.path.join(self.proto_directory,
+                                       'split_common_messages.proto')
+    open(services_proto_file, 'wb').write(services_proto_contents.replace(
+        _MESSAGES_IMPORT,
+        b'import "split_common_messages.proto";'
+    ))
+    open(messages_proto_file, 'wb').write(messages_proto_contents)
+    protoc_result = protoc.main([
+        '',
+        '--proto_path={}'.format(self.proto_directory),
+        '--python_out={}'.format(self.python_out_directory),
+        '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+        services_proto_file,
+        messages_proto_file,
+    ])
+    if protoc_result != 0:
+      raise Exception("unexpected protoc error")
+    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
+    self.pb2_import = 'split_common_messages_pb2'
+    self.pb2_grpc_import = 'split_common_services_pb2_grpc'
+    self.should_find_services_in_pb2 = False
+
+  def tearDown(self):
+    shutil.rmtree(self.directory)
+
+
+class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
+
+  def setUp(self):
+    services_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing.split_services',
+        'services.proto')
+    messages_proto_contents = pkgutil.get_data(
+        'tests.protoc_plugin.protos.invocation_testing.split_messages',
+        'messages.proto')
+    self.directory = tempfile.mkdtemp(suffix='split_separate', dir='.')
+    self.proto_directory = os.path.join(self.directory, 'proto_path')
+    self.python_out_directory = os.path.join(self.directory, 'python_out')
+    self.grpc_python_out_directory = os.path.join(self.directory, 'grpc_python_out')
+    os.makedirs(self.proto_directory)
+    os.makedirs(self.python_out_directory)
+    os.makedirs(self.grpc_python_out_directory)
+    services_proto_file = os.path.join(self.proto_directory,
+                                       'split_separate_services.proto')
+    messages_proto_file = os.path.join(self.proto_directory,
+                                       'split_separate_messages.proto')
+    open(services_proto_file, 'wb').write(services_proto_contents.replace(
+        _MESSAGES_IMPORT,
+        b'import "split_separate_messages.proto";'
+    ))
+    open(messages_proto_file, 'wb').write(messages_proto_contents)
+    protoc_result = protoc.main([
+        '',
+        '--proto_path={}'.format(self.proto_directory),
+        '--python_out={}'.format(self.python_out_directory),
+        '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
+        services_proto_file,
+        messages_proto_file,
+    ])
+    if protoc_result != 0:
+      raise Exception("unexpected protoc error")
+    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
+    self.pb2_import = 'split_separate_messages_pb2'
+    self.pb2_grpc_import = 'split_separate_services_pb2_grpc'
+    self.should_find_services_in_pb2 = False
+
+  def tearDown(self):
+    shutil.rmtree(self.directory)
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
new file mode 100644
index 0000000000..2f88fa0412
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
@@ -0,0 +1,30 @@
+# Copyright 2016, 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.
+
+
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/same.proto b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/same.proto
new file mode 100644
index 0000000000..269e2fd2c7
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/same.proto
@@ -0,0 +1,39 @@
+// Copyright 2016, 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";
+
+package grpc_protoc_plugin.invocation_testing;
+
+message Request {}
+message Response {}
+
+service TestService {
+  rpc Call(Request) returns (Response);
+}
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
new file mode 100644
index 0000000000..2f88fa0412
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
@@ -0,0 +1,30 @@
+# Copyright 2016, 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.
+
+
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/messages.proto b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/messages.proto
new file mode 100644
index 0000000000..de22dae049
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/messages.proto
@@ -0,0 +1,35 @@
+// Copyright 2016, 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";
+
+package grpc_protoc_plugin.invocation_testing.split;
+
+message Request {}
+message Response {}
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
new file mode 100644
index 0000000000..2f88fa0412
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
@@ -0,0 +1,30 @@
+# Copyright 2016, 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.
+
+
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/services.proto b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/services.proto
new file mode 100644
index 0000000000..af999cd48d
--- /dev/null
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/services.proto
@@ -0,0 +1,38 @@
+// Copyright 2016, 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 "messages.proto";
+
+package grpc_protoc_plugin.invocation_testing.split;
+
+service TestService {
+  rpc Call(Request) returns (Response);
+}
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index dcaef0db1f..d0cf2b5779 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -4,40 +4,44 @@
   "_api_test.ChannelTest",
   "_auth_test.AccessTokenCallCredentialsTest",
   "_auth_test.GoogleCallCredentialsTest",
-  "_beta_features_test.BetaFeaturesTest", 
-  "_beta_features_test.ContextManagementAndLifecycleTest", 
+  "_beta_features_test.BetaFeaturesTest",
+  "_beta_features_test.ContextManagementAndLifecycleTest",
   "_cancel_many_calls_test.CancelManyCallsTest",
   "_channel_connectivity_test.ChannelConnectivityTest",
   "_channel_ready_future_test.ChannelReadyFutureTest",
-  "_channel_test.ChannelTest", 
+  "_channel_test.ChannelTest",
   "_compression_test.CompressionTest",
   "_connectivity_channel_test.ConnectivityStatesTest",
   "_credentials_test.CredentialsTest",
   "_empty_message_test.EmptyMessageTest",
   "_exit_test.ExitTest",
-  "_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", 
-  "_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", 
-  "_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", 
-  "_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", 
-  "_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", 
+  "_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest",
+  "_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest",
+  "_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest",
+  "_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest",
+  "_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest",
   "_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest",
   "_health_servicer_test.HealthServicerTest",
   "_implementations_test.CallCredentialsTest",
-  "_implementations_test.ChannelCredentialsTest", 
-  "_insecure_interop_test.InsecureInteropTest", 
-  "_logging_pool_test.LoggingPoolTest", 
+  "_implementations_test.ChannelCredentialsTest",
+  "_insecure_interop_test.InsecureInteropTest",
+  "_logging_pool_test.LoggingPoolTest",
   "_metadata_code_details_test.MetadataCodeDetailsTest",
   "_metadata_test.MetadataTest",
-  "_not_found_test.NotFoundTest", 
+  "_not_found_test.NotFoundTest",
   "_python_plugin_test.PythonPluginTest",
   "_read_some_but_not_all_responses_test.ReadSomeButNotAllResponsesTest",
   "_rpc_test.RPCTest",
-  "_sanity_test.Sanity", 
-  "_secure_interop_test.SecureInteropTest", 
+  "_sanity_test.Sanity",
+  "_secure_interop_test.SecureInteropTest",
+  "_split_definitions_test.SameCommonTest",
+  "_split_definitions_test.SameSeparateTest",
+  "_split_definitions_test.SplitCommonTest",
+  "_split_definitions_test.SplitSeparateTest",
   "_thread_cleanup_test.CleanupThreadTest",
-  "_utilities_test.ChannelConnectivityTest", 
-  "beta_python_plugin_test.PythonPluginTest", 
-  "cygrpc_test.InsecureServerInsecureClient", 
-  "cygrpc_test.SecureServerSecureClient", 
+  "_utilities_test.ChannelConnectivityTest",
+  "beta_python_plugin_test.PythonPluginTest",
+  "cygrpc_test.InsecureServerInsecureClient",
+  "cygrpc_test.SecureServerSecureClient",
   "cygrpc_test.TypeSmokeTest"
 ]
-- 
GitLab


From fa5e31c6e84510743eec29453b21aab160ebb598 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Thu, 8 Dec 2016 18:04:36 -0800
Subject: [PATCH 105/344] remove ruby thread pool unit test of exception on
 overload

---
 src/ruby/spec/generic/rpc_server_pool_spec.rb | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
index 48ccaee510..69e8222cb9 100644
--- a/src/ruby/spec/generic/rpc_server_pool_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb
@@ -94,18 +94,6 @@ describe GRPC::Pool do
       expect(q.pop).to be(o)
       p.stop
     end
-
-    it 'it throws an error if all of the workers have tasks to do' do
-      p = Pool.new(5)
-      p.start
-      job = proc {}
-      5.times do
-        expect(p.ready_for_work?).to be(true)
-        p.schedule(&job)
-      end
-      expect { p.schedule(&job) }.to raise_error
-      expect { p.schedule(&job) }.to raise_error
-    end
   end
 
   describe '#stop' do
-- 
GitLab


From e51e72d7c902eefaa7b633ed87847a80e05af6db Mon Sep 17 00:00:00 2001
From: igorpeshansky <igorpeshansky@users.noreply.github.com>
Date: Fri, 9 Dec 2016 11:00:28 -0500
Subject: [PATCH 106/344] Use snake_case names for default rpc method
 implementations

This is what `GRPC::Pool::add_rpc_descs_for` expects.
---
 src/ruby/lib/grpc/generic/service.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 7cb9f1cc99..06ea5b3f17 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -110,7 +110,7 @@ module GRPC
         rpc_descs[name] = RpcDesc.new(name, input, output,
                                       marshal_class_method,
                                       unmarshal_class_method)
-        define_method(name) do
+        define_method(GenericService.underscore(name.to_s).to_sym) do
           fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
         end
       end
-- 
GitLab


From ac6915797db5b3dc719f57f1d2e037dab3992b1c Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 9 Dec 2016 08:51:34 -0800
Subject: [PATCH 107/344] Fix compilation

---
 src/core/lib/iomgr/tcp_posix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 7cc66fbad4..a26761ec48 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -236,7 +236,7 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
       /* We've consumed the edge, request a new one */
       grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
     } else {
-      grpc_slice_buffer_reset_and_unref(exec_ctx, tcp->incoming_buffer);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
       call_read_cb(exec_ctx, tcp,
                    tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp));
       TCP_UNREF(exec_ctx, tcp, "read");
-- 
GitLab


From 298d481f1e8348cb7713d53a26fc2c41eb9d8f7c Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 9 Dec 2016 08:51:48 -0800
Subject: [PATCH 108/344] clang-format

---
 src/core/lib/iomgr/tcp_posix.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index a26761ec48..25f9b84e11 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -236,7 +236,8 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
       /* We've consumed the edge, request a new one */
       grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
     } else {
-      grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                                 tcp->incoming_buffer);
       call_read_cb(exec_ctx, tcp,
                    tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp));
       TCP_UNREF(exec_ctx, tcp, "read");
-- 
GitLab


From c217e490b176669bf93c04e772218d88b5fef764 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 9 Dec 2016 14:03:58 -0800
Subject: [PATCH 109/344] Add function to create channel arg for client channel
 factory.

---
 .../client_channel/client_channel_factory.c   | 32 +++++++++++++++++++
 .../client_channel/client_channel_factory.h   |  3 ++
 .../chttp2/client/insecure/channel_create.c   | 18 +----------
 .../client/secure/secure_channel_create.c     | 27 +---------------
 4 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/src/core/ext/client_channel/client_channel_factory.c b/src/core/ext/client_channel/client_channel_factory.c
index 4900832d57..01eee02979 100644
--- a/src/core/ext/client_channel/client_channel_factory.c
+++ b/src/core/ext/client_channel/client_channel_factory.c
@@ -55,3 +55,35 @@ grpc_channel* grpc_client_channel_factory_create_channel(
   return factory->vtable->create_client_channel(exec_ctx, factory, target, type,
                                                 args);
 }
+
+static void *factory_arg_copy(void *factory) {
+  grpc_client_channel_factory_ref(factory);
+  return factory;
+}
+
+static void factory_arg_destroy(void *factory) {
+  // TODO(roth): Remove local exec_ctx when
+  // https://github.com/grpc/grpc/pull/8705 is merged.
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_client_channel_factory_unref(&exec_ctx, factory);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static int factory_arg_cmp(void *factory1, void *factory2) {
+  if (factory1 < factory2) return -1;
+  if (factory1 > factory2) return 1;
+  return 0;
+}
+
+static const grpc_arg_pointer_vtable factory_arg_vtable = {
+    factory_arg_copy, factory_arg_destroy, factory_arg_cmp};
+
+grpc_arg grpc_client_channel_factory_create_channel_arg(
+    grpc_client_channel_factory *factory) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
+  arg.value.pointer.p = factory;
+  arg.value.pointer.vtable = &factory_arg_vtable;
+  return arg;
+}
diff --git a/src/core/ext/client_channel/client_channel_factory.h b/src/core/ext/client_channel/client_channel_factory.h
index 2b8fc577b3..e7ad918881 100644
--- a/src/core/ext/client_channel/client_channel_factory.h
+++ b/src/core/ext/client_channel/client_channel_factory.h
@@ -83,4 +83,7 @@ grpc_channel *grpc_client_channel_factory_create_channel(
     const char *target, grpc_client_channel_type type,
     const grpc_channel_args *args);
 
+grpc_arg grpc_client_channel_factory_create_channel_arg(
+    grpc_client_channel_factory *factory);
+
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 3ad34b0870..1e1bed10dc 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -76,19 +76,6 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
 static grpc_client_channel_factory client_channel_factory = {
     &client_channel_factory_vtable};
 
-static void *cc_factory_arg_copy(void *cc_factory) { return cc_factory; }
-
-static void cc_factory_arg_destroy(void *cc_factory) {}
-
-static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
-  if (cc_factory1 < cc_factory2) return -1;
-  if (cc_factory1 > cc_factory2) return 1;
-  return 0;
-}
-
-static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
-    cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
-
 /* Create a client channel:
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
@@ -108,10 +95,7 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
   new_args[0].type = GRPC_ARG_STRING;
   new_args[0].key = GRPC_ARG_SERVER_URI;
   new_args[0].value.string = (char *)target;
-  new_args[1].type = GRPC_ARG_POINTER;
-  new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
-  new_args[1].value.pointer.p = factory;
-  new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+  new_args[1] = grpc_client_channel_factory_create_channel_arg(factory);
   grpc_channel_args *args_copy =
       grpc_channel_args_copy_and_add(args, new_args, GPR_ARRAY_SIZE(new_args));
   // Create channel.
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 2bef684398..2474f544cf 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -97,28 +97,6 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
      client_channel_factory_create_subchannel,
      client_channel_factory_create_channel};
 
-static void *cc_factory_arg_copy(void *cc_factory) {
-  client_channel_factory_ref(cc_factory);
-  return cc_factory;
-}
-
-static void cc_factory_arg_destroy(void *cc_factory) {
-  // TODO(roth): remove local exec_ctx when
-  // https://github.com/grpc/grpc/pull/8705 is merged
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  client_channel_factory_unref(&exec_ctx, cc_factory);
-  grpc_exec_ctx_finish(&exec_ctx);
-}
-
-static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
-  if (cc_factory1 < cc_factory2) return -1;
-  if (cc_factory1 > cc_factory2) return 1;
-  return 0;
-}
-
-static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
-    cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
-
 /* Create a secure client channel:
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
@@ -165,10 +143,7 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   new_args[0].type = GRPC_ARG_STRING;
   new_args[0].key = GRPC_ARG_SERVER_URI;
   new_args[0].value.string = (char *)target;
-  new_args[1].type = GRPC_ARG_POINTER;
-  new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
-  new_args[1].value.pointer.p = f;
-  new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+  new_args[1] = grpc_client_channel_factory_create_channel_arg(&f->base);
   new_args[2] = grpc_security_connector_to_arg(&security_connector->base);
   grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
       new_args_from_connector != NULL ? new_args_from_connector : args,
-- 
GitLab


From b2b6a9eb5761944fdc4f689b291b60028c92c082 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Fri, 9 Dec 2016 22:25:36 +0000
Subject: [PATCH 110/344] ServicerContext methods doc string fix and tweak

ServicerContext.set_code takes a (grpc.)StatusCode, not an integer.
---
 src/python/grpcio/grpc/__init__.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 126ad556bb..d4e3152c59 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -767,8 +767,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
     gRPC runtime to determine the status code of the RPC.
 
     Args:
-      code: The integer status code of the RPC to be transmitted to the
-        invocation side of the RPC.
+      code: A StatusCode value to be transmitted to the invocation side of the
+        RPC as the status code of the RPC.
     """
     raise NotImplementedError()
 
@@ -780,8 +780,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
     details to transmit.
 
     Args:
-      details: The details string of the RPC to be transmitted to
-        the invocation side of the RPC.
+      details: A string to be transmitted to the invocation side of the RPC as
+        the status details of the RPC.
     """
     raise NotImplementedError()
 
-- 
GitLab


From 6ba93f2612cf6e8010ee90d8b17a4478efde65e2 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Wed, 7 Dec 2016 18:25:19 -0800
Subject: [PATCH 111/344] Up-version Python for backports

---
 build.yaml                                        | 1 +
 src/python/grpcio/grpc_version.py                 | 2 +-
 src/python/grpcio_health_checking/grpc_version.py | 2 +-
 src/python/grpcio_tests/grpc_version.py           | 2 +-
 tools/distrib/python/grpcio_tools/grpc_version.py | 2 +-
 5 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/build.yaml b/build.yaml
index 12d7f855de..d725ff3890 100644
--- a/build.yaml
+++ b/build.yaml
@@ -7,6 +7,7 @@ settings:
   '#3': Use "-preN" suffixes to identify pre-release versions
   '#4': Per-language overrides are possible with (eg) ruby_version tag here
   '#5': See the expand_version.py for all the quirks here
+  python_version: 1.0.2
   version: 1.0.1
 filegroups:
 - name: census
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 5e35a7770d..219045a721 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION='1.0.1'
+VERSION='1.0.2'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 14cb881237..4cb8c3d82a 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION='1.0.1'
+VERSION='1.0.2'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 0f39afb37f..66b0398c7a 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION='1.0.1'
+VERSION='1.0.2'
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 4f7fe9d587..6dd6fae0d7 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION='1.0.1'
+VERSION='1.0.2'
-- 
GitLab


From 4625b8bb94cfebdbac7f2fd8b2c7ba3b2b9d1574 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@google.com>
Date: Fri, 9 Dec 2016 15:04:49 -0800
Subject: [PATCH 112/344] Fix go docker

---
 tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
index 858ee0a68c..46aabc6b38 100755
--- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
@@ -37,7 +37,7 @@ set -e
 git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc
 
 # Get all gRPC Go dependencies
-(cd src/google.golang.org/grpc && go get -t .)
+(cd src/google.golang.org/grpc && make deps && make testdeps)
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
-- 
GitLab


From 8b223e2986fe92e93aa93b8524d25fbc6d3989b2 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Fri, 9 Dec 2016 23:25:56 +0000
Subject: [PATCH 113/344] Correct Python cancel_after_begin interop test

It was a mistake that requests might be sent; the test specification
calls for no requests to be sent. It was a mistake that the response
future's cancelled() method was called; the cancelled() method returns
something more like "was this object's cancel() method called earlier?"
than "did the RPC terminate with status code CANCELLED?". Since it's
something that we'd well enough like to work I've retained the
cancelled() call with a different failure message.
---
 .../grpcio_tests/tests/interop/methods.py     | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 7edd75c56c..c4a0c08430 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -159,16 +159,6 @@ def _server_streaming(stub):
       raise ValueError(
           'response body of invalid size %d!' % len(response.payload.body))
 
-def _cancel_after_begin(stub):
-  sizes = (27182, 8, 1828, 45904,)
-  payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes)
-  requests = (messages_pb2.StreamingInputCallRequest(payload=payload)
-              for payload in payloads)
-  response_future = stub.StreamingInputCall.future(requests)
-  response_future.cancel()
-  if not response_future.cancelled():
-    raise ValueError('expected call to be cancelled')
-
 
 class _Pipe(object):
 
@@ -232,6 +222,16 @@ def _ping_pong(stub):
             'response body of invalid size %d!' % len(response.payload.body))
 
 
+def _cancel_after_begin(stub):
+  with _Pipe() as pipe:
+    response_future = stub.StreamingInputCall.future(pipe)
+    response_future.cancel()
+    if not response_future.cancelled():
+      raise ValueError('expected cancelled method to return True')
+    if response_future.code() is not grpc.StatusCode.CANCELLED:
+      raise ValueError('expected status code CANCELLED')
+
+
 def _cancel_after_first_response(stub):
   request_response_sizes = (31415, 9, 2653, 58979,)
   request_payload_sizes = (27182, 8, 1828, 45904,)
-- 
GitLab


From e1fd78f110d067c5091906664db05b7d80ee2991 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Fri, 9 Dec 2016 23:27:58 +0000
Subject: [PATCH 114/344] Drop unnecessary sleep in interop test

---
 src/python/grpcio_tests/tests/interop/methods.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index c4a0c08430..16afe4c6bf 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -33,7 +33,6 @@ import enum
 import json
 import os
 import threading
-import time
 
 from oauth2client import client as oauth2client_client
 
@@ -269,7 +268,6 @@ def _timeout_on_sleeping_server(stub):
         response_type=messages_pb2.COMPRESSABLE,
         payload=messages_pb2.Payload(body=b'\x00' * request_payload_size))
     pipe.add(request)
-    time.sleep(0.1)
     try:
       next(response_iterator)
     except grpc.RpcError as rpc_error:
-- 
GitLab


From 2562b532e0833cfe006cac0af2d9c54645a2d216 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Fri, 9 Dec 2016 16:26:07 -0800
Subject: [PATCH 115/344] Backport Python setuptools unpinning

This should allow our tests to build on newer virtualenvs.
---
 tools/run_tests/build_python.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index d2ff1c6b53..0a73353ce5 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -170,8 +170,7 @@ pip_install_dir() {
 }
 
 $VENV_PYTHON -m pip install --upgrade pip
-# TODO(https://github.com/pypa/setuptools/issues/709) get the latest setuptools
-$VENV_PYTHON -m pip install setuptools==25.1.1
+$VENV_PYTHON -m pip install setuptools
 $VENV_PYTHON -m pip install cython
 pip_install_dir $ROOT
 $VENV_PYTHON $ROOT/tools/distrib/python/make_grpcio_tools.py
-- 
GitLab


From 1a7c57bf6c939fc3f9a478191f93f997192653f4 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 12 Dec 2016 06:38:13 -0800
Subject: [PATCH 116/344] Fix merge error

---
 src/core/ext/transport/chttp2/server/chttp2_server.c  | 2 +-
 src/core/lib/security/transport/security_handshaker.c | 4 ----
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index 30bdcd8b75..d573bbe73e 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -165,7 +165,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
           connection_state->accepting_pollset, args->args);
       grpc_chttp2_transport_start_reading(exec_ctx, transport,
                                           args->read_buffer);
-      grpc_channel_args_destroy(args->args);
+      grpc_channel_args_destroy(exec_ctx, args->args);
     }
   }
   pending_handshake_manager_remove_locked(connection_state->server_state,
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 4f9f97ed71..7c2f63d1cc 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -132,14 +132,10 @@ static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx,
     grpc_endpoint_shutdown(exec_ctx, h->args->endpoint);
     // Not shutting down, so the write failed.  Clean up before
     // invoking the callback.
-<<<<<<< HEAD
     cleanup_args_for_failure_locked(exec_ctx, h);
-=======
-    cleanup_args_for_failure_locked(h);
     // Set shutdown to true so that subsequent calls to
     // security_handshaker_shutdown() do nothing.
     h->shutdown = true;
->>>>>>> b62bffbea5eef106bfbe644e8af161889c927401
   }
   // Invoke callback.
   grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, error, NULL);
-- 
GitLab


From 4d2ea021296697ade62457386ab36bafa8e7c5c4 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 07:12:27 -0800
Subject: [PATCH 117/344] Revert "Revert "Revert "Revert "Remove redundant
 includes from string.h and tmpfile.h""""

---
 BUILD                                         |  9 ++
 CMakeLists.txt                                |  7 ++
 Makefile                                      |  9 ++
 build.yaml                                    |  1 +
 gRPC-Core.podspec                             |  2 +
 grpc.gemspec                                  |  2 +
 include/grpc/impl/codegen/gpr_slice.h         | 84 +++++++++++++++++++
 include/grpc/impl/codegen/slice.h             | 20 +++++
 package.xml                                   |  2 +
 src/core/lib/support/string.h                 |  2 -
 src/core/lib/support/tmpfile.h                |  2 -
 .../core/surface/public_headers_must_be_c89.c |  1 +
 tools/doxygen/Doxyfile.c++                    |  1 +
 tools/doxygen/Doxyfile.c++.internal           |  1 +
 tools/doxygen/Doxyfile.core                   |  2 +
 tools/doxygen/Doxyfile.core.internal          |  2 +
 tools/run_tests/sources_and_headers.json      |  2 +
 vsprojects/vcxproj/gpr/gpr.vcxproj            |  1 +
 vsprojects/vcxproj/gpr/gpr.vcxproj.filters    |  3 +
 vsprojects/vcxproj/grpc++/grpc++.vcxproj      |  1 +
 .../vcxproj/grpc++/grpc++.vcxproj.filters     |  3 +
 .../grpc++_test_util/grpc++_test_util.vcxproj |  1 +
 .../grpc++_test_util.vcxproj.filters          |  3 +
 .../grpc++_unsecure/grpc++_unsecure.vcxproj   |  1 +
 .../grpc++_unsecure.vcxproj.filters           |  3 +
 vsprojects/vcxproj/grpc/grpc.vcxproj          |  1 +
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters  |  3 +
 .../grpc_test_util/grpc_test_util.vcxproj     |  1 +
 .../grpc_test_util.vcxproj.filters            |  3 +
 .../grpc_unsecure/grpc_unsecure.vcxproj       |  1 +
 .../grpc_unsecure.vcxproj.filters             |  3 +
 .../codegen_test_full.vcxproj                 |  1 +
 .../codegen_test_full.vcxproj.filters         |  3 +
 .../codegen_test_minimal.vcxproj              |  1 +
 .../codegen_test_minimal.vcxproj.filters      |  3 +
 .../grpc_tool_test/grpc_tool_test.vcxproj     |  1 +
 .../grpc_tool_test.vcxproj.filters            |  3 +
 37 files changed, 185 insertions(+), 4 deletions(-)
 create mode 100644 include/grpc/impl/codegen/gpr_slice.h

diff --git a/BUILD b/BUILD
index ab0fc237b7..fb81cf65fc 100644
--- a/BUILD
+++ b/BUILD
@@ -135,6 +135,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -564,6 +565,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -960,6 +962,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1341,6 +1344,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1496,6 +1500,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1958,6 +1963,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -2134,6 +2140,7 @@ cc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -2296,6 +2303,7 @@ objc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -2562,6 +2570,7 @@ objc_library(
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/gpr_slice.h",
     "include/grpc/impl/codegen/gpr_types.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff0927504a..16e5d62de2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -258,6 +258,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -537,6 +538,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -788,6 +790,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1039,6 +1042,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1202,6 +1206,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1535,6 +1540,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
@@ -1741,6 +1747,7 @@ foreach(_hdr
   include/grpc/impl/codegen/atm_gcc_atomic.h
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
   include/grpc/impl/codegen/gpr_types.h
   include/grpc/impl/codegen/port_platform.h
   include/grpc/impl/codegen/slice.h
diff --git a/Makefile b/Makefile
index 8f7328ae28..eae4f46e70 100644
--- a/Makefile
+++ b/Makefile
@@ -2552,6 +2552,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -2859,6 +2860,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3129,6 +3131,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3345,6 +3348,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3635,6 +3639,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3879,6 +3884,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4241,6 +4247,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4596,6 +4603,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -4774,6 +4782,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/gpr_slice.h \
     include/grpc/impl/codegen/gpr_types.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
diff --git a/build.yaml b/build.yaml
index de9d253ef1..2555abce0c 100644
--- a/build.yaml
+++ b/build.yaml
@@ -144,6 +144,7 @@ filegroups:
   - include/grpc/impl/codegen/atm_gcc_atomic.h
   - include/grpc/impl/codegen/atm_gcc_sync.h
   - include/grpc/impl/codegen/atm_windows.h
+  - include/grpc/impl/codegen/gpr_slice.h
   - include/grpc/impl/codegen/gpr_types.h
   - include/grpc/impl/codegen/port_platform.h
   - include/grpc/impl/codegen/slice.h
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 04f7211d21..f9e0164bdc 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -146,6 +146,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
                       'include/grpc/impl/codegen/atm_windows.h',
+                      'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
@@ -172,6 +173,7 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
                       'include/grpc/impl/codegen/atm_windows.h',
+                      'include/grpc/impl/codegen/gpr_slice.h',
                       'include/grpc/impl/codegen/gpr_types.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 6019b97f67..9c9568ce64 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -73,6 +73,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+  s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -155,6 +156,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+  s.files += %w( include/grpc/impl/codegen/gpr_slice.h )
   s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
diff --git a/include/grpc/impl/codegen/gpr_slice.h b/include/grpc/impl/codegen/gpr_slice.h
new file mode 100644
index 0000000000..c62e976b8f
--- /dev/null
+++ b/include/grpc/impl/codegen/gpr_slice.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef GRPC_IMPL_CODEGEN_GPR_SLICE_H
+#define GRPC_IMPL_CODEGEN_GPR_SLICE_H
+
+/* WARNING: Please do not use this header. This was added as a temporary measure
+ * to not break some of the external projects that depend on gpr_slice_*
+ * functions. We are actively working on moving all the gpr_slice_* references
+ * to grpc_slice_* and this file will be removed
+ * */
+
+/* TODO (sreek) - Allowed by default but will be very soon turned off */
+#define GRPC_ALLOW_GPR_SLICE_FUNCTIONS 1
+
+#ifdef GRPC_ALLOW_GPR_SLICE_FUNCTIONS
+
+#define gpr_slice_refcount grpc_slice_refcount
+#define gpr_slice grpc_slice
+#define gpr_slice_buffer grpc_slice_buffer
+
+#define gpr_slice_ref grpc_slice_ref
+#define gpr_slice_unref grpc_slice_unref
+#define gpr_slice_new grpc_slice_new
+#define gpr_slice_new_with_user_data grpc_slice_new_with_user_data
+#define gpr_slice_new_with_len grpc_slice_new_with_len
+#define gpr_slice_malloc grpc_slice_malloc
+#define gpr_slice_from_copied_string grpc_slice_from_copied_string
+#define gpr_slice_from_copied_buffer grpc_slice_from_copied_buffer
+#define gpr_slice_from_static_string grpc_slice_from_static_string
+#define gpr_slice_sub grpc_slice_sub
+#define gpr_slice_sub_no_ref grpc_slice_sub_no_ref
+#define gpr_slice_split_tail grpc_slice_split_tail
+#define gpr_slice_split_head grpc_slice_split_head
+#define gpr_slice_cmp grpc_slice_cmp
+#define gpr_slice_str_cmp grpc_slice_str_cmp
+
+#define gpr_slice_buffer grpc_slice_buffer
+#define gpr_slice_buffer_init grpc_slice_buffer_init
+#define gpr_slice_buffer_destroy grpc_slice_buffer_destroy
+#define gpr_slice_buffer_add grpc_slice_buffer_add
+#define gpr_slice_buffer_add_indexed grpc_slice_buffer_add_indexed
+#define gpr_slice_buffer_addn grpc_slice_buffer_addn
+#define gpr_slice_buffer_tiny_add grpc_slice_buffer_tiny_add
+#define gpr_slice_buffer_pop grpc_slice_buffer_pop
+#define gpr_slice_buffer_reset_and_unref grpc_slice_buffer_reset_and_unref
+#define gpr_slice_buffer_swap grpc_slice_buffer_swap
+#define gpr_slice_buffer_move_into grpc_slice_buffer_move_into
+#define gpr_slice_buffer_trim_end grpc_slice_buffer_trim_end
+#define gpr_slice_buffer_move_first grpc_slice_buffer_move_first
+#define gpr_slice_buffer_take_first grpc_slice_buffer_take_first
+
+#endif /* GRPC_ALLOW_GPR_SLICE_FUNCTIONS */
+
+#endif /* GRPC_IMPL_CODEGEN_GPR_SLICE_H */
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 774ba0e95d..50b5426e1a 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,6 +37,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <grpc/impl/codegen/gpr_slice.h>
+
 /* Slice API
 
    A slice represents a contiguous reference counted array of bytes.
@@ -115,4 +117,22 @@ typedef struct {
   GRPC_SLICE_START_PTR(slice) + GRPC_SLICE_LENGTH(slice)
 #define GRPC_SLICE_IS_EMPTY(slice) (GRPC_SLICE_LENGTH(slice) == 0)
 
+#ifdef GRPC_ALLOW_GPR_SLICE_FUNCTIONS
+
+/* Duplicate GPR_* definitions */
+#define GPR_SLICE_START_PTR(slice)                  \
+  ((slice).refcount ? (slice).data.refcounted.bytes \
+                    : (slice).data.inlined.bytes)
+#define GPR_SLICE_LENGTH(slice)                      \
+  ((slice).refcount ? (slice).data.refcounted.length \
+                    : (slice).data.inlined.length)
+#define GPR_SLICE_SET_LENGTH(slice, newlen)                               \
+  ((slice).refcount ? ((slice).data.refcounted.length = (size_t)(newlen)) \
+                    : ((slice).data.inlined.length = (uint8_t)(newlen)))
+#define GPR_SLICE_END_PTR(slice) \
+  GRPC_SLICE_START_PTR(slice) + GRPC_SLICE_LENGTH(slice)
+#define GPR_SLICE_IS_EMPTY(slice) (GRPC_SLICE_LENGTH(slice) == 0)
+
+#endif /* GRPC_ALLOW_GPR_SLICE_FUNCTIONS */
+
 #endif /* GRPC_IMPL_CODEGEN_SLICE_H */
diff --git a/package.xml b/package.xml
index 61668815a6..2106b8f666 100644
--- a/package.xml
+++ b/package.xml
@@ -81,6 +81,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -163,6 +164,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h
index e933e2eb46..db59308425 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/support/string.h
@@ -36,8 +36,6 @@
 
 #include <stddef.h>
 
-#include <grpc/slice.h>
-#include <grpc/slice_buffer.h>
 #include <grpc/support/port_platform.h>
 
 #ifdef __cplusplus
diff --git a/src/core/lib/support/tmpfile.h b/src/core/lib/support/tmpfile.h
index 8952e5ec3d..f613cf9bc8 100644
--- a/src/core/lib/support/tmpfile.h
+++ b/src/core/lib/support/tmpfile.h
@@ -36,8 +36,6 @@
 
 #include <stdio.h>
 
-#include <grpc/slice.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index d4cfa25d44..df6b733493 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -42,6 +42,7 @@
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/gpr_slice.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/impl/codegen/port_platform.h>
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index ff3a0e381d..9e3fc62ebc 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 04e8f4e7f2..074ba504fa 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 1e748ba4a8..b83e710a2b 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -818,6 +819,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 6572bd4ddf..533999b765 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -1212,6 +1213,7 @@ include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 6ae269cc20..449cc126e3 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6631,6 +6631,7 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_windows.h", 
+      "include/grpc/impl/codegen/gpr_slice.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
@@ -6647,6 +6648,7 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_windows.h", 
+      "include/grpc/impl/codegen/gpr_slice.h", 
       "include/grpc/impl/codegen/gpr_types.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index ce593473c0..c4f9c55308 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -177,6 +177,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index a50a9f4200..77a1ba64d6 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -225,6 +225,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index f281db72b6..14b3453b74 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index f359e4ef31..5360819649 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -354,6 +354,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index d2305b2e25..6a928e173f 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -185,6 +185,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index d1aaba7092..bf8fab03bb 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -147,6 +147,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 1511a2cfe4..39b01e6a4e 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -338,6 +338,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index bed77b25a4..9cafa1670a 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -339,6 +339,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 558b5b0c66..40f0f141b5 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -286,6 +286,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index a40a1b5f1c..c0de28563e 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -705,6 +705,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 2acdd32cf3..01b73ce1a2 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -166,6 +166,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 6c918f1254..40ff67671f 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -456,6 +456,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 661192101c..49c2d2db30 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -277,6 +277,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 466116e604..5bca4fb9a5 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -621,6 +621,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index a2b2a1dfa0..377d86fa5a 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -198,6 +198,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index 94b6c2530e..e9ba002e9b 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -135,6 +135,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 1a3c157983..3254ad8d45 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -198,6 +198,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index 1f4b60ca4d..6f32f65524 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -138,6 +138,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index 1e3cc3ca04..7fad922233 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -199,6 +199,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 1c308c5881..19cb113341 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -129,6 +129,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-- 
GitLab


From f75d26925f3371b44b774b15165d79484f3f12e1 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 08:41:42 -0800
Subject: [PATCH 118/344] Fix grpclb code.

---
 src/core/ext/lb_policy/grpclb/grpclb.c        |  8 +++++-
 .../chttp2/client/insecure/channel_create.c   | 26 +++++++++++--------
 .../client/secure/secure_channel_create.c     | 24 ++++++++++-------
 3 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index df0db61c22..da1cf65060 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -818,9 +818,15 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
    * We need the LB channel to return addresses with is_balancer=false
    * so that it does not wind up recursively using the grpclb LB policy,
    * as per the special case logic in client_channel.c.
+   *
+   * Finally, we also strip out the channel arg for the server URI,
+   * since that will be different for the LB channel than for the parent
+   * channel.  (The client channel factory will re-add this arg with
+   * the right value.)
    */
   static const char *keys_to_remove[] = {GRPC_ARG_LB_POLICY_NAME,
-                                         GRPC_ARG_LB_ADDRESSES};
+                                         GRPC_ARG_LB_ADDRESSES,
+                                         GRPC_ARG_SERVER_URI};
   grpc_channel_args *new_args = grpc_channel_args_copy_and_remove(
       args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove));
   glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 1e1bed10dc..90d3503959 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -65,7 +65,16 @@ static grpc_channel *client_channel_factory_create_channel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const char *target, grpc_client_channel_type type,
     const grpc_channel_args *args) {
-  return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
+  // Add channel arg containing the server URI.
+  grpc_arg arg;
+  arg.type = GRPC_ARG_STRING;
+  arg.key = GRPC_ARG_SERVER_URI;
+  arg.value.string = (char *)target;
+  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
+  grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
+                                              GRPC_CLIENT_CHANNEL, NULL);
+  grpc_channel_args_destroy(new_args);
+  return channel;
 }
 
 static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -90,19 +99,14 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
   GPR_ASSERT(reserved == NULL);
   grpc_client_channel_factory *factory =
       (grpc_client_channel_factory *)&client_channel_factory;
-  // Add channel args containing the server name and client channel factory.
-  grpc_arg new_args[2];
-  new_args[0].type = GRPC_ARG_STRING;
-  new_args[0].key = GRPC_ARG_SERVER_URI;
-  new_args[0].value.string = (char *)target;
-  new_args[1] = grpc_client_channel_factory_create_channel_arg(factory);
-  grpc_channel_args *args_copy =
-      grpc_channel_args_copy_and_add(args, new_args, GPR_ARRAY_SIZE(new_args));
+  // Add channel arg containing the client channel factory.
+  grpc_arg arg = grpc_client_channel_factory_create_channel_arg(factory);
+  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
   // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
-      &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
+      &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
   // Clean up.
-  grpc_channel_args_destroy(args_copy);
+  grpc_channel_args_destroy(new_args);
   grpc_client_channel_factory_unref(&exec_ctx, factory);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel != NULL ? channel : grpc_lame_client_channel_create(
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 2474f544cf..9b6d3819b6 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -89,7 +89,16 @@ static grpc_channel *client_channel_factory_create_channel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const char *target, grpc_client_channel_type type,
     const grpc_channel_args *args) {
-  return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
+  // Add channel arg containing the server URI.
+  grpc_arg arg;
+  arg.type = GRPC_ARG_STRING;
+  arg.key = GRPC_ARG_SERVER_URI;
+  arg.value.string = (char *)target;
+  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
+  grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
+                                              GRPC_CLIENT_CHANNEL, NULL);
+  grpc_channel_args_destroy(new_args);
+  return channel;
 }
 
 static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -137,14 +146,11 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
                               "grpc_secure_channel_create");
   f->security_connector = security_connector;
-  // Add channel args containing the server name, client channel
-  // factory, and security connector.
-  grpc_arg new_args[3];
-  new_args[0].type = GRPC_ARG_STRING;
-  new_args[0].key = GRPC_ARG_SERVER_URI;
-  new_args[0].value.string = (char *)target;
-  new_args[1] = grpc_client_channel_factory_create_channel_arg(&f->base);
-  new_args[2] = grpc_security_connector_to_arg(&security_connector->base);
+  // Add channel args containing the client channel factory and security
+  // connector.
+  grpc_arg new_args[2];
+  new_args[0] = grpc_client_channel_factory_create_channel_arg(&f->base);
+  new_args[1] = grpc_security_connector_to_arg(&security_connector->base);
   grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
       new_args_from_connector != NULL ? new_args_from_connector : args,
       new_args, GPR_ARRAY_SIZE(new_args));
-- 
GitLab


From 201db7d613e73d3324d541d0e87a860dd656ca9f Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 09:36:02 -0800
Subject: [PATCH 119/344] Eliminate redundant places where server name was
 stored.

---
 include/grpc/impl/codegen/grpc_types.h        |  2 --
 .../client_channel/http_connect_handshaker.c  | 30 ++++++++++-------
 .../client_channel/http_connect_handshaker.h  |  5 ++-
 .../ext/client_channel/resolver_registry.c    | 32 +++++++++++++------
 .../ext/client_channel/resolver_registry.h    |  4 +++
 src/core/ext/client_channel/subchannel.h      |  2 --
 .../ext/client_channel/subchannel_index.c     |  4 ---
 src/core/ext/lb_policy/grpclb/grpclb.c        | 26 +++++++--------
 .../ext/lb_policy/pick_first/pick_first.c     | 12 ++-----
 .../ext/lb_policy/round_robin/round_robin.c   | 12 ++-----
 .../ext/resolver/dns/native/dns_resolver.c    |  7 +---
 .../ext/resolver/sockaddr/sockaddr_resolver.c |  7 +---
 .../chttp2/client/chttp2_connector.c          | 11 ++-----
 .../chttp2/client/chttp2_connector.h          |  3 +-
 .../chttp2/client/insecure/channel_create.c   |  3 +-
 .../client/secure/secure_channel_create.c     |  2 +-
 test/core/end2end/fake_resolver.c             |  7 +---
 17 files changed, 74 insertions(+), 95 deletions(-)

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index c86f7ecd7d..f2ee5af78c 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -215,8 +215,6 @@ typedef struct {
 #define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
 /** Server URI. Not intended for external use. */
 #define GRPC_ARG_SERVER_URI "grpc.server_uri"
-/** Server name. Not intended for external use. */
-#define GRPC_ARG_SERVER_NAME "grpc.server_name"
 /** Resolved addresses in a form used by the LB policy.
     Not intended for external use. */
 #define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 572af52dfd..6dc68eaaea 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/http/format_request.h"
@@ -51,7 +52,6 @@ typedef struct http_connect_handshaker {
   grpc_handshaker base;
 
   char* proxy_server;
-  char* server_name;
 
   gpr_refcount refcount;
   gpr_mu mu;
@@ -86,7 +86,6 @@ static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
       gpr_free(handshaker->read_buffer_to_destroy);
     }
     gpr_free(handshaker->proxy_server);
-    gpr_free(handshaker->server_name);
     grpc_slice_buffer_destroy(&handshaker->write_buffer);
     grpc_http_parser_destroy(&handshaker->http_parser);
     grpc_http_response_destroy(&handshaker->http_response);
@@ -265,18 +264,27 @@ static void http_connect_handshaker_do_handshake(
     grpc_tcp_server_acceptor* acceptor, grpc_closure* on_handshake_done,
     grpc_handshaker_args* args) {
   http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
-  gpr_mu_lock(&handshaker->mu);
+  // Get server name from channel args.
+  const grpc_arg* arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
+  GPR_ASSERT(arg != NULL);
+  GPR_ASSERT(arg->type == GRPC_ARG_STRING);
+  char *canonical_uri =
+      grpc_resolver_factory_add_default_prefix_if_needed(arg->value.string);
+  grpc_uri* uri = grpc_uri_parse(canonical_uri, 1);
+  char* server_name = uri->path;
+  if (server_name[0] == '/') ++server_name;
   // Save state in the handshaker object.
+  gpr_mu_lock(&handshaker->mu);
   handshaker->args = args;
   handshaker->on_handshake_done = on_handshake_done;
   // Send HTTP CONNECT request.
-  gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s",
-          handshaker->server_name, handshaker->proxy_server);
+  gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s", server_name,
+          handshaker->proxy_server);
   grpc_httpcli_request request;
   memset(&request, 0, sizeof(request));
-  request.host = handshaker->proxy_server;
+  request.host = server_name;
   request.http.method = "CONNECT";
-  request.http.path = handshaker->server_name;
+  request.http.path = server_name;
   request.handshaker = &grpc_httpcli_plaintext;
   grpc_slice request_slice = grpc_httpcli_format_connect_request(&request);
   grpc_slice_buffer_add(&handshaker->write_buffer, request_slice);
@@ -285,23 +293,23 @@ static void http_connect_handshaker_do_handshake(
   grpc_endpoint_write(exec_ctx, args->endpoint, &handshaker->write_buffer,
                       &handshaker->request_done_closure);
   gpr_mu_unlock(&handshaker->mu);
+  // Clean up.
+  gpr_free(canonical_uri);
+  grpc_uri_destroy(uri);
 }
 
 static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
     http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
     http_connect_handshaker_do_handshake};
 
-grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
-                                                     const char* server_name) {
+grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) {
   GPR_ASSERT(proxy_server != NULL);
-  GPR_ASSERT(server_name != NULL);
   http_connect_handshaker* handshaker = gpr_malloc(sizeof(*handshaker));
   memset(handshaker, 0, sizeof(*handshaker));
   grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base);
   gpr_mu_init(&handshaker->mu);
   gpr_ref_init(&handshaker->refcount, 1);
   handshaker->proxy_server = gpr_strdup(proxy_server);
-  handshaker->server_name = gpr_strdup(server_name);
   grpc_slice_buffer_init(&handshaker->write_buffer);
   grpc_closure_init(&handshaker->request_done_closure, on_write_done,
                     handshaker);
diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/client_channel/http_connect_handshaker.h
index c689df2b2b..ea293852e6 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.h
+++ b/src/core/ext/client_channel/http_connect_handshaker.h
@@ -36,9 +36,8 @@
 
 #include "src/core/lib/channel/handshaker.h"
 
-/// Does NOT take ownership of \a proxy_server or \a server_name.
-grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
-                                                     const char* server_name);
+/// Does NOT take ownership of \a proxy_server.
+grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server);
 
 /// Returns the name of the proxy to use, or NULL if no proxy is configured.
 /// Caller takes ownership of result.
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c
index d0f0fc3f33..2b62b976a9 100644
--- a/src/core/ext/client_channel/resolver_registry.c
+++ b/src/core/ext/client_channel/resolver_registry.c
@@ -109,8 +109,8 @@ static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) {
 }
 
 static grpc_resolver_factory *resolve_factory(const char *target,
-                                              grpc_uri **uri) {
-  char *tmp;
+                                              grpc_uri **uri,
+                                              char **canonical_target) {
   grpc_resolver_factory *factory = NULL;
 
   GPR_ASSERT(uri != NULL);
@@ -118,15 +118,15 @@ static grpc_resolver_factory *resolve_factory(const char *target,
   factory = lookup_factory_by_uri(*uri);
   if (factory == NULL) {
     grpc_uri_destroy(*uri);
-    gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target);
-    *uri = grpc_uri_parse(tmp, 1);
+    gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target);
+    *uri = grpc_uri_parse(*canonical_target, 1);
     factory = lookup_factory_by_uri(*uri);
     if (factory == NULL) {
       grpc_uri_destroy(grpc_uri_parse(target, 0));
-      grpc_uri_destroy(grpc_uri_parse(tmp, 0));
-      gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, tmp);
+      grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
+      gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
+              *canonical_target);
     }
-    gpr_free(tmp);
   }
   return factory;
 }
@@ -134,7 +134,9 @@ static grpc_resolver_factory *resolve_factory(const char *target,
 grpc_resolver *grpc_resolver_create(const char *target,
                                     const grpc_channel_args *args) {
   grpc_uri *uri = NULL;
-  grpc_resolver_factory *factory = resolve_factory(target, &uri);
+  char *canonical_target = NULL;
+  grpc_resolver_factory *factory =
+      resolve_factory(target, &uri, &canonical_target);
   grpc_resolver *resolver;
   grpc_resolver_args resolver_args;
   memset(&resolver_args, 0, sizeof(resolver_args));
@@ -142,13 +144,25 @@ grpc_resolver *grpc_resolver_create(const char *target,
   resolver_args.args = args;
   resolver = grpc_resolver_factory_create_resolver(factory, &resolver_args);
   grpc_uri_destroy(uri);
+  gpr_free(canonical_target);
   return resolver;
 }
 
 char *grpc_get_default_authority(const char *target) {
   grpc_uri *uri = NULL;
-  grpc_resolver_factory *factory = resolve_factory(target, &uri);
+  char *canonical_target = NULL;
+  grpc_resolver_factory *factory =
+      resolve_factory(target, &uri, &canonical_target);
   char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
   grpc_uri_destroy(uri);
+  gpr_free(canonical_target);
   return authority;
 }
+
+char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target) {
+  grpc_uri *uri = NULL;
+  char *canonical_target = NULL;
+  resolve_factory(target, &uri, &canonical_target);
+  grpc_uri_destroy(uri);
+  return canonical_target == NULL ? gpr_strdup(target) : canonical_target;
+}
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
index 2a95a669f0..24678bc05f 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/client_channel/resolver_registry.h
@@ -71,4 +71,8 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
     representing the default authority to pass from a client. */
 char *grpc_get_default_authority(const char *target);
 
+/** Returns a newly allocated string containing \a target, adding the
+    default prefix if needed. */
+char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target);
+
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index 10bae620df..24aa9f73dc 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -164,8 +164,6 @@ struct grpc_subchannel_args {
   size_t filter_count;
   /** Channel arguments to be supplied to the newly created channel */
   const grpc_channel_args *args;
-  /** Server name */
-  const char *server_name;
   /** Address to connect to */
   grpc_resolved_address *addr;
 };
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
index 227013a7d7..a1ba5e945c 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/client_channel/subchannel_index.c
@@ -86,7 +86,6 @@ static grpc_subchannel_key *create_key(
   } else {
     k->args.filters = NULL;
   }
-  k->args.server_name = gpr_strdup(args->server_name);
   k->args.addr = gpr_malloc(sizeof(grpc_resolved_address));
   k->args.addr->len = args->addr->len;
   if (k->args.addr->len > 0) {
@@ -113,8 +112,6 @@ static int subchannel_key_compare(grpc_subchannel_key *a,
   if (c != 0) return c;
   c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
   if (c != 0) return c;
-  c = strcmp(a->args.server_name, b->args.server_name);
-  if (c != 0) return c;
   if (a->args.addr->len) {
     c = memcmp(a->args.addr->addr, b->args.addr->addr, a->args.addr->len);
     if (c != 0) return c;
@@ -132,7 +129,6 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
   grpc_connector_unref(exec_ctx, k->connector);
   gpr_free((grpc_channel_args *)k->args.filters);
   grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
-  gpr_free((void *)k->args.server_name);
   gpr_free(k->args.addr);
   gpr_free(k);
 }
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index da1cf65060..b7c06a55bb 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -743,12 +743,6 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
 static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
                                   grpc_lb_policy_factory *factory,
                                   grpc_lb_policy_args *args) {
-  /* Get server name. */
-  const grpc_arg *arg =
-      grpc_channel_args_find(args->args, GRPC_ARG_SERVER_NAME);
-  const char *server_name =
-      arg != NULL && arg->type == GRPC_ARG_STRING ? arg->value.string : NULL;
-
   /* Count the number of gRPC-LB addresses. There must be at least one.
    * TODO(roth): For now, we ignore non-balancer addresses, but in the
    * future, we may change the behavior such that we fall back to using
@@ -756,7 +750,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
    * time, this should be changed to allow a list with no balancer addresses,
    * since the resolver might fail to return a balancer address even when
    * this is the right LB policy to use. */
-  arg = grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
+  const grpc_arg *arg =
+      grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
   GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_grpclb_addrs = 0;
@@ -768,13 +763,19 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy));
   memset(glb_policy, 0, sizeof(*glb_policy));
 
+  /* Get server name. */
+  arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
+  GPR_ASSERT(arg != NULL);
+  GPR_ASSERT(arg->type == GRPC_ARG_STRING);
+  grpc_uri *uri = grpc_uri_parse(arg->value.string, 1);
+  glb_policy->server_name = gpr_strdup(uri->path);
+  grpc_uri_destroy(uri);
+
   /* All input addresses in addresses come from a resolver that claims
    * they are LB services. It's the resolver's responsibility to make sure
-   * this
-   * policy is only instantiated and used in that case.
+   * this policy is only instantiated and used in that case.
    *
    * Create a client channel over them to communicate with a LB service */
-  glb_policy->server_name = gpr_strdup(server_name);
   glb_policy->cc_factory = args->client_channel_factory;
   glb_policy->args = grpc_channel_args_copy(args->args);
   GPR_ASSERT(glb_policy->cc_factory != NULL);
@@ -824,9 +825,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
    * channel.  (The client channel factory will re-add this arg with
    * the right value.)
    */
-  static const char *keys_to_remove[] = {GRPC_ARG_LB_POLICY_NAME,
-                                         GRPC_ARG_LB_ADDRESSES,
-                                         GRPC_ARG_SERVER_URI};
+  static const char *keys_to_remove[] = {
+      GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
   grpc_channel_args *new_args = grpc_channel_args_copy_and_remove(
       args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove));
   glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index c69f773e78..b9cfe6b5c0 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -438,15 +438,10 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
                                          grpc_lb_policy_args *args) {
   GPR_ASSERT(args->client_channel_factory != NULL);
 
-  /* Get server name. */
-  const grpc_arg *arg =
-      grpc_channel_args_find(args->args, GRPC_ARG_SERVER_NAME);
-  const char *server_name =
-      arg != NULL && arg->type == GRPC_ARG_STRING ? arg->value.string : NULL;
-
   /* Find the number of backend addresses. We ignore balancer
    * addresses, since we don't know how to handle them. */
-  arg = grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
+  const grpc_arg *arg =
+      grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
   GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_addrs = 0;
@@ -472,9 +467,6 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
     }
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    /* server_name will be copied as part of the subchannel creation. This makes
-     * the copying of server_name (a borrowed pointer) OK. */
-    sc_args.server_name = server_name;
     sc_args.addr = &addresses->addresses[i].address;
     sc_args.args = args->args;
 
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 59f84054c4..f0305473d2 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -703,15 +703,10 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
                                           grpc_lb_policy_args *args) {
   GPR_ASSERT(args->client_channel_factory != NULL);
 
-  /* Get server name. */
-  const grpc_arg *arg =
-      grpc_channel_args_find(args->args, GRPC_ARG_SERVER_NAME);
-  const char *server_name =
-      arg != NULL && arg->type == GRPC_ARG_STRING ? arg->value.string : NULL;
-
   /* Find the number of backend addresses. We ignore balancer
    * addresses, since we don't know how to handle them. */
-  arg = grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
+  const grpc_arg *arg =
+      grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
   GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER);
   grpc_lb_addresses *addresses = arg->value.pointer.p;
   size_t num_addrs = 0;
@@ -734,9 +729,6 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
     if (addresses->addresses[i].is_balancer) continue;
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    /* server_name will be copied as part of the subchannel creation. This makes
-     * the copying of server_name (a borrowed pointer) OK. */
-    sc_args.server_name = server_name;
     sc_args.addr = &addresses->addresses[i].address;
     sc_args.args = args->args;
 
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 15476f5792..a7392e14ad 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -264,12 +264,7 @@ static grpc_resolver *dns_create(grpc_resolver_args *args,
   grpc_resolver_init(&r->base, &dns_resolver_vtable);
   r->name_to_resolve = proxy_name == NULL ? gpr_strdup(path) : proxy_name;
   r->default_port = gpr_strdup(default_port);
-  grpc_arg server_name_arg;
-  server_name_arg.type = GRPC_ARG_STRING;
-  server_name_arg.key = GRPC_ARG_SERVER_NAME;
-  server_name_arg.value.string = (char *)path;
-  r->channel_args =
-      grpc_channel_args_copy_and_add(args->args, &server_name_arg, 1);
+  r->channel_args = grpc_channel_args_copy(args->args);
   gpr_backoff_init(&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS,
                    GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER,
                    GRPC_DNS_RECONNECT_JITTER,
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 26a650aadd..0a9b1aa49a 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -198,12 +198,7 @@ static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
   sockaddr_resolver *r = gpr_malloc(sizeof(sockaddr_resolver));
   memset(r, 0, sizeof(*r));
   r->addresses = addresses;
-  grpc_arg server_name_arg;
-  server_name_arg.type = GRPC_ARG_STRING;
-  server_name_arg.key = GRPC_ARG_SERVER_NAME;
-  server_name_arg.value.string = args->uri->path;
-  r->channel_args =
-      grpc_channel_args_copy_and_add(args->args, &server_name_arg, 1);
+  r->channel_args = grpc_channel_args_copy(args->args);
   gpr_mu_init(&r->mu);
   grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
   return &r->base;
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 58a6877b9b..114bb07222 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -58,7 +58,6 @@ typedef struct {
   bool shutdown;
   bool connecting;
 
-  char *server_name;
   grpc_chttp2_add_handshakers_func add_handshakers;
   void *add_handshakers_user_data;
 
@@ -89,7 +88,6 @@ static void chttp2_connector_unref(grpc_exec_ctx *exec_ctx,
     // If handshaking is not yet in progress, destroy the endpoint.
     // Otherwise, the handshaker will do this for us.
     if (c->endpoint != NULL) grpc_endpoint_destroy(exec_ctx, c->endpoint);
-    gpr_free(c->server_name);
     gpr_free(c);
   }
 }
@@ -155,9 +153,8 @@ static void start_handshake_locked(grpc_exec_ctx *exec_ctx,
   c->handshake_mgr = grpc_handshake_manager_create();
   char *proxy_name = grpc_get_http_proxy_server();
   if (proxy_name != NULL) {
-    grpc_handshake_manager_add(
-        c->handshake_mgr,
-        grpc_http_connect_handshaker_create(proxy_name, c->server_name));
+    grpc_handshake_manager_add(c->handshake_mgr,
+                               grpc_http_connect_handshaker_create(proxy_name));
     gpr_free(proxy_name);
   }
   if (c->add_handshakers != NULL) {
@@ -254,15 +251,13 @@ static const grpc_connector_vtable chttp2_connector_vtable = {
     chttp2_connector_connect};
 
 grpc_connector *grpc_chttp2_connector_create(
-    grpc_exec_ctx *exec_ctx, const char *server_name,
-    grpc_chttp2_add_handshakers_func add_handshakers,
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers,
     void *add_handshakers_user_data) {
   chttp2_connector *c = gpr_malloc(sizeof(*c));
   memset(c, 0, sizeof(*c));
   c->base.vtable = &chttp2_connector_vtable;
   gpr_mu_init(&c->mu);
   gpr_ref_init(&c->refs, 1);
-  c->server_name = gpr_strdup(server_name);
   c->add_handshakers = add_handshakers;
   c->add_handshakers_user_data = add_handshakers_user_data;
   return &c->base;
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h
index c57fb1a9a0..58eba22417 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.h
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h
@@ -45,8 +45,7 @@ typedef void (*grpc_chttp2_add_handshakers_func)(
 /// If \a add_handshakers is non-NULL, it will be called with
 /// \a add_handshakers_user_data to add handshakers.
 grpc_connector* grpc_chttp2_connector_create(
-    grpc_exec_ctx* exec_ctx, const char* server_name,
-    grpc_chttp2_add_handshakers_func add_handshakers,
+    grpc_exec_ctx* exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers,
     void* add_handshakers_user_data);
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 90d3503959..a0d0652ce7 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -54,8 +54,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const grpc_subchannel_args *args) {
   grpc_connector *connector = grpc_chttp2_connector_create(
-      exec_ctx, args->server_name, NULL /* add_handshakers */,
-      NULL /* user_data */);
+      exec_ctx, NULL /* add_handshakers */, NULL /* user_data */);
   grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
   grpc_connector_unref(exec_ctx, connector);
   return s;
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 9b6d3819b6..f35439cd44 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -79,7 +79,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
     const grpc_subchannel_args *args) {
   client_channel_factory *f = (client_channel_factory *)cc_factory;
   grpc_connector *connector = grpc_chttp2_connector_create(
-      exec_ctx, args->server_name, add_handshakers, f->security_connector);
+      exec_ctx, add_handshakers, f->security_connector);
   grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
   grpc_connector_unref(exec_ctx, connector);
   return s;
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 865b55de4d..7380dccd80 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -181,12 +181,7 @@ static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
   // Instantiate resolver.
   fake_resolver* r = gpr_malloc(sizeof(fake_resolver));
   memset(r, 0, sizeof(*r));
-  grpc_arg server_name_arg;
-  server_name_arg.type = GRPC_ARG_STRING;
-  server_name_arg.key = GRPC_ARG_SERVER_NAME;
-  server_name_arg.value.string = args->uri->path;
-  r->channel_args =
-      grpc_channel_args_copy_and_add(args->args, &server_name_arg, 1);
+  r->channel_args = grpc_channel_args_copy(args->args);
   r->addresses = addresses;
   gpr_mu_init(&r->mu);
   grpc_resolver_init(&r->base, &fake_resolver_vtable);
-- 
GitLab


From be5e3ca5057b93e7958c9bc757c5299b9debacee Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 09:58:20 -0800
Subject: [PATCH 120/344] Move internal channel arg definitions out of public
 headers.

---
 include/grpc/impl/codegen/grpc_types.h               | 12 ++----------
 src/core/ext/client_channel/client_channel.h         |  3 +++
 src/core/ext/client_channel/client_channel_factory.h |  3 +++
 .../ext/client_channel/http_connect_handshaker.c     |  1 +
 src/core/ext/client_channel/lb_policy_factory.h      |  3 +++
 src/core/ext/lb_policy/grpclb/grpclb.c               |  1 +
 6 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index f2ee5af78c..4471ccf745 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -206,22 +206,14 @@ typedef struct {
 /** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */
 #define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport"
 /** If non-zero, a pointer to a buffer pool (use grpc_resource_quota_arg_vtable
-   to fetch an appropriate pointer arg vtable */
+   to fetch an appropriate pointer arg vtable) */
 #define GRPC_ARG_RESOURCE_QUOTA "grpc.resource_quota"
-/** Service config data, to be passed to subchannels.
-    Not intended for external use. */
+/** Service config data in JSON form. Not intended for use outside of tests. */
 #define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
 /** LB policy name. */
 #define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
-/** Server URI. Not intended for external use. */
-#define GRPC_ARG_SERVER_URI "grpc.server_uri"
-/** Resolved addresses in a form used by the LB policy.
-    Not intended for external use. */
-#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
 /** The grpc_socket_mutator instance that set the socket options. A pointer. */
 #define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
-/** Client channel factory.  Not intended for external use. */
-#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory"
 /** \} */
 
 /** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/src/core/ext/client_channel/client_channel.h b/src/core/ext/client_channel/client_channel.h
index 9ba012865c..f02587d0c1 100644
--- a/src/core/ext/client_channel/client_channel.h
+++ b/src/core/ext/client_channel/client_channel.h
@@ -38,6 +38,9 @@
 #include "src/core/ext/client_channel/resolver.h"
 #include "src/core/lib/channel/channel_stack.h"
 
+// Channel arg key for server URI string.
+#define GRPC_ARG_SERVER_URI "grpc.server_uri"
+
 /* A client channel is a channel that begins disconnected, and can connect
    to some endpoint on demand. If that endpoint disconnects, it will be
    connected to again later.
diff --git a/src/core/ext/client_channel/client_channel_factory.h b/src/core/ext/client_channel/client_channel_factory.h
index e7ad918881..bf2764b537 100644
--- a/src/core/ext/client_channel/client_channel_factory.h
+++ b/src/core/ext/client_channel/client_channel_factory.h
@@ -39,6 +39,9 @@
 #include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_stack.h"
 
+// Channel arg key for client channel factory.
+#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory"
+
 typedef struct grpc_client_channel_factory grpc_client_channel_factory;
 typedef struct grpc_client_channel_factory_vtable
     grpc_client_channel_factory_vtable;
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 6dc68eaaea..cf10dfb3e9 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
diff --git a/src/core/ext/client_channel/lb_policy_factory.h b/src/core/ext/client_channel/lb_policy_factory.h
index e2b8080a32..79b3dee259 100644
--- a/src/core/ext/client_channel/lb_policy_factory.h
+++ b/src/core/ext/client_channel/lb_policy_factory.h
@@ -40,6 +40,9 @@
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 
+// Channel arg key for grpc_lb_addresses.
+#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
+
 typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
 typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
 
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index b7c06a55bb..38eebdc758 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -106,6 +106,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+#include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/client_channel_factory.h"
 #include "src/core/ext/client_channel/lb_policy_factory.h"
 #include "src/core/ext/client_channel/lb_policy_registry.h"
-- 
GitLab


From bcd54cdf7d47decc8aebfc469fe1bd46ec6e9d55 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 10:02:35 -0800
Subject: [PATCH 121/344] Fix sockaddr_resolver_test.

---
 test/core/client_channel/resolvers/sockaddr_resolver_test.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index ebf311ab83..5ef248f036 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -49,11 +49,6 @@ typedef struct on_resolution_arg {
 
 void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   on_resolution_arg *res = arg;
-  const grpc_arg *channel_arg =
-      grpc_channel_args_find(res->resolver_result, GRPC_ARG_SERVER_NAME);
-  GPR_ASSERT(channel_arg != NULL);
-  GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
-  GPR_ASSERT(strcmp(res->expected_server_name, channel_arg->value.string) == 0);
   grpc_channel_args_destroy(res->resolver_result);
 }
 
-- 
GitLab


From aa1cd147291cb57665eccf2dc9baeaa39184f0ba Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 10:24:59 -0800
Subject: [PATCH 122/344] Clean up C++ filter API.

---
 src/core/lib/channel/channel_stack.h   |  7 +++++
 src/cpp/common/channel_filter.h        | 40 +++++++++++---------------
 test/cpp/common/channel_filter_test.cc | 17 ++++++++---
 3 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 5d064c5695..d9d3a85233 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -34,6 +34,13 @@
 #ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H
 #define GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H
 
+//////////////////////////////////////////////////////////////////////////////
+// IMPORTANT NOTE:
+//
+// When you update this API, please make the corresponding changes to
+// the C++ API in src/cpp/common/channel_filter.{h,cc}
+//////////////////////////////////////////////////////////////////////////////
+
 /* A channel filter defines how operations on a channel are implemented.
    Channel filters are chained together to create full channels, and if those
    chains are linear, then channel stacks provide a mechanism to minimize
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 107522ea04..93efe0fc3b 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -217,14 +217,13 @@ class TransportStreamOp {
 class ChannelData {
  public:
   virtual ~ChannelData() {
-    if (peer_) gpr_free((void *)peer_);
   }
 
   /// Initializes the call data.
-  virtual grpc_error *Init() { return GRPC_ERROR_NONE; }
-
-  /// Caller does NOT take ownership of result.
-  const char *peer() const { return peer_; }
+  virtual grpc_error *Init(grpc_exec_ctx *exec_ctx,
+                           grpc_channel_element_args *args) {
+    return GRPC_ERROR_NONE;
+  }
 
   // TODO(roth): Find a way to avoid passing elem into these methods.
 
@@ -235,11 +234,7 @@ class ChannelData {
                        const grpc_channel_info *channel_info);
 
  protected:
-  /// Takes ownership of \a peer.
-  ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {}
-
- private:
-  const char *peer_;
+  ChannelData() {}
 };
 
 /// Represents call data.
@@ -248,7 +243,10 @@ class CallData {
   virtual ~CallData() {}
 
   /// Initializes the call data.
-  virtual grpc_error *Init() { return GRPC_ERROR_NONE; }
+  virtual grpc_error *Init(grpc_exec_ctx *exec_ctx, ChannelData *channel_data,
+                           grpc_channel_element_args *args) {
+    return GRPC_ERROR_NONE;
+  }
 
   // TODO(roth): Find a way to avoid passing elem into these methods.
 
@@ -266,7 +264,7 @@ class CallData {
   virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem);
 
  protected:
-  explicit CallData(const ChannelData &) {}
+  CallData() {}
 };
 
 namespace internal {
@@ -282,14 +280,8 @@ class ChannelFilter final {
   static grpc_error *InitChannelElement(grpc_exec_ctx *exec_ctx,
                                         grpc_channel_element *elem,
                                         grpc_channel_element_args *args) {
-    const char *peer =
-        args->optional_transport
-            ? grpc_transport_get_peer(exec_ctx, args->optional_transport)
-            : nullptr;
-    // Construct the object in the already-allocated memory.
-    ChannelDataType *channel_data =
-        new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
-    return channel_data->Init();
+    ChannelDataType *channel_data = new (elem->channel_data) ChannelDataType();
+    return channel_data->Init(exec_ctx, args);
   }
 
   static void DestroyChannelElement(grpc_exec_ctx *exec_ctx,
@@ -317,11 +309,11 @@ class ChannelFilter final {
   static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      grpc_call_element_args *args) {
-    const ChannelDataType &channel_data =
-        *(ChannelDataType *)elem->channel_data;
+    ChannelDataType *channel_data =
+        (ChannelDataType *)elem->channel_data;
     // Construct the object in the already-allocated memory.
-    CallDataType *call_data = new (elem->call_data) CallDataType(channel_data);
-    return call_data->Init();
+    CallDataType *call_data = new (elem->call_data) CallDataType();
+    return call_data->Init(exec_ctx, channel_data, args);
   }
 
   static void DestroyCallElement(grpc_exec_ctx *exec_ctx,
diff --git a/test/cpp/common/channel_filter_test.cc b/test/cpp/common/channel_filter_test.cc
index 600a953d82..26d341c2b9 100644
--- a/test/cpp/common/channel_filter_test.cc
+++ b/test/cpp/common/channel_filter_test.cc
@@ -41,14 +41,23 @@ namespace testing {
 
 class MyChannelData : public ChannelData {
  public:
-  MyChannelData(const grpc_channel_args& args, const char* peer)
-      : ChannelData(args, peer) {}
+  MyChannelData() {}
+
+  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) {
+    (void)args->channel_args;  // Make sure field is available.
+    return GRPC_ERROR_NONE;
+  }
 };
 
 class MyCallData : public CallData {
  public:
-  explicit MyCallData(const ChannelData& channel_data)
-      : CallData(channel_data) {}
+  MyCallData() {}
+
+  grpc_error *Init(grpc_exec_ctx *exec_ctx, ChannelData *channel_data,
+                   grpc_call_element_args *args) {
+    (void)args->path;  // Make sure field is available.
+    return GRPC_ERROR_NONE;
+  }
 };
 
 // This test ensures that when we make changes to the filter API in
-- 
GitLab


From 42663fb20ec0dc275dbc290c32969f48f5df6f7c Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 12 Dec 2016 10:51:01 -0800
Subject: [PATCH 123/344] Fix bug.

---
 src/cpp/common/channel_filter.h        | 2 +-
 test/cpp/common/channel_filter_test.cc | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 93efe0fc3b..f4652cee77 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -244,7 +244,7 @@ class CallData {
 
   /// Initializes the call data.
   virtual grpc_error *Init(grpc_exec_ctx *exec_ctx, ChannelData *channel_data,
-                           grpc_channel_element_args *args) {
+                           grpc_call_element_args *args) {
     return GRPC_ERROR_NONE;
   }
 
diff --git a/test/cpp/common/channel_filter_test.cc b/test/cpp/common/channel_filter_test.cc
index 26d341c2b9..0859cc024b 100644
--- a/test/cpp/common/channel_filter_test.cc
+++ b/test/cpp/common/channel_filter_test.cc
@@ -43,7 +43,8 @@ class MyChannelData : public ChannelData {
  public:
   MyChannelData() {}
 
-  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) {
+  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args)
+      override {
     (void)args->channel_args;  // Make sure field is available.
     return GRPC_ERROR_NONE;
   }
@@ -54,7 +55,7 @@ class MyCallData : public CallData {
   MyCallData() {}
 
   grpc_error *Init(grpc_exec_ctx *exec_ctx, ChannelData *channel_data,
-                   grpc_call_element_args *args) {
+                   grpc_call_element_args *args) override {
     (void)args->path;  // Make sure field is available.
     return GRPC_ERROR_NONE;
   }
-- 
GitLab


From 8c57917f56bc7af695f2c92f8e5678160da4276e Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Mon, 12 Dec 2016 13:58:15 -0800
Subject: [PATCH 124/344] fixed feedback from review

---
 test/http2_test/http2_base_server.py    | 65 +++++++++++++------------
 test/http2_test/http2_test_server.py    | 36 +++++++-------
 test/http2_test/test_goaway.py          | 10 ++--
 test/http2_test/test_max_streams.py     |  9 ++--
 test/http2_test/test_ping.py            |  5 +-
 test/http2_test/test_rst_during_data.py |  1 -
 6 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index cbc26b11b1..4d356d4385 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -1,19 +1,19 @@
-import struct
-import messages_pb2
 import logging
+import messages_pb2
+import struct
 
-from twisted.internet.protocol import Protocol
-from twisted.internet import reactor
-from h2.connection import H2Connection
-from h2.events import RequestReceived, DataReceived, WindowUpdated, RemoteSettingsChanged, PingAcknowledged
-from h2.exceptions import ProtocolError
+import h2
+import h2.connection
+import twisted
+import twisted.internet
+import twisted.internet.protocol
 
-READ_CHUNK_SIZE = 16384
-GRPC_HEADER_SIZE = 5
+_READ_CHUNK_SIZE = 16384
+_GRPC_HEADER_SIZE = 5
 
-class H2ProtocolBaseServer(Protocol):
+class H2ProtocolBaseServer(twisted.internet.protocol.Protocol):
   def __init__(self):
-    self._conn = H2Connection(client_side=False)
+    self._conn = h2.connection.H2Connection(client_side=False)
     self._recv_buffer = {}
     self._handlers = {}
     self._handlers['ConnectionMade'] = self.on_connection_made_default
@@ -43,34 +43,35 @@ class H2ProtocolBaseServer(Protocol):
     self.transport.write(self._conn.data_to_send())
 
   def on_connection_lost(self, reason):
-    logging.info('Disconnected %s'%reason)
-    reactor.callFromThread(reactor.stop)
+    logging.info('Disconnected %s' % reason)
+    twisted.internet.reactor.callFromThread(twisted.internet.reactor.stop)
 
   def dataReceived(self, data):
     try:
       events = self._conn.receive_data(data)
-    except ProtocolError:
+    except h2.exceptions.ProtocolError:
       # this try/except block catches exceptions due to race between sending
       # GOAWAY and processing a response in flight.
       return
     if self._conn.data_to_send:
       self.transport.write(self._conn.data_to_send())
     for event in events:
-      if isinstance(event, RequestReceived) and self._handlers.has_key('RequestReceived'):
-        logging.info('RequestReceived Event for stream: %d'%event.stream_id)
+      if isinstance(event, h2.events.RequestReceived) and self._handlers.has_key('RequestReceived'):
+        logging.info('RequestReceived Event for stream: %d' % event.stream_id)
         self._handlers['RequestReceived'](event)
-      elif isinstance(event, DataReceived) and self._handlers.has_key('DataReceived'):
-        logging.info('DataReceived Event for stream: %d'%event.stream_id)
+      elif isinstance(event, h2.events.DataReceived) and self._handlers.has_key('DataReceived'):
+        logging.info('DataReceived Event for stream: %d' % event.stream_id)
         self._handlers['DataReceived'](event)
-      elif isinstance(event, WindowUpdated) and self._handlers.has_key('WindowUpdated'):
-        logging.info('WindowUpdated Event for stream: %d'%event.stream_id)
+      elif isinstance(event, h2.events.WindowUpdated) and self._handlers.has_key('WindowUpdated'):
+        logging.info('WindowUpdated Event for stream: %d' % event.stream_id)
         self._handlers['WindowUpdated'](event)
-      elif isinstance(event, PingAcknowledged) and self._handlers.has_key('PingAcknowledged'):
+      elif isinstance(event, h2.events.PingAcknowledged) and self._handlers.has_key('PingAcknowledged'):
         logging.info('PingAcknowledged Event')
         self._handlers['PingAcknowledged'](event)
     self.transport.write(self._conn.data_to_send())
 
   def on_ping_acknowledged_default(self, event):
+    logging.info('ping acknowledged')
     self._outstanding_pings -= 1
 
   def on_data_received_default(self, event):
@@ -101,7 +102,7 @@ class H2ProtocolBaseServer(Protocol):
     self.transport.write(self._conn.data_to_send())
 
   def setup_send(self, data_to_send, stream_id):
-    logging.info('Setting up data to send for stream_id: %d'%stream_id)
+    logging.info('Setting up data to send for stream_id: %d' % stream_id)
     self._send_remaining[stream_id] = len(data_to_send)
     self._send_offset = 0
     self._data_to_send = data_to_send
@@ -116,16 +117,16 @@ class H2ProtocolBaseServer(Protocol):
       lfcw = self._conn.local_flow_control_window(stream_id)
       if lfcw == 0:
         break
-      chunk_size = min(lfcw, READ_CHUNK_SIZE)
+      chunk_size = min(lfcw, _READ_CHUNK_SIZE)
       bytes_to_send = min(chunk_size, self._send_remaining[stream_id])
-      logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d'%
+      logging.info('flow_control_window = %d. sending [%d:%d] stream_id %d' %
                     (lfcw, self._send_offset, self._send_offset + bytes_to_send,
                     stream_id))
       data = self._data_to_send[self._send_offset : self._send_offset + bytes_to_send]
       try:
         self._conn.send_data(stream_id, data, False)
-      except ProtocolError:
-        logging.info('Stream %d is closed'%stream_id)
+      except h2.exceptions.ProtocolError:
+        logging.info('Stream %d is closed' % stream_id)
         break
       self._send_remaining[stream_id] -= bytes_to_send
       self._send_offset += bytes_to_send
@@ -133,6 +134,7 @@ class H2ProtocolBaseServer(Protocol):
         self._handlers['SendDone'](stream_id)
 
   def default_ping(self):
+    logging.info('sending ping')
     self._outstanding_pings += 1
     self._conn.ping(b'\x00'*8)
     self.transport.write(self._conn.data_to_send())
@@ -141,9 +143,11 @@ class H2ProtocolBaseServer(Protocol):
     if self._stream_status[stream_id]:
       self._stream_status[stream_id] = False
       self.default_send_trailer(stream_id)
+    else:
+      logging.error('Stream %d is already closed' % stream_id)
 
   def default_send_trailer(self, stream_id):
-    logging.info('Sending trailer for stream id %d'%stream_id)
+    logging.info('Sending trailer for stream id %d' % stream_id)
     self._conn.send_headers(stream_id,
       headers=[ ('grpc-status', '0') ],
       end_stream=True
@@ -159,15 +163,14 @@ class H2ProtocolBaseServer(Protocol):
     return response_data
 
   def parse_received_data(self, stream_id):
-    recv_buffer = self._recv_buffer[stream_id]
     """ returns a grpc framed string of bytes containing response proto of the size
     asked in request """
+    recv_buffer = self._recv_buffer[stream_id]
     grpc_msg_size = struct.unpack('i',recv_buffer[1:5][::-1])[0]
-    if len(recv_buffer) != GRPC_HEADER_SIZE + grpc_msg_size:
-      #logging.error('not enough data to decode req proto. size = %d, needed %s'%(len(recv_buffer), 5+grpc_msg_size))
+    if len(recv_buffer) != _GRPC_HEADER_SIZE + grpc_msg_size:
       return None
     req_proto_str = recv_buffer[5:5+grpc_msg_size]
     sr = messages_pb2.SimpleRequest()
     sr.ParseFromString(req_proto_str)
-    logging.info('Parsed request for stream %d: response_size=%s'%(stream_id, sr.response_size))
+    logging.info('Parsed request for stream %d: response_size=%s' % (stream_id, sr.response_size))
     return sr
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 5270ee4255..1549d6da61 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -3,18 +3,20 @@
 """
 import argparse
 import logging
+import twisted
+import twisted.internet
+import twisted.internet.endpoints
+import twisted.internet.reactor
 
-from twisted.internet.protocol import Factory
-from twisted.internet import endpoints, reactor
 import http2_base_server
-import test_rst_after_header
-import test_rst_after_data
-import test_rst_during_data
 import test_goaway
-import test_ping
 import test_max_streams
+import test_ping
+import test_rst_after_data
+import test_rst_after_header
+import test_rst_during_data
 
-test_case_mappings = {
+_TEST_CASE_MAPPING = {
   'rst_after_header': test_rst_after_header.TestcaseRstStreamAfterHeader,
   'rst_after_data': test_rst_after_data.TestcaseRstStreamAfterData,
   'rst_during_data': test_rst_during_data.TestcaseRstStreamDuringData,
@@ -23,20 +25,20 @@ test_case_mappings = {
   'max_streams': test_max_streams.TestcaseSettingsMaxStreams,
 }
 
-class H2Factory(Factory):
+class H2Factory(twisted.internet.protocol.Factory):
   def __init__(self, testcase):
-    logging.info('In H2Factory')
+    logging.info('Creating H2Factory for new connection.')
     self._num_streams = 0
     self._testcase = testcase
 
   def buildProtocol(self, addr):
     self._num_streams += 1
-    logging.info('New Connection: %d'%self._num_streams)
-    if not test_case_mappings.has_key(self._testcase):
-      logging.error('Unknown test case: %s'%self._testcase)
+    logging.info('New Connection: %d' % self._num_streams)
+    if not _TEST_CASE_MAPPING.has_key(self._testcase):
+      logging.error('Unknown test case: %s' % self._testcase)
       assert(0)
     else:
-      t = test_case_mappings[self._testcase]
+      t = _TEST_CASE_MAPPING[self._testcase]
 
     if self._testcase == 'goaway':
       return t(self._num_streams).get_base_server()
@@ -49,9 +51,9 @@ if __name__ == "__main__":
   parser.add_argument("test")
   parser.add_argument("port")
   args = parser.parse_args()
-  if args.test not in test_case_mappings.keys():
-    logging.error('unknown test: %s'%args.test)
+  if args.test not in _TEST_CASE_MAPPING.keys():
+    logging.error('unknown test: %s' % args.test)
   else:
-    endpoint = endpoints.TCP4ServerEndpoint(reactor, int(args.port), backlog=128)
+    endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(twisted.internet.reactor, int(args.port), backlog=128)
     endpoint.listen(H2Factory(args.test))
-    reactor.run()
+    twisted.internet.reactor.run()
diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
index 7a915402b2..6deb883d4e 100644
--- a/test/http2_test/test_goaway.py
+++ b/test/http2_test/test_goaway.py
@@ -1,5 +1,6 @@
 import logging
 import time
+
 import http2_base_server
 
 class TestcaseGoaway(object):
@@ -7,7 +8,7 @@ class TestcaseGoaway(object):
     This test does the following:
       Process incoming request normally, i.e. send headers, data and trailers.
       Then send a GOAWAY frame with the stream id of the processed request.
-      It assert that the next request is made on a different TCP connection.
+      It checks that the next request is made on a different TCP connection.
   """
   def __init__(self, iteration):
     self._base_server = http2_base_server.H2ProtocolBaseServer()
@@ -22,15 +23,14 @@ class TestcaseGoaway(object):
     return self._base_server
 
   def on_connection_lost(self, reason):
-    logging.info('Disconnect received. Count %d'%self._iteration)
+    logging.info('Disconnect received. Count %d' % self._iteration)
     # _iteration == 2 => Two different connections have been used.
     if self._iteration == 2:
       self._base_server.on_connection_lost(reason)
 
   def on_send_done(self, stream_id):
     self._base_server.on_send_done_default(stream_id)
-    time.sleep(1)
-    logging.info('Sending GOAWAY for stream %d:'%stream_id)
+    logging.info('Sending GOAWAY for stream %d:' % stream_id)
     self._base_server._conn.close_connection(error_code=0, additional_data=None, last_stream_id=stream_id)
     self._base_server._stream_status[stream_id] = False
 
@@ -42,7 +42,7 @@ class TestcaseGoaway(object):
     self._base_server.on_data_received_default(event)
     sr = self._base_server.parse_received_data(event.stream_id)
     if sr:
-      logging.info('Creating response size = %s'%sr.response_size)
+      logging.info('Creating response size = %s' % sr.response_size)
       response_data = self._base_server.default_response_data(sr.response_size)
       self._ready_to_send = True
       self._base_server.setup_send(response_data, event.stream_id)
diff --git a/test/http2_test/test_max_streams.py b/test/http2_test/test_max_streams.py
index deb26770c3..10a9da3deb 100644
--- a/test/http2_test/test_max_streams.py
+++ b/test/http2_test/test_max_streams.py
@@ -1,6 +1,7 @@
+import hyperframe.frame
 import logging
+
 import http2_base_server
-from hyperframe.frame import SettingsFrame
 
 class TestcaseSettingsMaxStreams(object):
   """
@@ -18,7 +19,8 @@ class TestcaseSettingsMaxStreams(object):
   def on_connection_made(self):
     logging.info('Connection Made')
     self._base_server._conn.initiate_connection()
-    self._base_server._conn.update_settings({SettingsFrame.MAX_CONCURRENT_STREAMS: 1})
+    self._base_server._conn.update_settings(
+                  {hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1})
     self._base_server.transport.setTcpNoDelay(True)
     self._base_server.transport.write(self._base_server._conn.data_to_send())
 
@@ -26,6 +28,7 @@ class TestcaseSettingsMaxStreams(object):
     self._base_server.on_data_received_default(event)
     sr = self._base_server.parse_received_data(event.stream_id)
     if sr:
-      logging.info('Creating response of size = %s'%sr.response_size)
+      logging.info('Creating response of size = %s' % sr.response_size)
       response_data = self._base_server.default_response_data(sr.response_size)
       self._base_server.setup_send(response_data, event.stream_id)
+    # TODO (makdharma): Add assertion to check number of live streams
diff --git a/test/http2_test/test_ping.py b/test/http2_test/test_ping.py
index 2e6dadbc07..873eb4f39e 100644
--- a/test/http2_test/test_ping.py
+++ b/test/http2_test/test_ping.py
@@ -1,4 +1,5 @@
 import logging
+
 import http2_base_server
 
 class TestcasePing(object):
@@ -25,13 +26,13 @@ class TestcasePing(object):
     self._base_server.on_data_received_default(event)
     sr = self._base_server.parse_received_data(event.stream_id)
     if sr:
-      logging.info('Creating response size = %s'%sr.response_size)
+      logging.info('Creating response size = %s' % sr.response_size)
       response_data = self._base_server.default_response_data(sr.response_size)
       self._base_server.default_ping()
       self._base_server.setup_send(response_data, event.stream_id)
       self._base_server.default_ping()
 
   def on_connection_lost(self, reason):
-    logging.info('Disconnect received. Ping Count %d'%self._base_server._outstanding_pings)
+    logging.info('Disconnect received. Ping Count %d' % self._base_server._outstanding_pings)
     assert(self._base_server._outstanding_pings == 0)
     self._base_server.on_connection_lost(reason)
diff --git a/test/http2_test/test_rst_during_data.py b/test/http2_test/test_rst_during_data.py
index 105c9403bb..6767ccaf66 100644
--- a/test/http2_test/test_rst_during_data.py
+++ b/test/http2_test/test_rst_during_data.py
@@ -23,7 +23,6 @@ class TestcaseRstStreamDuringData(object):
       response_len = len(response_data)
       truncated_response_data = response_data[0:response_len/2]
       self._base_server.setup_send(truncated_response_data, event.stream_id)
-      # send reset stream
 
   def on_send_done(self, stream_id):
     self._base_server.send_reset_stream()
-- 
GitLab


From 7ba3527ffe6900a3c68059eec2220a17f6bd819c Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Mon, 12 Dec 2016 13:19:31 -0800
Subject: [PATCH 125/344] Un-namespace Python packages

Setuptools was updated and our hacky namespace-package-chickens came
back to roost. This removes the unsupported namespace package hacks.
---
 examples/python/multiplex/run_codegen.py      |  2 +-
 examples/python/route_guide/run_codegen.py    |  2 +-
 .../grpcio_health_checking/grpc/__init__.py   | 30 -------------------
 .../{grpc/health => grpc_health}/__init__.py  |  0
 .../health => grpc_health}/v1/__init__.py     |  0
 .../{grpc/health => grpc_health}/v1/health.py |  2 +-
 .../grpcio_health_checking/health_commands.py |  4 +--
 src/python/grpcio_health_checking/setup.py    |  1 -
 src/python/grpcio_tests/commands.py           |  4 +--
 src/python/grpcio_tests/setup.py              |  4 +--
 .../health_check/_health_servicer_test.py     |  6 ++--
 .../protoc_plugin/_split_definitions_test.py  |  2 +-
 .../python/grpcio_tools/grpc/__init__.py      | 30 -------------------
 .../{grpc/tools => grpc_tools}/__init__.py    |  0
 .../tools => grpc_tools}/_protoc_compiler.pyx |  2 +-
 .../{grpc/tools => grpc_tools}/command.py     |  2 +-
 .../{grpc/tools => grpc_tools}/main.cc        |  2 +-
 .../{grpc/tools => grpc_tools}/main.h         |  0
 .../{grpc/tools => grpc_tools}/protoc.py      |  2 +-
 tools/distrib/python/grpcio_tools/setup.py    |  9 +++---
 20 files changed, 21 insertions(+), 83 deletions(-)
 delete mode 100644 src/python/grpcio_health_checking/grpc/__init__.py
 rename src/python/grpcio_health_checking/{grpc/health => grpc_health}/__init__.py (100%)
 rename src/python/grpcio_health_checking/{grpc/health => grpc_health}/v1/__init__.py (100%)
 rename src/python/grpcio_health_checking/{grpc/health => grpc_health}/v1/health.py (98%)
 delete mode 100644 tools/distrib/python/grpcio_tools/grpc/__init__.py
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/__init__.py (100%)
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/_protoc_compiler.pyx (97%)
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/command.py (98%)
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/main.cc (98%)
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/main.h (100%)
 rename tools/distrib/python/grpcio_tools/{grpc/tools => grpc_tools}/protoc.py (98%)

diff --git a/examples/python/multiplex/run_codegen.py b/examples/python/multiplex/run_codegen.py
index 7922a0f5c7..89ac9c8fae 100755
--- a/examples/python/multiplex/run_codegen.py
+++ b/examples/python/multiplex/run_codegen.py
@@ -29,7 +29,7 @@
 
 """Generates protocol messages and gRPC stubs."""
 
-from grpc.tools import protoc
+from grpc_tools import protoc
 
 protoc.main(
     (
diff --git a/examples/python/route_guide/run_codegen.py b/examples/python/route_guide/run_codegen.py
index c7c6008580..3751e019c9 100644
--- a/examples/python/route_guide/run_codegen.py
+++ b/examples/python/route_guide/run_codegen.py
@@ -29,7 +29,7 @@
 
 """Runs protoc with the gRPC plugin to generate messages and gRPC stubs."""
 
-from grpc.tools import protoc
+from grpc_tools import protoc
 
 protoc.main(
     (
diff --git a/src/python/grpcio_health_checking/grpc/__init__.py b/src/python/grpcio_health_checking/grpc/__init__.py
deleted file mode 100644
index fcc7048815..0000000000
--- a/src/python/grpcio_health_checking/grpc/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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.
-
-__import__('pkg_resources').declare_namespace(__name__)
diff --git a/src/python/grpcio_health_checking/grpc/health/__init__.py b/src/python/grpcio_health_checking/grpc_health/__init__.py
similarity index 100%
rename from src/python/grpcio_health_checking/grpc/health/__init__.py
rename to src/python/grpcio_health_checking/grpc_health/__init__.py
diff --git a/src/python/grpcio_health_checking/grpc/health/v1/__init__.py b/src/python/grpcio_health_checking/grpc_health/v1/__init__.py
similarity index 100%
rename from src/python/grpcio_health_checking/grpc/health/v1/__init__.py
rename to src/python/grpcio_health_checking/grpc_health/v1/__init__.py
diff --git a/src/python/grpcio_health_checking/grpc/health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py
similarity index 98%
rename from src/python/grpcio_health_checking/grpc/health/v1/health.py
rename to src/python/grpcio_health_checking/grpc_health/v1/health.py
index 8108ac1096..0df679b0e2 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1/health.py
+++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py
@@ -33,7 +33,7 @@ import threading
 
 import grpc
 
-from grpc.health.v1 import health_pb2
+from grpc_health.v1 import health_pb2
 
 
 class HealthServicer(health_pb2.HealthServicer):
diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py
index 66df25da63..0c420a655f 100644
--- a/src/python/grpcio_health_checking/health_commands.py
+++ b/src/python/grpcio_health_checking/health_commands.py
@@ -54,7 +54,7 @@ class CopyProtoModules(setuptools.Command):
     if os.path.isfile(HEALTH_PROTO):
       shutil.copyfile(
           HEALTH_PROTO,
-          os.path.join(ROOT_DIR, 'grpc/health/v1/health.proto'))
+          os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto'))
 
 
 class BuildPackageProtos(setuptools.Command):
@@ -74,5 +74,5 @@ class BuildPackageProtos(setuptools.Command):
     # directory is provided as an 'include' directory. We assume it's the '' key
     # to `self.distribution.package_dir` (and get a key error if it's not
     # there).
-    from grpc.tools import command
+    from grpc_tools import command
     command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 8c92ee16a9..e88f389ba8 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -66,7 +66,6 @@ setuptools.setup(
     license='3-clause BSD',
     package_dir=PACKAGE_DIRECTORIES,
     packages=setuptools.find_packages('.'),
-    namespace_packages=['grpc'],
     install_requires=INSTALL_REQUIRES,
     setup_requires=SETUP_REQUIRES,
     cmdclass=COMMAND_CLASS
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 5ee551cfe1..e822971fe0 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -100,7 +100,7 @@ class BuildProtoModules(setuptools.Command):
     pass
 
   def run(self):
-    import grpc.tools.protoc as protoc
+    import grpc_tools.protoc as protoc
 
     include_regex = re.compile(self.include)
     exclude_regex = re.compile(self.exclude) if self.exclude else None
@@ -116,7 +116,7 @@ class BuildProtoModules(setuptools.Command):
     # but we currently have name conflicts in src/proto
     for path in paths:
       command = [
-          'grpc.tools.protoc',
+          'grpc_tools.protoc',
           '-I {}'.format(PROTO_STEM),
           '--python_out={}'.format(PROTO_STEM),
           '--grpc_python_out={}'.format(PROTO_STEM),
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 7384206602..cd9194a7a8 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -35,7 +35,7 @@ import sys
 
 import setuptools
 
-import grpc.tools.command
+import grpc_tools.command
 
 PY3 = sys.version_info.major == 3
 
@@ -68,7 +68,7 @@ COMMAND_CLASS = {
     # Run `preprocess` *before* doing any packaging!
     'preprocess': commands.GatherProto,
 
-    'build_package_protos': grpc.tools.command.BuildPackageProtos,
+    'build_package_protos': grpc_tools.command.BuildPackageProtos,
     'build_py': commands.BuildPy,
     'run_interop': commands.RunInterop,
     'test_lite': commands.TestLite
diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
index 80300d13df..5dde72b169 100644
--- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
+++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
@@ -27,14 +27,14 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Tests of grpc.health.v1.health."""
+"""Tests of grpc_health.v1.health."""
 
 import unittest
 
 import grpc
 from grpc.framework.foundation import logging_pool
-from grpc.health.v1 import health
-from grpc.health.v1 import health_pb2
+from grpc_health.v1 import health
+from grpc_health.v1 import health_pb2
 
 from tests.unit.framework.common import test_constants
 
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 64fd97256e..f8ae05bb7a 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
@@ -44,7 +44,7 @@ import threading
 import unittest
 
 import grpc
-from grpc.tools import protoc
+from grpc_tools import protoc
 from tests.unit.framework.common import test_constants
 
 _MESSAGES_IMPORT = b'import "messages.proto";'
diff --git a/tools/distrib/python/grpcio_tools/grpc/__init__.py b/tools/distrib/python/grpcio_tools/grpc/__init__.py
deleted file mode 100644
index 70ac5edd48..0000000000
--- a/tools/distrib/python/grpcio_tools/grpc/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2016, 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.
-
-__import__('pkg_resources').declare_namespace(__name__)
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/__init__.py b/tools/distrib/python/grpcio_tools/grpc_tools/__init__.py
similarity index 100%
rename from tools/distrib/python/grpcio_tools/grpc/tools/__init__.py
rename to tools/distrib/python/grpcio_tools/grpc_tools/__init__.py
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/_protoc_compiler.pyx b/tools/distrib/python/grpcio_tools/grpc_tools/_protoc_compiler.pyx
similarity index 97%
rename from tools/distrib/python/grpcio_tools/grpc/tools/_protoc_compiler.pyx
rename to tools/distrib/python/grpcio_tools/grpc_tools/_protoc_compiler.pyx
index a6530127c0..81034fad5e 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/_protoc_compiler.pyx
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/_protoc_compiler.pyx
@@ -29,7 +29,7 @@
 
 from libc cimport stdlib
 
-cdef extern from "grpc/tools/main.h":
+cdef extern from "grpc_tools/main.h":
   int protoc_main(int argc, char *argv[])
 
 def run_main(list args not None):
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
similarity index 98%
rename from tools/distrib/python/grpcio_tools/grpc/tools/command.py
rename to tools/distrib/python/grpcio_tools/grpc_tools/command.py
index 2520099835..befb1284da 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/command.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
@@ -32,7 +32,7 @@ import sys
 
 import setuptools
 
-from grpc.tools import protoc
+from grpc_tools import protoc
 
 
 def build_package_protos(package_root):
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/main.cc b/tools/distrib/python/grpcio_tools/grpc_tools/main.cc
similarity index 98%
rename from tools/distrib/python/grpcio_tools/grpc/tools/main.cc
rename to tools/distrib/python/grpcio_tools/grpc_tools/main.cc
index 8391839513..0c2fa3180a 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/main.cc
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/main.cc
@@ -32,7 +32,7 @@
 
 #include "src/compiler/python_generator.h"
 
-#include "grpc/tools/main.h"
+#include "grpc_tools/main.h"
 
 int protoc_main(int argc, char* argv[]) {
   google::protobuf::compiler::CommandLineInterface cli;
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/main.h b/tools/distrib/python/grpcio_tools/grpc_tools/main.h
similarity index 100%
rename from tools/distrib/python/grpcio_tools/grpc/tools/main.h
rename to tools/distrib/python/grpcio_tools/grpc_tools/main.h
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
similarity index 98%
rename from tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
rename to tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
index e1256a7dd9..7d5892dc4b 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
@@ -32,7 +32,7 @@
 import pkg_resources
 import sys
 
-from grpc.tools import _protoc_compiler
+from grpc_tools import _protoc_compiler
 
 def main(command_arguments):
   """Run the protocol buffer compiler with the given command-line arguments.
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index 762d6948cc..814bf9651b 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -103,7 +103,7 @@ PROTO_FILES = [
 CC_INCLUDE = os.path.normpath(protoc_lib_deps.CC_INCLUDE)
 PROTO_INCLUDE = os.path.normpath(protoc_lib_deps.PROTO_INCLUDE)
 
-GRPC_PYTHON_TOOLS_PACKAGE = 'grpc.tools'
+GRPC_PYTHON_TOOLS_PACKAGE = 'grpc_tools'
 GRPC_PYTHON_PROTO_RESOURCES_NAME = '_proto'
 
 DEFINE_MACROS = ()
@@ -149,14 +149,14 @@ def package_data():
 
 def protoc_ext_module():
   plugin_sources = [
-      os.path.join('grpc', 'tools', 'main.cc'),
+      os.path.join('grpc_tools', 'main.cc'),
       os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc')] + [
       os.path.join(CC_INCLUDE, cc_file)
       for cc_file in CC_FILES]
   plugin_ext = extension.Extension(
-      name='grpc.tools._protoc_compiler',
+      name='grpc_tools._protoc_compiler',
       sources=(
-          [os.path.join('grpc', 'tools', '_protoc_compiler.pyx')] +
+          [os.path.join('grpc_tools', '_protoc_compiler.pyx')] +
           plugin_sources),
       include_dirs=[
           '.',
@@ -183,7 +183,6 @@ setuptools.setup(
       protoc_ext_module(),
   ]),
   packages=setuptools.find_packages('.'),
-  namespace_packages=['grpc'],
   install_requires=[
     'protobuf>=3.0.0',
     'grpcio>={version}'.format(version=grpc_version.VERSION),
-- 
GitLab


From f096f540eeb057103eb5c2330a4165e0aa251ff1 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Mon, 12 Dec 2016 15:34:34 -0800
Subject: [PATCH 126/344] Recover 'namespace'd Python distribution packages

Uses dynamic loading to paper-over the negative effects of losing
namespace packages in the previous commit.
---
 src/python/grpcio/grpc/__init__.py | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index d4e3152c59..f801dd632a 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -31,6 +31,7 @@
 
 import abc
 import enum
+import sys
 
 import six
 
@@ -1293,3 +1294,24 @@ __all__ = (
     'secure_channel',
     'server',
 )
+
+
+############################### Extension Shims ################################
+
+
+# Here to maintain backwards compatibility; avoid using these in new code!
+try:
+  import grpc_tools
+  sys.modules.update({'grpc.tools': grpc_tools})
+except ImportError:
+  pass
+try:
+  import grpc_health
+  sys.modules.update({'grpc.health': grpc_health})
+except ImportError:
+  pass
+try:
+  import grpc_reflection
+  sys.modules.update({'grpc.reflection': grpc_reflection})
+except ImportError:
+  pass
-- 
GitLab


From e136c1a77309274328760fb73b7faa8420f47c6b Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Mon, 12 Dec 2016 15:58:36 -0800
Subject: [PATCH 127/344] Up-version Python

---
 build.yaml                                        | 2 +-
 src/python/grpcio/grpc_version.py                 | 2 +-
 src/python/grpcio_health_checking/grpc_version.py | 2 +-
 src/python/grpcio_tests/grpc_version.py           | 2 +-
 tools/distrib/python/grpcio_tools/grpc_version.py | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/build.yaml b/build.yaml
index d725ff3890..79bb8c9471 100644
--- a/build.yaml
+++ b/build.yaml
@@ -7,7 +7,7 @@ settings:
   '#3': Use "-preN" suffixes to identify pre-release versions
   '#4': Per-language overrides are possible with (eg) ruby_version tag here
   '#5': See the expand_version.py for all the quirks here
-  python_version: 1.0.2
+  python_version: 1.0.3
   version: 1.0.1
 filegroups:
 - name: census
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 219045a721..775ece397b 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION='1.0.2'
+VERSION='1.0.3'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 4cb8c3d82a..17ef5873f1 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION='1.0.2'
+VERSION='1.0.3'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 66b0398c7a..c6226160b8 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION='1.0.2'
+VERSION='1.0.3'
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 6dd6fae0d7..a96d2ef8b2 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION='1.0.2'
+VERSION='1.0.3'
-- 
GitLab


From 91764921bc25f695bf2ce75904fe7a69f552203e Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Tue, 13 Dec 2016 02:53:20 +0000
Subject: [PATCH 128/344] Use LONG_TIMEOUT for calls that do not time out

---
 .../grpcio_tests/tests/unit/_channel_ready_future_test.py       | 2 +-
 src/python/grpcio_tests/tests/unit/beta/_utilities_test.py      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
index e8982ed2de..3d1519a537 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
@@ -86,7 +86,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
 
     ready_future = grpc.channel_ready_future(channel)
     ready_future.add_done_callback(callback.accept_value)
-    self.assertIsNone(ready_future.result(test_constants.SHORT_TIMEOUT))
+    self.assertIsNone(ready_future.result(test_constants.LONG_TIMEOUT))
     value_passed_to_callback = callback.block_until_called()
     self.assertIs(ready_future, value_passed_to_callback)
     self.assertFalse(ready_future.cancelled())
diff --git a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
index 90fe10c77c..b955756b6b 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
@@ -88,7 +88,7 @@ class ChannelConnectivityTest(unittest.TestCase):
       ready_future = utilities.channel_ready_future(channel)
       ready_future.add_done_callback(callback.accept_value)
       self.assertIsNone(
-          ready_future.result(test_constants.SHORT_TIMEOUT))
+          ready_future.result(test_constants.LONG_TIMEOUT))
       value_passed_to_callback = callback.block_until_called()
       self.assertIs(ready_future, value_passed_to_callback)
       self.assertFalse(ready_future.cancelled())
-- 
GitLab


From 1de3914d69f90969114dc6e73d34d1e6d4bc2ae6 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Tue, 13 Dec 2016 02:56:41 +0000
Subject: [PATCH 129/344] Style fix: pass keyword arguments by keyword

---
 .../grpcio_tests/tests/unit/_channel_ready_future_test.py     | 4 ++--
 src/python/grpcio_tests/tests/unit/beta/_utilities_test.py    | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
index 3d1519a537..20ba13fc4e 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
@@ -66,7 +66,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
     ready_future = grpc.channel_ready_future(channel)
     ready_future.add_done_callback(callback.accept_value)
     with self.assertRaises(grpc.FutureTimeoutError):
-      ready_future.result(test_constants.SHORT_TIMEOUT)
+      ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
     self.assertFalse(ready_future.cancelled())
     self.assertFalse(ready_future.done())
     self.assertTrue(ready_future.running())
@@ -86,7 +86,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
 
     ready_future = grpc.channel_ready_future(channel)
     ready_future.add_done_callback(callback.accept_value)
-    self.assertIsNone(ready_future.result(test_constants.LONG_TIMEOUT))
+    self.assertIsNone(ready_future.result(timeout=test_constants.LONG_TIMEOUT))
     value_passed_to_callback = callback.block_until_called()
     self.assertIs(ready_future, value_passed_to_callback)
     self.assertFalse(ready_future.cancelled())
diff --git a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
index b955756b6b..9cce96cc85 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
@@ -66,7 +66,7 @@ class ChannelConnectivityTest(unittest.TestCase):
     ready_future = utilities.channel_ready_future(channel)
     ready_future.add_done_callback(callback.accept_value)
     with self.assertRaises(future.TimeoutError):
-      ready_future.result(test_constants.SHORT_TIMEOUT)
+      ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
     self.assertFalse(ready_future.cancelled())
     self.assertFalse(ready_future.done())
     self.assertTrue(ready_future.running())
@@ -88,7 +88,7 @@ class ChannelConnectivityTest(unittest.TestCase):
       ready_future = utilities.channel_ready_future(channel)
       ready_future.add_done_callback(callback.accept_value)
       self.assertIsNone(
-          ready_future.result(test_constants.LONG_TIMEOUT))
+          ready_future.result(timeout=test_constants.LONG_TIMEOUT))
       value_passed_to_callback = callback.block_until_called()
       self.assertIs(ready_future, value_passed_to_callback)
       self.assertFalse(ready_future.cancelled())
-- 
GitLab


From 727f887cc21d6f2a583d8a2fa2bb2f4c124f20fb Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 12 Dec 2016 12:09:35 +0100
Subject: [PATCH 130/344] remove leading space in C# comments

---
 src/compiler/csharp_generator.cc              |   2 +-
 src/csharp/Grpc.Examples/MathGrpc.cs          |  74 ++++-----
 .../Grpc.IntegrationTesting/MetricsGrpc.cs    |  22 +--
 .../Grpc.IntegrationTesting/ServicesGrpc.cs   | 124 +++++++-------
 .../Grpc.IntegrationTesting/TestGrpc.cs       | 156 +++++++++---------
 src/csharp/Grpc.Reflection/ReflectionGrpc.cs  |  12 +-
 6 files changed, 195 insertions(+), 195 deletions(-)

diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index a3af258d9c..3362bc13dd 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -107,7 +107,7 @@ void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
         printer->Print("///\n");
       }
       last_was_empty = false;
-      printer->Print("/// $line$\n", "line", *it);
+      printer->Print("///$line$\n", "line", *it);
     }
   }
   printer->Print("/// </summary>\n");
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 8b431c7218..827c9f66d6 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -85,8 +85,8 @@ namespace Math {
     public abstract partial class MathBase
     {
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       {
@@ -94,10 +94,10 @@ namespace Math {
       }
 
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
       {
@@ -105,9 +105,9 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
       {
@@ -115,8 +115,8 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
       {
@@ -149,86 +149,86 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
       }
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivMany(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
       }
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Sum(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index d0bf0afc1d..a88964b0ef 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -76,8 +76,8 @@ namespace Grpc.Testing {
     public abstract partial class MetricsServiceBase
     {
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context)
       {
@@ -85,7 +85,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context)
       {
@@ -118,44 +118,44 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetAllGauges(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_GetAllGauges, null, options, request);
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGauge(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_GetGauge, null, options, request);
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGaugeAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 3cc4ed9f3c..54d81e2259 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -71,8 +71,8 @@ namespace Grpc.Testing {
     public abstract partial class BenchmarkServiceBase
     {
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -80,8 +80,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
       {
@@ -114,48 +114,48 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
       {
@@ -227,12 +227,12 @@ namespace Grpc.Testing {
     public abstract partial class WorkerServiceBase
     {
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
       {
@@ -240,12 +240,12 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
       {
@@ -253,7 +253,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
       {
@@ -261,7 +261,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
       {
@@ -294,104 +294,104 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunServer(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
       }
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunClient(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 43dbc2865f..05da7f95ea 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -42,8 +42,8 @@ using Grpc.Core;
 
 namespace Grpc.Testing {
   /// <summary>
-  ///  A simple service to test the various types of RPCs and experiment with
-  ///  performance with various types of payload.
+  /// A simple service to test the various types of RPCs and experiment with
+  /// performance with various types of payload.
   /// </summary>
   public static partial class TestService
   {
@@ -123,7 +123,7 @@ namespace Grpc.Testing {
     public abstract partial class TestServiceBase
     {
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -131,7 +131,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -139,9 +139,9 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -149,8 +149,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -158,8 +158,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
       {
@@ -167,9 +167,9 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -177,10 +177,10 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -188,8 +188,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -222,194 +222,194 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
       }
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
       }
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
       }
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
@@ -438,8 +438,8 @@ namespace Grpc.Testing {
 
   }
   /// <summary>
-  ///  A simple service NOT implemented at servers so clients can test for
-  ///  that case.
+  /// A simple service NOT implemented at servers so clients can test for
+  /// that case.
   /// </summary>
   public static partial class UnimplementedService
   {
@@ -464,7 +464,7 @@ namespace Grpc.Testing {
     public abstract partial class UnimplementedServiceBase
     {
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -497,28 +497,28 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
@@ -540,7 +540,7 @@ namespace Grpc.Testing {
 
   }
   /// <summary>
-  ///  A service used to control reconnect server.
+  /// A service used to control reconnect server.
   /// </summary>
   public static partial class ReconnectService
   {
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 1b6f96ce7c..3bd2d121d5 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -64,8 +64,8 @@ namespace Grpc.Reflection.V1Alpha {
     public abstract partial class ServerReflectionBase
     {
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, ServerCallContext context)
       {
@@ -98,16 +98,16 @@ namespace Grpc.Reflection.V1Alpha {
       }
 
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return ServerReflectionInfo(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(CallOptions options)
       {
-- 
GitLab


From 726f40f0461f57d295015b1e60228a675b883740 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 12 Dec 2016 12:09:35 +0100
Subject: [PATCH 131/344] remove leading space in C# comments

---
 src/compiler/csharp_generator.cc              |   2 +-
 src/csharp/Grpc.Examples/MathGrpc.cs          |  74 ++++-----
 .../Grpc.IntegrationTesting/MetricsGrpc.cs    |  22 +--
 .../Grpc.IntegrationTesting/ServicesGrpc.cs   | 124 +++++++-------
 .../Grpc.IntegrationTesting/TestGrpc.cs       | 156 +++++++++---------
 src/csharp/Grpc.Reflection/ReflectionGrpc.cs  |  12 +-
 6 files changed, 195 insertions(+), 195 deletions(-)

diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index a3af258d9c..3362bc13dd 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -107,7 +107,7 @@ void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
         printer->Print("///\n");
       }
       last_was_empty = false;
-      printer->Print("/// $line$\n", "line", *it);
+      printer->Print("///$line$\n", "line", *it);
     }
   }
   printer->Print("/// </summary>\n");
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 8b431c7218..827c9f66d6 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -85,8 +85,8 @@ namespace Math {
     public abstract partial class MathBase
     {
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       {
@@ -94,10 +94,10 @@ namespace Math {
       }
 
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
       {
@@ -105,9 +105,9 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
       {
@@ -115,8 +115,8 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
       {
@@ -149,86 +149,86 @@ namespace Math {
       }
 
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
-      ///  and remainder.
+      /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      /// and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
       }
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivMany(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
+      /// DivMany accepts an arbitrary number of division args from the client stream
+      /// and sends back the results in the reply stream.  The stream continues until
+      /// the client closes its end; the server does the same after sending all the
+      /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
+      /// Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
+      /// generates up to limit numbers; otherwise it continues until the call is
+      /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
       }
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Sum(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
+      /// Sum sums a stream of numbers, returning the final result once the stream
+      /// is closed.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index d0bf0afc1d..a88964b0ef 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -76,8 +76,8 @@ namespace Grpc.Testing {
     public abstract partial class MetricsServiceBase
     {
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context)
       {
@@ -85,7 +85,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context)
       {
@@ -118,44 +118,44 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetAllGauges(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
+      /// Returns the values of all the gauges that are currently being maintained by
+      /// the service
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_GetAllGauges, null, options, request);
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGauge(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_GetGauge, null, options, request);
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGaugeAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Returns the value of one gauge
+      /// Returns the value of one gauge
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 3cc4ed9f3c..54d81e2259 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -71,8 +71,8 @@ namespace Grpc.Testing {
     public abstract partial class BenchmarkServiceBase
     {
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -80,8 +80,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
       {
@@ -114,48 +114,48 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
+      /// One request followed by one response.
+      /// The server returns the client payload as-is.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
       {
@@ -227,12 +227,12 @@ namespace Grpc.Testing {
     public abstract partial class WorkerServiceBase
     {
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
       {
@@ -240,12 +240,12 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
       {
@@ -253,7 +253,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
       {
@@ -261,7 +261,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
       {
@@ -294,104 +294,104 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunServer(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start server with specified workload.
+      /// First request sent specifies the ServerConfig followed by ServerStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test server
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
       }
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunClient(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
+      /// Start client with specified workload.
+      /// First request sent specifies the ClientConfig followed by ClientStatus
+      /// response. After that, a "Mark" can be sent anytime to request the latest
+      /// stats. Closing the stream will initiate shutdown of the test client
+      /// and once the shutdown has finished, the OK status is sent to terminate
+      /// this RPC.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Just return the core count - unary call
+      /// Just return the core count - unary call
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Quit this worker
+      /// Quit this worker
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
       {
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 43dbc2865f..05da7f95ea 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -42,8 +42,8 @@ using Grpc.Core;
 
 namespace Grpc.Testing {
   /// <summary>
-  ///  A simple service to test the various types of RPCs and experiment with
-  ///  performance with various types of payload.
+  /// A simple service to test the various types of RPCs and experiment with
+  /// performance with various types of payload.
   /// </summary>
   public static partial class TestService
   {
@@ -123,7 +123,7 @@ namespace Grpc.Testing {
     public abstract partial class TestServiceBase
     {
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -131,7 +131,7 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -139,9 +139,9 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
@@ -149,8 +149,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -158,8 +158,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
       {
@@ -167,9 +167,9 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -177,10 +177,10 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
@@ -188,8 +188,8 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -222,194 +222,194 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One empty request followed by one empty response.
+      /// One empty request followed by one empty response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response.
+      /// One request followed by one response.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by one response. Response has cache control
-      ///  headers set such that a caching HTTP proxy (such as GFE) can
-      ///  satisfy subsequent requests.
+      /// One request followed by one response. Response has cache control
+      /// headers set such that a caching HTTP proxy (such as GFE) can
+      /// satisfy subsequent requests.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CacheableUnaryCall, null, options, request);
       }
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
+      /// One request followed by a sequence of responses (streamed download).
+      /// The server returns the payload with client desired type and sizes.
       /// </summary>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
       }
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
+      /// A sequence of requests followed by one response (streamed upload).
+      /// The server returns the aggregated size of client payload as the result.
       /// </summary>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
       }
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
+      /// A sequence of requests with each request served by the server immediately.
+      /// As one request could lead to multiple responses, this interface
+      /// demonstrates the idea of full duplexing.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
       }
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
+      /// A sequence of requests followed by a sequence of responses.
+      /// The server buffers all the client requests and then serves them in order. A
+      /// stream of responses are returned to the client when the server starts with
+      /// first request.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The test server will not implement this method. It will be used
-      ///  to test the behavior when clients call unimplemented methods.
+      /// The test server will not implement this method. It will be used
+      /// to test the behavior when clients call unimplemented methods.
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
@@ -438,8 +438,8 @@ namespace Grpc.Testing {
 
   }
   /// <summary>
-  ///  A simple service NOT implemented at servers so clients can test for
-  ///  that case.
+  /// A simple service NOT implemented at servers so clients can test for
+  /// that case.
   /// </summary>
   public static partial class UnimplementedService
   {
@@ -464,7 +464,7 @@ namespace Grpc.Testing {
     public abstract partial class UnimplementedServiceBase
     {
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
@@ -497,28 +497,28 @@ namespace Grpc.Testing {
       }
 
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  A call that no server should implement
+      /// A call that no server should implement
       /// </summary>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
@@ -540,7 +540,7 @@ namespace Grpc.Testing {
 
   }
   /// <summary>
-  ///  A service used to control reconnect server.
+  /// A service used to control reconnect server.
   /// </summary>
   public static partial class ReconnectService
   {
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 1b6f96ce7c..3bd2d121d5 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -64,8 +64,8 @@ namespace Grpc.Reflection.V1Alpha {
     public abstract partial class ServerReflectionBase
     {
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, ServerCallContext context)
       {
@@ -98,16 +98,16 @@ namespace Grpc.Reflection.V1Alpha {
       }
 
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return ServerReflectionInfo(new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  The reflection service is structured as a bidirectional stream, ensuring
-      ///  all related requests go to a single server.
+      /// The reflection service is structured as a bidirectional stream, ensuring
+      /// all related requests go to a single server.
       /// </summary>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(CallOptions options)
       {
-- 
GitLab


From 00f66361b7c90ec688265487c3f88377a302fdcf Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 12 Dec 2016 13:02:29 +0100
Subject: [PATCH 132/344] Generate param comments in C# proto plugin

---
 src/compiler/csharp_generator.cc              |  89 +++++++++--
 src/csharp/Grpc.Examples/MathGrpc.cs          |  51 +++++++
 src/csharp/Grpc.HealthCheck/HealthGrpc.cs     |   1 +
 .../Grpc.IntegrationTesting/MetricsGrpc.cs    |  32 ++++
 .../Grpc.IntegrationTesting/ServicesGrpc.cs   |  89 +++++++++++
 .../Grpc.IntegrationTesting/TestGrpc.cs       | 139 ++++++++++++++++++
 src/csharp/Grpc.Reflection/ReflectionGrpc.cs  |  11 ++
 7 files changed, 402 insertions(+), 10 deletions(-)

diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 3362bc13dd..cc7a7a96ae 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -68,13 +68,13 @@ namespace {
 // Currently, we cannot easily reuse the functionality as
 // google/protobuf/compiler/csharp/csharp_doc_comment.h is not a public header.
 // TODO(jtattermusch): reuse the functionality from google/protobuf.
-void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
+bool GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
                                 grpc::protobuf::SourceLocation location) {
   grpc::string comments = location.leading_comments.empty()
                               ? location.trailing_comments
                               : location.leading_comments;
   if (comments.empty()) {
-    return;
+    return false;
   }
   // XML escaping... no need for apostrophes etc as the whole text is going to
   // be a child
@@ -111,14 +111,80 @@ void GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer *printer,
     }
   }
   printer->Print("/// </summary>\n");
+  return true;
 }
 
 template <typename DescriptorType>
-void GenerateDocCommentBody(grpc::protobuf::io::Printer *printer,
+bool GenerateDocCommentBody(grpc::protobuf::io::Printer *printer,
                             const DescriptorType *descriptor) {
   grpc::protobuf::SourceLocation location;
-  if (descriptor->GetSourceLocation(&location)) {
-    GenerateDocCommentBodyImpl(printer, location);
+  if (!descriptor->GetSourceLocation(&location)) {
+    return false;
+  }
+  return GenerateDocCommentBodyImpl(printer, location);
+}
+
+void GenerateDocCommentServerMethod(grpc::protobuf::io::Printer *printer,
+                                    const MethodDescriptor *method) {
+  if (GenerateDocCommentBody(printer, method)) {
+    if (method->client_streaming()) {
+      printer->Print(
+          "/// <param name=\"requestStream\">Used for reading requests from "
+          "the client.</param>\n");
+    } else {
+      printer->Print(
+          "/// <param name=\"request\">The request received from the "
+          "client.</param>\n");
+    }
+    if (method->server_streaming()) {
+      printer->Print(
+          "/// <param name=\"responseStream\">Used for sending responses back "
+          "to the client.</param>\n");
+    }
+    printer->Print(
+        "/// <param name=\"context\">The context of the server-side call "
+        "handler being invoked.</param>\n");
+    if (method->server_streaming()) {
+      printer->Print(
+          "/// <returns>A task indicating completion of the "
+          "handler.</returns>\n");
+    } else {
+      printer->Print(
+          "/// <returns>The response to send back to the client (wrapped by a "
+          "task).</returns>\n");
+    }
+  }
+}
+
+void GenerateDocCommentClientMethod(grpc::protobuf::io::Printer *printer,
+                                    const MethodDescriptor *method,
+                                    bool is_sync, bool use_call_options) {
+  if (GenerateDocCommentBody(printer, method)) {
+    if (!method->client_streaming()) {
+      printer->Print(
+          "/// <param name=\"request\">The request to send to the "
+          "server.</param>\n");
+    }
+    if (!use_call_options) {
+      printer->Print(
+          "/// <param name=\"headers\">The initial metadata to send with the "
+          "call. This parameter is optional.</param>\n");
+      printer->Print(
+          "/// <param name=\"deadline\">An optional deadline for the call. The "
+          "call will be cancelled if deadline is hit.</param>\n");
+      printer->Print(
+          "/// <param name=\"cancellationToken\">An optional token for "
+          "canceling the call.</param>\n");
+    } else {
+      printer->Print(
+          "/// <param name=\"options\">The options for the call.</param>\n");
+    }
+    if (is_sync) {
+      printer->Print(
+          "/// <returns>The response received from the server.</returns>\n");
+    } else {
+      printer->Print("/// <returns>The call object.</returns>\n");
+    }
   }
 }
 
@@ -319,7 +385,7 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
   out->Indent();
   for (int i = 0; i < service->method_count(); i++) {
     const MethodDescriptor *method = service->method(i);
-    GenerateDocCommentBody(out, method);
+    GenerateDocCommentServerMethod(out, method);
     out->Print(
         "public virtual $returntype$ "
         "$methodname$($request$$response_stream_maybe$, "
@@ -393,7 +459,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
 
     if (method_type == METHODTYPE_NO_STREAMING) {
       // unary calls have an extra synchronous stub method
-      GenerateDocCommentBody(out, method);
+      GenerateDocCommentClientMethod(out, method, true, false);
       out->Print(
           "public virtual $response$ $methodname$($request$ request, Metadata "
           "headers = null, DateTime? deadline = null, CancellationToken "
@@ -411,7 +477,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
       out->Print("}\n");
 
       // overload taking CallOptions as a param
-      GenerateDocCommentBody(out, method);
+      GenerateDocCommentClientMethod(out, method, true, true);
       out->Print(
           "public virtual $response$ $methodname$($request$ request, "
           "CallOptions options)\n",
@@ -432,7 +498,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
     if (method_type == METHODTYPE_NO_STREAMING) {
       method_name += "Async";  // prevent name clash with synchronous method.
     }
-    GenerateDocCommentBody(out, method);
+    GenerateDocCommentClientMethod(out, method, false, false);
     out->Print(
         "public virtual $returntype$ $methodname$($request_maybe$Metadata "
         "headers = null, DateTime? deadline = null, CancellationToken "
@@ -452,7 +518,7 @@ void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
     out->Print("}\n");
 
     // overload taking CallOptions as a param
-    GenerateDocCommentBody(out, method);
+    GenerateDocCommentClientMethod(out, method, false, true);
     out->Print(
         "public virtual $returntype$ $methodname$($request_maybe$CallOptions "
         "options)\n",
@@ -517,6 +583,9 @@ void GenerateBindServiceMethod(Printer *out, const ServiceDescriptor *service) {
   out->Print(
       "/// <summary>Creates service definition that can be registered with a "
       "server</summary>\n");
+  out->Print(
+      "/// <param name=\"serviceImpl\">An object implementing the server-side"
+      " handling logic.</param>\n");
   out->Print(
       "public static ServerServiceDefinition BindService($implclass$ "
       "serviceImpl)\n",
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 827c9f66d6..3364b8ce8e 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -88,6 +88,9 @@ namespace Math {
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
       /// and remainder.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -99,6 +102,10 @@ namespace Math {
       /// the client closes its end; the server does the same after sending all the
       /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -109,6 +116,10 @@ namespace Math {
       /// generates up to limit numbers; otherwise it continues until the call is
       /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -118,6 +129,9 @@ namespace Math {
       /// Sum sums a stream of numbers, returning the final result once the stream
       /// is closed.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -152,6 +166,11 @@ namespace Math {
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
       /// and remainder.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
@@ -160,6 +179,9 @@ namespace Math {
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
       /// and remainder.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
@@ -168,6 +190,11 @@ namespace Math {
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
       /// and remainder.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -176,6 +203,9 @@ namespace Math {
       /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
       /// and remainder.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
@@ -186,6 +216,10 @@ namespace Math {
       /// the client closes its end; the server does the same after sending all the
       /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivMany(new CallOptions(headers, deadline, cancellationToken));
@@ -196,6 +230,8 @@ namespace Math {
       /// the client closes its end; the server does the same after sending all the
       /// replies.  The stream ends immediately if either end aborts.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
@@ -205,6 +241,11 @@ namespace Math {
       /// generates up to limit numbers; otherwise it continues until the call is
       /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
@@ -214,6 +255,9 @@ namespace Math {
       /// generates up to limit numbers; otherwise it continues until the call is
       /// canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
@@ -222,6 +266,10 @@ namespace Math {
       /// Sum sums a stream of numbers, returning the final result once the stream
       /// is closed.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Sum(new CallOptions(headers, deadline, cancellationToken));
@@ -230,6 +278,8 @@ namespace Math {
       /// Sum sums a stream of numbers, returning the final result once the stream
       /// is closed.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
@@ -242,6 +292,7 @@ namespace Math {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(MathBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index ad5cf11b75..020c2df565 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -115,6 +115,7 @@ namespace Grpc.Health.V1 {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(HealthBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index a88964b0ef..8b58622d53 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -79,6 +79,10 @@ namespace Grpc.Testing {
       /// Returns the values of all the gauges that are currently being maintained by
       /// the service
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -87,6 +91,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Returns the value of one gauge
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -121,6 +128,11 @@ namespace Grpc.Testing {
       /// Returns the values of all the gauges that are currently being maintained by
       /// the service
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetAllGauges(request, new CallOptions(headers, deadline, cancellationToken));
@@ -129,6 +141,9 @@ namespace Grpc.Testing {
       /// Returns the values of all the gauges that are currently being maintained by
       /// the service
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_GetAllGauges, null, options, request);
@@ -136,6 +151,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Returns the value of one gauge
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGauge(request, new CallOptions(headers, deadline, cancellationToken));
@@ -143,6 +163,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Returns the value of one gauge
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_GetGauge, null, options, request);
@@ -150,6 +173,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Returns the value of one gauge
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return GetGaugeAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -157,6 +185,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Returns the value of one gauge
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_GetGauge, null, options, request);
@@ -169,6 +200,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 54d81e2259..5135d9ab66 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -74,6 +74,9 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -83,6 +86,10 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -117,6 +124,11 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -125,6 +137,9 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
@@ -133,6 +148,11 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -141,6 +161,9 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
@@ -149,6 +172,10 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
@@ -157,6 +184,8 @@ namespace Grpc.Testing {
       /// One request followed by one response.
       /// The server returns the client payload as-is.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
@@ -169,6 +198,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
@@ -234,6 +264,10 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -247,6 +281,10 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -255,6 +293,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Just return the core count - unary call
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -263,6 +304,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Quit this worker
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -301,6 +345,10 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunServer(new CallOptions(headers, deadline, cancellationToken));
@@ -313,6 +361,8 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
@@ -325,6 +375,10 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return RunClient(new CallOptions(headers, deadline, cancellationToken));
@@ -337,6 +391,8 @@ namespace Grpc.Testing {
       /// and once the shutdown has finished, the OK status is sent to terminate
       /// this RPC.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
@@ -344,6 +400,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Just return the core count - unary call
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
@@ -351,6 +412,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Just return the core count - unary call
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
@@ -358,6 +422,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Just return the core count - unary call
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -365,6 +434,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Just return the core count - unary call
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
@@ -372,6 +444,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Quit this worker
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
@@ -379,6 +456,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Quit this worker
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
@@ -386,6 +466,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// Quit this worker
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -393,6 +478,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// Quit this worker
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
@@ -405,6 +493,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 05da7f95ea..0265f8e821 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -125,6 +125,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One empty request followed by one empty response.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -133,6 +136,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One request followed by one response.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -143,6 +149,9 @@ namespace Grpc.Testing {
       /// headers set such that a caching HTTP proxy (such as GFE) can
       /// satisfy subsequent requests.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -152,6 +161,10 @@ namespace Grpc.Testing {
       /// One request followed by a sequence of responses (streamed download).
       /// The server returns the payload with client desired type and sizes.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -161,6 +174,9 @@ namespace Grpc.Testing {
       /// A sequence of requests followed by one response (streamed upload).
       /// The server returns the aggregated size of client payload as the result.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -171,6 +187,10 @@ namespace Grpc.Testing {
       /// As one request could lead to multiple responses, this interface
       /// demonstrates the idea of full duplexing.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -182,6 +202,10 @@ namespace Grpc.Testing {
       /// stream of responses are returned to the client when the server starts with
       /// first request.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -191,6 +215,9 @@ namespace Grpc.Testing {
       /// The test server will not implement this method. It will be used
       /// to test the behavior when clients call unimplemented methods.
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -224,6 +251,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// One empty request followed by one empty response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -231,6 +263,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One empty request followed by one empty response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
@@ -238,6 +273,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// One empty request followed by one empty response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -245,6 +285,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One empty request followed by one empty response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
@@ -252,6 +295,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// One request followed by one response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -259,6 +307,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One request followed by one response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
@@ -266,6 +317,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// One request followed by one response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -273,6 +329,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// One request followed by one response.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
@@ -282,6 +341,11 @@ namespace Grpc.Testing {
       /// headers set such that a caching HTTP proxy (such as GFE) can
       /// satisfy subsequent requests.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -291,6 +355,9 @@ namespace Grpc.Testing {
       /// headers set such that a caching HTTP proxy (such as GFE) can
       /// satisfy subsequent requests.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_CacheableUnaryCall, null, options, request);
@@ -300,6 +367,11 @@ namespace Grpc.Testing {
       /// headers set such that a caching HTTP proxy (such as GFE) can
       /// satisfy subsequent requests.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return CacheableUnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -309,6 +381,9 @@ namespace Grpc.Testing {
       /// headers set such that a caching HTTP proxy (such as GFE) can
       /// satisfy subsequent requests.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_CacheableUnaryCall, null, options, request);
@@ -317,6 +392,11 @@ namespace Grpc.Testing {
       /// One request followed by a sequence of responses (streamed download).
       /// The server returns the payload with client desired type and sizes.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -325,6 +405,9 @@ namespace Grpc.Testing {
       /// One request followed by a sequence of responses (streamed download).
       /// The server returns the payload with client desired type and sizes.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
       {
         return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
@@ -333,6 +416,10 @@ namespace Grpc.Testing {
       /// A sequence of requests followed by one response (streamed upload).
       /// The server returns the aggregated size of client payload as the result.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
@@ -341,6 +428,8 @@ namespace Grpc.Testing {
       /// A sequence of requests followed by one response (streamed upload).
       /// The server returns the aggregated size of client payload as the result.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
@@ -350,6 +439,10 @@ namespace Grpc.Testing {
       /// As one request could lead to multiple responses, this interface
       /// demonstrates the idea of full duplexing.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
@@ -359,6 +452,8 @@ namespace Grpc.Testing {
       /// As one request could lead to multiple responses, this interface
       /// demonstrates the idea of full duplexing.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
@@ -369,6 +464,10 @@ namespace Grpc.Testing {
       /// stream of responses are returned to the client when the server starts with
       /// first request.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
@@ -379,6 +478,8 @@ namespace Grpc.Testing {
       /// stream of responses are returned to the client when the server starts with
       /// first request.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
@@ -387,6 +488,11 @@ namespace Grpc.Testing {
       /// The test server will not implement this method. It will be used
       /// to test the behavior when clients call unimplemented methods.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -395,6 +501,9 @@ namespace Grpc.Testing {
       /// The test server will not implement this method. It will be used
       /// to test the behavior when clients call unimplemented methods.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
@@ -403,6 +512,11 @@ namespace Grpc.Testing {
       /// The test server will not implement this method. It will be used
       /// to test the behavior when clients call unimplemented methods.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -411,6 +525,9 @@ namespace Grpc.Testing {
       /// The test server will not implement this method. It will be used
       /// to test the behavior when clients call unimplemented methods.
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
@@ -423,6 +540,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
@@ -466,6 +584,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// A call that no server should implement
       /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -499,6 +620,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// A call that no server should implement
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
@@ -506,6 +632,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// A call that no server should implement
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
       public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
@@ -513,6 +642,11 @@ namespace Grpc.Testing {
       /// <summary>
       /// A call that no server should implement
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
@@ -520,6 +654,9 @@ namespace Grpc.Testing {
       /// <summary>
       /// A call that no server should implement
       /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
@@ -532,6 +669,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
@@ -648,6 +786,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 3bd2d121d5..5bd7558be5 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -67,6 +67,10 @@ namespace Grpc.Reflection.V1Alpha {
       /// The reflection service is structured as a bidirectional stream, ensuring
       /// all related requests go to a single server.
       /// </summary>
+      /// <param name="requestStream">Used for reading requests from the client.</param>
+      /// <param name="responseStream">Used for sending responses back to the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>A task indicating completion of the handler.</returns>
       public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
@@ -101,6 +105,10 @@ namespace Grpc.Reflection.V1Alpha {
       /// The reflection service is structured as a bidirectional stream, ensuring
       /// all related requests go to a single server.
       /// </summary>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return ServerReflectionInfo(new CallOptions(headers, deadline, cancellationToken));
@@ -109,6 +117,8 @@ namespace Grpc.Reflection.V1Alpha {
       /// The reflection service is structured as a bidirectional stream, ensuring
       /// all related requests go to a single server.
       /// </summary>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
       public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(CallOptions options)
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_ServerReflectionInfo, null, options);
@@ -121,6 +131,7 @@ namespace Grpc.Reflection.V1Alpha {
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
     public static ServerServiceDefinition BindService(ServerReflectionBase serviceImpl)
     {
       return ServerServiceDefinition.CreateBuilder()
-- 
GitLab


From 68a9e38c56bb76e31de1d10b900c34474a1be4c0 Mon Sep 17 00:00:00 2001
From: David Garcia Quintas <dgq@google.com>
Date: Tue, 13 Dec 2016 10:50:40 -0800
Subject: [PATCH 133/344] Short deadlines: set Status on deadline

---
 src/core/ext/client_channel/client_channel.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 1fcff4388a..4b3d8951d7 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -683,9 +683,15 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
                                      "Failed to create subchannel", &error, 1));
   } else if (GET_CALL(calld) == CANCELLED_CALL) {
     /* already cancelled before subchannel became ready */
-    fail_locked(exec_ctx, calld,
-                GRPC_ERROR_CREATE_REFERENCING(
-                    "Cancelled before creating subchannel", &error, 1));
+    grpc_error *cancellation_error = GRPC_ERROR_CREATE_REFERENCING(
+        "Cancelled before creating subchannel", &error, 1);
+    /* if due to deadline, attach the deadline exceeded status to the error */
+    if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
+      cancellation_error =
+          grpc_error_set_int(cancellation_error, GRPC_ERROR_INT_GRPC_STATUS,
+                             GRPC_STATUS_DEADLINE_EXCEEDED);
+    }
+    fail_locked(exec_ctx, calld, cancellation_error);
   } else {
     /* Create call on subchannel. */
     grpc_subchannel_call *subchannel_call = NULL;
@@ -809,7 +815,6 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
         initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
       }
     }
-    // TODO(dgq): make this deadline configurable somehow.
     const grpc_lb_policy_pick_args inputs = {
         initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem,
         gpr_inf_future(GPR_CLOCK_MONOTONIC)};
-- 
GitLab


From 5eebc93b1d7bf0f1e878ce2193c6e58d9e637211 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Tue, 13 Dec 2016 18:05:33 -0800
Subject: [PATCH 134/344] Make event order consistent, and make 'end' and
 'error' mutually exclusive

---
 src/node/src/client.js        | 13 ++++++++-----
 src/node/test/surface_test.js |  8 ++++----
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/node/src/client.js b/src/node/src/client.js
index 9c1562e8b8..0f85f2c63a 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -184,14 +184,15 @@ function _emitStatusIfDone() {
     } else {
       status = this.received_status;
     }
-    this.emit('status', status);
-    if (status.code !== grpc.status.OK) {
+    if (status.code === grpc.status.OK) {
+      this.push(null);
+    } else {
       var error = new Error(status.details);
       error.code = status.code;
       error.metadata = status.metadata;
       this.emit('error', error);
-      return;
     }
+    this.emit('status', status);
   }
 }
 
@@ -224,9 +225,11 @@ function _read(size) {
     } catch (e) {
       self._readsDone({code: grpc.status.INTERNAL,
                        details: 'Failed to parse server response'});
+      return;
     }
     if (data === null) {
       self._readsDone();
+      return;
     }
     if (self.push(deserialized) && data !== null) {
       var read_batch = {};
@@ -396,6 +399,8 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
       var status = response.status;
       var error;
       var deserialized;
+      emitter.emit('metadata', Metadata._fromCoreRepresentation(
+          response.metadata));
       if (status.code === grpc.status.OK) {
         if (err) {
           // Got a batch error, but OK status. Something went wrong
@@ -423,8 +428,6 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
         args.callback(null, deserialized);
       }
       emitter.emit('status', status);
-      emitter.emit('metadata', Metadata._fromCoreRepresentation(
-          response.metadata));
     });
     return emitter;
   }
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index d8b36dc55c..2a42dd5db5 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -179,8 +179,8 @@ describe('Server.prototype.addProtoService', function() {
       call.on('data', function(value) {
         assert.fail('No messages expected');
       });
-      call.on('status', function(status) {
-        assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED);
+      call.on('error', function(err) {
+        assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
         done();
       });
     });
@@ -189,8 +189,8 @@ describe('Server.prototype.addProtoService', function() {
       call.on('data', function(value) {
         assert.fail('No messages expected');
       });
-      call.on('status', function(status) {
-        assert.strictEqual(status.code, grpc.status.UNIMPLEMENTED);
+      call.on('error', function(err) {
+        assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
         done();
       });
       call.end();
-- 
GitLab


From 78246df236e46c1a6d7c59f43040f646a7cdc6a5 Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Tue, 13 Dec 2016 16:49:55 -0800
Subject: [PATCH 135/344] Add GRPC_CONTEXT_TRAFFIC in grpc_context_index

---
 src/core/lib/channel/context.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h
index 071c5f695c..6c931ad28a 100644
--- a/src/core/lib/channel/context.h
+++ b/src/core/lib/channel/context.h
@@ -47,6 +47,9 @@ typedef enum {
   /// Value is a \a census_context.
   GRPC_CONTEXT_TRACING,
 
+  /// Reserved for traffic_class_context.
+  GRPC_CONTEXT_TRAFFIC,
+
   GRPC_CONTEXT_COUNT
 } grpc_context_index;
 
-- 
GitLab


From 3cadfb152fee3160be689ee4545e15dfcf8ebd37 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 07:52:47 -0800
Subject: [PATCH 136/344] Started updating docs.

---
 doc/images/load-balancing.svg        |   4 +
 doc/images/load_balancing_design.png | Bin 40354 -> 0 bytes
 doc/load-balancing.md                | 128 +++++++++--------
 doc/naming.md                        |  49 +++++--
 doc/service_config.md                | 201 +++++++++++++++++++++++++++
 5 files changed, 317 insertions(+), 65 deletions(-)
 create mode 100644 doc/images/load-balancing.svg
 delete mode 100644 doc/images/load_balancing_design.png
 create mode 100644 doc/service_config.md

diff --git a/doc/images/load-balancing.svg b/doc/images/load-balancing.svg
new file mode 100644
index 0000000000..425a9d33aa
--- /dev/null
+++ b/doc/images/load-balancing.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="yes"?>
+
+<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,3.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path fill="#000000" d="m268.05804 127.32641l1.609375 0.25q0.109375 0.7500076 0.578125 1.0937576q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.2812576q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.2656326q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.3906326zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm18.65625 0l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm3.5198364 4.765625l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.191681 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.879181 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.110107 5.875l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm14.031982 -1.5l0.234375 1.484375q-0.703125 0.140625 -1.265625 0.140625q-0.90625 0 -1.40625 -0.28125q-0.5 -0.296875 -0.703125 -0.75q-0.203125 -0.46875 -0.203125 -1.984375l0 -5.65625l-1.234375 0l0 -1.3125l1.234375 0l0 -2.4375l1.65625 -1.0l0 3.4375l1.6875 0l0 1.3125l-1.6875 0l0 5.75q0 0.71875 0.078125 0.921875q0.09375 0.203125 0.296875 0.328125q0.203125 0.125 0.578125 0.125q0.265625 0 0.734375 -0.078125z" fill-rule="nonzero"></path><path fill="#93c47d" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path fill="#000000" d="m273.87787 196.37569l1.453125 0.21875q0.09375 0.671875 0.515625 0.96875q0.546875 0.421875 1.515625 0.421875q1.03125 0 1.59375 -0.421875q0.5625 -0.40625 0.765625 -1.15625q0.125 -0.453125 0.109375 -1.921875q-0.984375 1.15625 -2.4375 1.15625q-1.8125 0 -2.8125 -1.3125q-1.0 -1.3125 -1.0 -3.140625q0 -1.265625 0.453125 -2.328125q0.46875 -1.078125 1.328125 -1.65625q0.875 -0.578125 2.03125 -0.578125q1.5625 0 2.578125 1.265625l0 -1.0625l1.375 0l0 7.609375q0 2.0625 -0.421875 2.921875q-0.40625 0.859375 -1.328125 1.359375q-0.90625 0.5 -2.234375 0.5q-1.578125 0 -2.546875 -0.71875q-0.96875 -0.703125 -0.9375 -2.125zm1.234375 -5.296875q0 1.734375 0.6875 2.53125q0.703125 0.796875 1.734375 0.796875q1.03125 0 1.71875 -0.796875q0.703125 -0.796875 0.703125 -2.484375q0 -1.625 -0.71875 -2.4375q-0.71875 -0.828125 -1.734375 -0.828125q-0.984375 0 -1.6875 0.8125q-0.703125 0.8125 -0.703125 2.40625zm8.90271 4.5625l0 -12.171875l5.390625 0q1.625 0 2.46875 0.328125q0.84375 0.328125 1.34375 1.15625q0.515625 0.828125 0.515625 1.84375q0 1.296875 -0.84375 2.1875q-0.828125 0.875 -2.578125 1.125q0.640625 0.296875 0.96875 0.59375q0.703125 0.65625 1.328125 1.625l2.125 3.3125l-2.03125 0l-1.609375 -2.53125q-0.703125 -1.09375 -1.15625 -1.671875q-0.453125 -0.59375 -0.828125 -0.8125q-0.359375 -0.234375 -0.71875 -0.328125q-0.28125 -0.0625 -0.90625 -0.0625l-1.859375 0l0 5.40625l-1.609375 0zm1.609375 -6.796875l3.453125 0q1.109375 0 1.71875 -0.21875q0.625 -0.234375 0.953125 -0.734375q0.328125 -0.515625 0.328125 -1.09375q0 -0.875 -0.625 -1.421875q-0.625 -0.5625 -1.984375 -0.5625l-3.84375 0l0 4.03125zm10.873199 6.796875l0 -12.171875l4.59375 0q1.203125 0 1.84375 0.125q0.90625 0.140625 1.5 0.5625q0.609375 0.421875 0.96875 1.1875q0.375 0.75 0.375 1.640625q0 1.5625 -0.984375 2.640625q-0.984375 1.0625 -3.5625 1.0625l-3.125 0l0 4.953125l-1.609375 0zm1.609375 -6.390625l3.140625 0q1.5625 0 2.21875 -0.578125q0.65625 -0.578125 0.65625 -1.625q0 -0.765625 -0.390625 -1.3125q-0.375 -0.546875 -1.015625 -0.71875q-0.40625 -0.109375 -1.5 -0.109375l-3.109375 0l0 4.34375zm18.635834 2.125l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm17.328156 0l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm3.6075745 4.265625l0 -12.171875l1.484375 0l0 12.171875l-1.484375 0zm3.881012 -10.453125l0 -1.71875l1.5 0l0 1.71875l-1.5 0zm0 10.453125l0 -8.8125l1.5 0l0 8.8125l-1.5 0zm9.881012 -2.84375l1.546875 0.203125q-0.375 1.34375 -1.359375 2.09375q-0.984375 0.75 -2.515625 0.75q-1.9375 0 -3.078125 -1.1875q-1.125 -1.203125 -1.125 -3.34375q0 -2.234375 1.140625 -3.453125q1.140625 -1.234375 2.96875 -1.234375q1.78125 0 2.890625 1.203125q1.125 1.203125 1.125 3.390625q0 0.125 -0.015625 0.390625l-6.5625 0q0.078125 1.453125 0.8125 2.234375q0.75 0.765625 1.84375 0.765625q0.828125 0 1.40625 -0.421875q0.578125 -0.4375 0.921875 -1.390625zm-4.90625 -2.40625l4.921875 0q-0.09375 -1.109375 -0.5625 -1.671875q-0.71875 -0.859375 -1.859375 -0.859375q-1.015625 0 -1.71875 0.6875q-0.703125 0.6875 -0.78125 1.84375zm8.512085 5.25l0 -8.8125l1.34375 0l0 1.25q0.96875 -1.453125 2.796875 -1.453125q0.796875 0 1.46875 0.296875q0.671875 0.28125 1.0 0.75q0.328125 0.453125 0.46875 1.09375q0.078125 0.421875 0.078125 1.453125l0 5.421875l-1.484375 0l0 -5.359375q0 -0.921875 -0.1875 -1.375q-0.171875 -0.453125 -0.625 -0.71875q-0.4375 -0.265625 -1.03125 -0.265625q-0.953125 0 -1.65625 0.609375q-0.6875 0.59375 -0.6875 2.296875l0 4.8125l-1.484375 0zm12.90271 -1.34375l0.203125 1.328125q-0.625 0.125 -1.125 0.125q-0.8125 0 -1.265625 -0.25q-0.4375 -0.265625 -0.625 -0.671875q-0.1875 -0.421875 -0.1875 -1.765625l0 -5.078125l-1.09375 0l0 -1.15625l1.09375 0l0 -2.1875l1.484375 -0.890625l0 3.078125l1.515625 0l0 1.15625l-1.515625 0l0 5.15625q0 0.640625 0.078125 0.828125q0.078125 0.171875 0.25 0.28125q0.1875 0.109375 0.53125 0.109375q0.234375 0 0.65625 -0.0625z" fill-rule="nonzero"></path><path fill="#f1c232" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path fill="#000000" d="m45.465923 185.42131l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm19.707325 -1.21875q-0.9375 0.796875 -1.7968788 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.0312538 -0.25 2.9843788 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.6406288 -0.5625 -1.9062538 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.2656288 0 2.0468788 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.7343788 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.7500038 -0.4375 1.1093788 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.078842 4.9375l0 -9.859375l1.5 0l0 1.390625q0.453125 -0.71875 1.21875 -1.15625q0.78125 -0.453125 1.765625 -0.453125q1.09375 0 1.796875 0.453125q0.703125 0.453125 0.984375 1.28125q1.171875 -1.734375 3.046875 -1.734375q1.46875 0 2.25 0.8125q0.796875 0.8125 0.796875 2.5l0 6.765625l-1.671875 0l0 -6.203125q0 -1.0 -0.15625 -1.4375q-0.15625 -0.453125 -0.59375 -0.71875q-0.421875 -0.265625 -1.0 -0.265625q-1.03125 0 -1.71875 0.6875q-0.6875 0.6875 -0.6875 2.21875l0 5.71875l-1.671875 0l0 -6.40625q0 -1.109375 -0.40625 -1.65625q-0.40625 -0.5625 -1.34375 -0.5625q-0.703125 0 -1.3125 0.375q-0.59375 0.359375 -0.859375 1.078125q-0.265625 0.71875 -0.265625 2.0625l0 5.109375l-1.671875 0zm22.290802 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm14.543396 5.875l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm18.176071 4.421875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.438217 2.9375l1.65625 -0.265625q0.140625 1.0 0.765625 1.53125q0.640625 0.515625 1.78125 0.515625q1.15625 0 1.703125 -0.46875q0.5625 -0.46875 0.5625 -1.09375q0 -0.5625 -0.484375 -0.890625q-0.34375 -0.21875 -1.703125 -0.5625q-1.84375 -0.46875 -2.5625 -0.796875q-0.703125 -0.34375 -1.078125 -0.9375q-0.359375 -0.609375 -0.359375 -1.328125q0 -0.65625 0.296875 -1.21875q0.3125 -0.5625 0.828125 -0.9375q0.390625 -0.28125 1.0625 -0.484375q0.671875 -0.203125 1.4375 -0.203125q1.171875 0 2.046875 0.34375q0.875 0.328125 1.28125 0.90625q0.421875 0.5625 0.578125 1.515625l-1.625 0.21875q-0.109375 -0.75 -0.65625 -1.171875q-0.53125 -0.4375 -1.5 -0.4375q-1.15625 0 -1.640625 0.390625q-0.484375 0.375 -0.484375 0.875q0 0.328125 0.203125 0.59375q0.203125 0.265625 0.640625 0.4375q0.25 0.09375 1.46875 0.4375q1.765625 0.46875 2.46875 0.765625q0.703125 0.296875 1.09375 0.875q0.40625 0.578125 0.40625 1.4375q0 0.828125 -0.484375 1.578125q-0.484375 0.734375 -1.40625 1.140625q-0.921875 0.390625 -2.078125 0.390625q-1.921875 0 -2.9375 -0.796875q-1.0 -0.796875 -1.28125 -2.359375zm9.375 -1.984375q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250717 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm6.910446 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" d="m73.85669 211.42131q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm9.775177 -7.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.813217 6.6875l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm14.699646 5.109375l0 -13.59375l4.6875 0q1.578125 0 2.421875 0.1875q1.15625 0.265625 1.984375 0.96875q1.078125 0.921875 1.609375 2.34375q0.53125 1.40625 0.53125 3.21875q0 1.546875 -0.359375 2.75q-0.359375 1.1875 -0.921875 1.984375q-0.5625 0.78125 -1.234375 1.234375q-0.671875 0.4375 -1.625 0.671875q-0.953125 0.234375 -2.1875 0.234375l-4.90625 0zm1.796875 -1.609375l2.90625 0q1.34375 0 2.109375 -0.25q0.765625 -0.25 1.21875 -0.703125q0.640625 -0.640625 1.0 -1.71875q0.359375 -1.078125 0.359375 -2.625q0 -2.125 -0.703125 -3.265625q-0.703125 -1.15625 -1.703125 -1.546875q-0.71875 -0.28125 -2.328125 -0.28125l-2.859375 0l0 10.390625zm11.660446 1.609375l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm12.879196 -4.375l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm13.927948 8.375l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m248.70341 189.50131l-62.29921 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m236.70341 189.50131l-38.29921 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m236.70341 192.80478l9.076187 -3.3034668l-9.076187 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m198.4042 186.19785l-9.076202 3.3034668l9.076202 3.3034668z" fill-rule="evenodd"></path><path fill="#e06666" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m492.37677 197.23381l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.281952 5.109375l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm6.228302 3.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm15.297607 1.265625l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.859375 3.609375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm5.7229614 0l-1.546875 0l0 -13.59375l1.65625 0l0 4.84375q1.0625 -1.328125 2.703125 -1.328125q0.90625 0 1.71875 0.375q0.8125 0.359375 1.328125 1.03125q0.53125 0.65625 0.828125 1.59375q0.296875 0.9375 0.296875 2.0q0 2.53125 -1.25 3.921875q-1.25 1.375 -3.0 1.375q-1.75 0 -2.734375 -1.453125l0 1.234375zm-0.015625 -5.0q0 1.765625 0.46875 2.5625q0.796875 1.28125 2.140625 1.28125q1.09375 0 1.890625 -0.9375q0.796875 -0.953125 0.796875 -2.84375q0 -1.921875 -0.765625 -2.84375q-0.765625 -0.921875 -1.84375 -0.921875q-1.09375 0 -1.890625 0.953125q-0.796875 0.953125 -0.796875 2.75zm14.027771 8.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm8.235046 -0.046875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250732 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.1917114 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.566711 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.8125 7.40625l-0.171875 -1.5625q0.546875 0.140625 0.953125 0.140625q0.546875 0 0.875 -0.1875q0.34375 -0.1875 0.5625 -0.515625q0.15625 -0.25 0.5 -1.25q0.046875 -0.140625 0.15625 -0.40625l-3.734375 -9.875l1.796875 0l2.046875 5.71875q0.40625 1.078125 0.71875 2.28125q0.28125 -1.15625 0.6875 -2.25l2.09375 -5.75l1.671875 0l-3.75 10.03125q-0.59375 1.625 -0.9375 2.234375q-0.4375 0.828125 -1.015625 1.203125q-0.578125 0.390625 -1.375 0.390625q-0.484375 0 -1.078125 -0.203125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m195.75066 158.99738l27.716537 0l0 32.53543l-27.716537 0z" fill-rule="nonzero"></path><path fill="#000000" d="m210.74643 180.79738l-1.140625 0l0 -7.28125q-0.421875 0.390625 -1.09375 0.796875q-0.65625 0.390625 -1.1875 0.578125l0 -1.109375q0.953125 -0.4375 1.671875 -1.078125q0.71875 -0.640625 1.015625 -1.25l0.734375 0l0 9.34375z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m392.7034 189.50131l82.39371 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m404.7034 189.50131l58.393707 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m404.7034 186.19785l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m463.0971 192.80478l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m489.2755 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644836 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349792 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.34375 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584229 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094421 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.9627075 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m266.83298 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.3437805 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094452 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962677 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l-215.08661 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m311.25372 227.40143l-196.18726 153.55408" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m313.28983 230.00282l5.1111755 -8.195496l-9.18335 2.9927216z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m113.030396 378.35413l-5.111183 8.195496l9.18335 -2.9927063z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l0.12600708 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m320.7124 232.00525l0.10800171 144.34647" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m324.01587 232.00278l-3.3102722 -9.07373l-3.2966614 9.078674z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m317.51694 376.3542l3.3102722 9.07373l3.2966614 -9.078674z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l222.58267 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m330.27423 227.24397l203.44104 153.869" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m332.267 224.60924l-9.231659 -2.840271l5.246155 8.109756z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m531.72253 383.7477l9.231628 2.840271l-5.246155 -8.109741z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m412.22308 158.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m434.8905 179.70363l0 1.09375l-6.15625 0q-0.015625 -0.40625 0.140625 -0.796875q0.234375 -0.625 0.75 -1.234375q0.515625 -0.609375 1.5 -1.40625q1.515625 -1.25 2.046875 -1.96875q0.53125 -0.734375 0.53125 -1.375q0 -0.6875 -0.484375 -1.140625q-0.484375 -0.46875 -1.265625 -0.46875q-0.828125 0 -1.328125 0.5q-0.484375 0.484375 -0.5 1.359375l-1.171875 -0.125q0.125 -1.3125 0.90625 -2.0q0.78125 -0.6875 2.109375 -0.6875q1.34375 0 2.125 0.75q0.78125 0.734375 0.78125 1.828125q0 0.5625 -0.234375 1.109375q-0.21875 0.53125 -0.75 1.140625q-0.53125 0.59375 -1.765625 1.625q-1.03125 0.859375 -1.328125 1.171875q-0.28125 0.3125 -0.46875 0.625l4.5625 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m287.22308 247.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m303.8905 267.35986l1.1875 -0.109375q0.140625 0.890625 0.625 1.328125q0.484375 0.4375 1.171875 0.4375q0.828125 0 1.390625 -0.625q0.578125 -0.625 0.578125 -1.640625q0 -0.984375 -0.546875 -1.546875q-0.546875 -0.5625 -1.4375 -0.5625q-0.5625 0 -1.015625 0.25q-0.4375 0.25 -0.6875 0.640625l-1.0625 -0.140625l0.890625 -4.765625l4.625 0l0 1.078125l-3.703125 0l-0.5 2.5q0.828125 -0.578125 1.75 -0.578125q1.21875 0 2.046875 0.84375q0.84375 0.84375 0.84375 2.171875q0 1.265625 -0.734375 2.1875q-0.890625 1.125 -2.4375 1.125q-1.265625 0 -2.078125 -0.703125q-0.796875 -0.71875 -0.90625 -1.890625z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m629.2467 241.13911l39.653564 0l0 32.535416l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m638.7936 260.486l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875153q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.2500153l-1.140625 -0.203125q0.21875 -1.1406403 0.953125 -1.7656403q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.2031403q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625zm8.021851 2.453125l0 -1.296875l1.296875 0l0 1.296875q0 0.71875 -0.25 1.15625q-0.25 0.4375 -0.8125 0.6875l-0.3125 -0.484375q0.359375 -0.171875 0.53125 -0.484375q0.171875 -0.296875 0.1875 -0.875l-0.640625 0zm3.093628 -2.4375l1.1875 -0.109375q0.140625 0.890625 0.625 1.328125q0.484375 0.4375 1.171875 0.4375q0.828125 0 1.390625 -0.625q0.578125 -0.625 0.578125 -1.640625q0 -0.984375 -0.546875 -1.546875q-0.546875 -0.5625 -1.4375 -0.5625q-0.5625 0 -1.015625 0.25q-0.4375 0.25 -0.6875 0.640625l-1.0625 -0.140625l0.890625 -4.7656403l4.625 0l0 1.078125l-3.703125 0l-0.5 2.5000153q0.828125 -0.578125 1.75 -0.578125q1.21875 0 2.046875 0.84375q0.84375 0.84375 0.84375 2.171875q0 1.265625 -0.734375 2.1875q-0.890625 1.125 -2.4375 1.125q-1.265625 0 -2.078125 -0.703125q-0.796875 -0.71875 -0.90625 -1.890625z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m44.392044 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547592 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644821 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.343758 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962669 0l-3.7499924 -9.859375l1.7656174 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#6d9eeb" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m760.14105 300.09717l0 -13.59375l1.796875 0l0 11.984375l6.703125 0l0 1.609375l-8.5 0zm9.610046 -4.921875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.031311 0 3.312561 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375061 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.250061 0 2.062561 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.062561 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm15.719482 3.703125q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm10.469482 4.9375l0 -1.25q-0.9375 1.46875 -2.75 1.46875q-1.171875 0 -2.171875 -0.640625q-0.984375 -0.65625 -1.53125 -1.8125q-0.53125 -1.171875 -0.53125 -2.6875q0 -1.46875 0.484375 -2.671875q0.5 -1.203125 1.46875 -1.84375q0.984375 -0.640625 2.203125 -0.640625q0.890625 0 1.578125 0.375q0.703125 0.375 1.140625 0.984375l0 -4.875l1.65625 0l0 13.59375l-1.546875 0zm-5.28125 -4.921875q0 1.890625 0.796875 2.828125q0.8125 0.9375 1.890625 0.9375q1.09375 0 1.859375 -0.890625q0.765625 -0.890625 0.765625 -2.734375q0 -2.015625 -0.78125 -2.953125q-0.78125 -0.953125 -1.921875 -0.953125q-1.109375 0 -1.859375 0.90625q-0.75 0.90625 -0.75 2.859375z" fill-rule="nonzero"></path><path fill="#000000" d="m744.0764 322.09717l0 -13.59375l5.109375 0q1.546875 0 2.484375 0.40625q0.953125 0.40625 1.484375 1.265625q0.53125 0.859375 0.53125 1.796875q0 0.875 -0.46875 1.65625q-0.46875 0.765625 -1.4375 1.234375q1.234375 0.359375 1.890625 1.234375q0.671875 0.875 0.671875 2.0625q0 0.953125 -0.40625 1.78125q-0.390625 0.8125 -0.984375 1.265625q-0.59375 0.4375 -1.5 0.671875q-0.890625 0.21875 -2.1875 0.21875l-5.1875 0zm1.796875 -7.890625l2.9375 0q1.203125 0 1.71875 -0.15625q0.6875 -0.203125 1.03125 -0.671875q0.359375 -0.46875 0.359375 -1.1875q0 -0.671875 -0.328125 -1.1875q-0.328125 -0.515625 -0.9375 -0.703125q-0.59375 -0.203125 -2.0625 -0.203125l-2.71875 0l0 4.109375zm0 6.28125l3.390625 0q0.875 0 1.21875 -0.0625q0.625 -0.109375 1.046875 -0.359375q0.421875 -0.265625 0.6875 -0.765625q0.265625 -0.5 0.265625 -1.140625q0 -0.765625 -0.390625 -1.328125q-0.390625 -0.5625 -1.078125 -0.78125q-0.6875 -0.234375 -1.984375 -0.234375l-3.15625 0l0 4.671875zm16.943604 0.390625q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0476074 4.9375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm10.613525 -1.21875q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0788574 4.9375l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm16.813232 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm9.640625 0.4375l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 -84.15747" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m700.5833 298.80334l-146.57245 -73.40985" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m699.104 301.75708l9.5946045 1.1107483l-6.6359253 -7.0181885z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m555.49023 222.43977l-9.5946045 -1.1107635l6.6359253 7.0181885z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-612.9134 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.4244 305.80954l-589.1365 80.89273" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m699.8737 309.0823l8.54248 -4.507416l-9.441223 -2.0381165z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m109.83856 383.4295l-8.54245 4.507416l9.4412 2.0381165z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-390.4882 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.5822 306.70535l-367.02686 79.101105" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m700.27814 309.93466l8.176514 -5.14151l-9.568481 -1.3171387z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m331.85934 382.57715l-8.176483 5.14151l9.568451 1.3171387z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m700.5833 309.55096l-146.57245 73.40988" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m702.0627 312.50467l6.6359253 -7.0181885l-9.5946045 1.1107788z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m552.53156 380.00714l-6.6359253 7.0181885l9.5946045 -1.1107788z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m538.70605 294.4908l39.653503 0l0 32.53543l-39.653503 0z" fill-rule="nonzero"></path><path fill="#000000" d="m559.0297 316.2908l0 -2.234375l-4.03125 0l0 -1.046875l4.234375 -6.03125l0.9375 0l0 6.03125l1.265625 0l0 1.046875l-1.265625 0l0 2.234375l-1.140625 0zm0 -3.28125l0 -4.1875l-2.921875 4.1875l2.921875 0z" fill-rule="nonzero"></path></g></svg>
+
diff --git a/doc/images/load_balancing_design.png b/doc/images/load_balancing_design.png
deleted file mode 100644
index 86183966fb88e24a5a86dbd4b62ae2a308d0a542..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 40354
zcmbrmgL_=j_CK69ZW^nx8mqC@*bN#x6Wg|JvvC^RYHZuK?cd40-~0Xp@6+a)$?43V
zGkfj5*7{&K<d=*n{1@ymU|?YI;$lMbU|^qB!N5Lo!axC6NUcTbfCnf&Nl_uN_m4l>
zZG~~b6<BLARXZ>+IMk1yPhhF(-++tI_TtjQ&>PT*2za#KZ#vLmV1!`eLIR4;OD7pF
zD)GBd{d`Q_jGZtrIp$xAU_w#y$Wkc`>57^_mWNfd3Xave9Y?k4oJvadnKab0swtTx
zw4-=7up090rqQ7|p}{aPzTV(pmq*T{oD6l6KgkKGW{x|I=C?j`U(>DMd!FsP`SBAX
z!9aZW`TzZ3j6QJGw1P(Xi#cfn!3JA}Bvs&J<WZ~=*Ds~BImHl8pNMKdK4>CGSc$N+
zbAr`Bs7NRb7CYfJ#1!GX23w}nf9|3d6a&fc92}~gb%8`nW~`BDfGw2xpSv5yZZiJA
z8}$wBmtY2l%0u##f@tvj#%ya;-rdGu8gPi*sZ*s@qAnXu<CC4Tvd~M2Dj-PcuSB91
zWaoBoXnDS7IE{(NGnA7n+UrW|!IMEZ=X5wl^b-UNF&f4X_Wq0DMbJao48}5a$6qlP
zl@5EHr0Y~ONH;Un-$i9iu-vRUKd3>a!k~g2xT%To3&dN}t3iPrA_%sA#BV~08+Qv_
zq=bYvz8zj-$%XsUW#9G=2S>|E=FHxXVPi-?W?JAi_?3c~Sgvq7Ah-Yt=D!zx_^qLX
zhX-`}1K`@l#ILH@)U;IC|1T^vq96mqD}DJ`dWWc=XvC8LjaN1U^8cRl1K;&yg0K^U
zy?XirdkjFqiT@i|0G!czG=+)CCM6|@6yoD+{&xod_pyXRO5NF%)3J%aMJxq`%ZAYs
z#DE{;wBOrU?P>Y4A~G&<Tx&S52xY+?VPwEZL?Cy%>k!wuF}$G;8i`GafiTcxJYQYo
zI19KV0&kAziziIeELs9xoG+Yz{i2euI%uJ<j{J^3X?6t*#p@FK*&)Bzfc3OZq+*bK
zq4r*_#?-vqspjU8_mUkCUkbD}yw9FiV1m-W47`5r<;m8p<9-AhBSigTHNQ45ymiF=
zss_%=1!qZu)+Oa}$6!xEYwkr0AGnydYqRbh(3$k~&Ii|{f~1DrDcRY-C1K1>X0bNX
z`MV@_hM|oBvmbaiKt*NRPCPsv*8ufZEFWJa&l(zUoym5{#lnVDyJK&9OJ<K@b1WRe
zi7`bfyBy@?PSmmu$B_~%wQ_~eUW~Ri)ZzAUWObyQLpkzz_&VBS^*(LhTo-|U+NycL
z(V4|iLmW+=cV7+M>z=Hdd3|e!L`X>x(>?FEo{3`JzFqk5<Qm_Pg4)Pf?$VdJ812=(
zh{;x!t!z;0%n3xD$mP`J4Y|kM2)^pQtm6yqg0%CC$Z7ldW`eLPq9Ap~Iw8YdZLM=>
z0%w#=Ia;sTUy09~HmgZZ;jhVQ_aYK%Y_1(mC=2DdHhy;!uorr@gNRdD&x-3;6kLh!
zO5a?=QI)f^^KJWu5)*#*4Haqh39~chbSQ+G_GoFII@{-!EZ!_e)$TV1V5(vz3>UOL
zj^LhBjWxFPvu{9LkXcJG2N@W?*p&{hqZ=foKfKbkcs^yI)CE$~M=++G6CC+@6;%w@
zGKtDBw1N;H7XzeH*{0ZE@1?yepSCR?pj<8&I{LPE_QX`hv25hLs^6}SfyiOKH$WeA
zw^L(QT=k~E=akJbZe3ctyEz};yZ9{BUFMN#?)6$_cFN?}Hnw{eA=2ST*uAUXFCxhF
zWmO~%aH4zRD<keFey;>8|7_vo{<<#l%2bfO#5mST!e68n&qD(2)8JAlov|4N8r7uH
z71^mHyxFE$<*_?($n>_NKSe^4M)c}|h}L;QSs6Adg8ef)8YMa>I!3H7juF6b6c#&D
z_<KL;y||bS)aK5b`(pBlxmQb5xK{$kwCc&88EEXdo4!#8gtrSIgyWrrC;W7Lmc4^9
zQWDvXjnQ<JeCBrf<DUTy$B|ahH9eYoF~R!vY_-pvk1|Pe(UCAqfpW@L@Z2uXtMc#M
zb||kRzfW`QVE2gCRZwJcQ?%SrH)5@@2?-llB=BM3Uz`{p@j@kP&6nIFDz&I$r<qUK
zRrrmw!J{JWO`;vm!FVe$CQ)X5Nqwx}8{Jf|w#IQ+VmlX%2!0^{c>B|CDEDW89Qv|1
z9UXVUIUZQ3l?s%DQiF!49l0MXR~3#tO{mcq>Y+xjOXRMUQ%Fq6$=$Ejl&2jXj`brh
z_s9JQ8`EP#+>ekhmswt=WJf_B+%NyE!;U*DoegvAR!8k$GdOI0&R&~qdlUu;D|w;%
zz}G*C{vFNA@ml17rx87paaX0ENd4kg2m$dOND{SwKTihLR4*iD$`q(cdxybwyL((Z
z*faAvU0;1%G}R?iV#Lx+&j`7>?jBuR12z4tW@IHJx7%A{;l{=Nwq93)q#7a4Mxefy
zyxWDNty!+zu(<~;TeWDaRele1O4`{f_v7Cf?nzy-^B&<_8y(BGAsq4psTnT7%y}24
zv0!oRy0_7#p~G?3INzd2l45S>$w$X1jA52kAhj?@TV~`z_bxKSZ|{-D#VE)Ct3X21
z;o}WjZ;qw!jnsG=rB>%X(y>pOcqb+JR7TUxQtpSiCaMMwXLgHwC9OA$q_`(LHwWhZ
zXAeJlwPJc3ftArZz1Y~6-?4Xbgn6h!33_;5sCMweBB&V98?wf1_Z;od8Q_S{-V2*m
zzBn)X&OC9m<!rerT#Cl1Z-2IW&iLRgjDg^2>-&1T*vyv|FwE$3Z6doTa}LIDDF9is
z-Z2orNmsg<LhiAj;Ua}US6>`lswC;@NYtW)|DA~x#|(%1i4RR8M9r@`+h2DYdd3U~
z51fYs%PTYXI8`lIr~sKn8z_9Sah?$}KKLig)({r?i9y=mEaw7Xe%z%%)5x$jH4(J&
zFC9vear2D`>HNkt^CP>fV;}F7J+~rb=l0&X0NbwRyZdg#{=}Y7YQWCE%%me#6avOs
z|Nd2Z$`%%XA>sfXdSINcXKpMonDQ0o;1s&EJONsq!!ac1MbFdKi|MuBe~PqGzpUSe
z@r_%-ObAka!EP5KTi^&qLz`CZmiZ$0?cGLfH8ko|7VDqwsQ)XdbzfqB|CznIT5Eer
zO%KnFfM2s%s@#2X;eA<ue^7pZ8~OT$k?#30hJ@yA8xhyS{9x-us##51#)csamv^MO
zN*~rbCUbcI`Z}e`0w+aS7^1N;x^S}cI|DKSTuxcOohU7?A>ULcu+vM!he)4(36u?^
zCm6fDb%)vCRqvkkY2iM!a|L-Fb^Y00t&$&jI4Pti8#daBw<E1ck2`j=b+?dpq=(JU
zk?+r~$SRC$fu~gW<)~}N4AZ^@^3ZU#v~t8`UI=|gZmpE)NrO+{tNBA7^&qCC%Vut^
zt49S;JQolC#bHXQ)LwnbDr@zPlh8#AKu_Q-XtmWET2w>PS=rwke-Rg_->o<=z)pJJ
zS3dmu^><7)X)>O+<Mz%|CO1bpUYg$ZqMIT%OZC22z{mQ0g5t2Y^^iqyU(blA?RvS@
zWt%%0(VrZm#)x{P*Z=;h&QUp26^(k=mU5azGeU2k@FbQ^qTj|*pZ=qIyr&Htc5DOt
zsr8wS9z_YV>dud@Pb_)kESrvEZ@aK#f8mYE9`RVBpI_GVO@~^&BVt!^rODMI7bxdF
z3knOx@$3y1>(Y$-)%IFg&3nMY+d4hhGP_T<a}zae<*gs1m@96)2D9&|uqzt|>PhT#
z|El`&%fqRcEl1N)>cYdUWnxDSato`3FEr%mi`y{1>*oT#@L>&^_J4n9Vcnlb7)vcm
z4{%pP(ue0Cp58slSj4f#whp$u%QE0?18|j{jLc6>y*P%Y1`8-UlFR?_(%#mVOo$e*
zL3j#ai^EKy9{9ya<xhLL9t9+A&|LzH2UuGp`T_zk40dG8<T5)GH;4Z9R^uI>?|6RK
z9zPvf!`>hK<TALf`$tk<I6b+8j7B!5gJHf552-kA`P-yj>*)<l8>{dbew~cs{<n$6
zl#GY+Z*XPBa9zs=3#--PBAfme7thRr9C1v7X#05H9mea*K4Ueo2@+i@%HCiHj6Cj<
z=j8+jzII>5wrY_R&d?2ug#VAv-OWYKws~q`)V?D#?*Rec;lFf5dTh~Wi?uXaH6^St
zts@Z1D3)s$Nt8(QMR!3-o(3Juu~zBe{BiZ8t7d(#OWVt-%1d?B<w89H1tAdb^S9A3
zV5#@*Lfu<-D{QYk=-r~rXi@y}3u6%`Ra12Q5_jiz3yUa%U`;$BYqHV+v=moPFV+s#
zjC2jwkqr!LEKaV_HOBG{G7`WVt28vihs(TX9Mf*0Mg+>GNeo@zDc8cF>QyQ|f}=ba
zmBo(xYbqia0>;H{vw0kDi_ag6WG3NI%hjS)h=}pAU1$ng%59*<iTF(Uoj5uw>n#(Z
zQ7!x?nVWW)O6+Z$_{di;)A?Dq##kXlO;D>~Mo>|;nDkuYlM#aUhV_k&Z#Q_j_<=H=
z7AZ*Vei<Vi3_oL;O>7xxFAT^33Q9e7h(YnJKzj#^-&bvhWt6^ir@9e;j_A*d%j`$B
z;u~ob%x`!SKz+X0^B;fImqlq8(7Fk04chS!Ln~onllsed+kplY%gVYM6O%%9*$wm!
z`q=_a$gi(LvY&8#U}yJQz>}iQ337VT-S%@;sAFSctZg<=pU>H3oaCq;^$vdhQ!djx
ztkU;)ag_&Bn946C*_)$)gw`Y8A64pXTHz6-b-%DF-O1>q^f@@V7fUb!MAEmLi3o4t
zCLvLSsRs1-FUj#cVa(Yi_2MBk-QBMutAQCS7Aoxh%M^|BQ<6>g`QhE-!s$|!RR@LW
zCss?lyIbY~Mj>?}VoWfw(kTc<M?=G-6&w3_1$^%LYZk<pQkU?(|NaZp!k4vbn37t3
zC3u~?(#ZQ#9W@nCYo^Szpu)m>n0mQ6rxM<}sOrzg3+H!G!(pBFx;!Jlel^i2Hbo#u
zpB!EvD^;JCAR@_;#c9_{8eL?L5PysJIgBYEdHo*ICR)LC!z&6jSFF8z*E)Qn+jk#t
zS{$CsX$vfgLx(MthCFZkbhkA&>(6fUBjrq2Q;PW4+S^&3qX8B~Tyu8MLL0lWp7t4m
zQ$;U@;>eP--dtZAp9S;-)2_kv*^hu66JeI9Q$BG1cZPztpZCI0s5PvacCeVRAw?*G
zZGRmYIGc;CEziZOp7u^vW%@F5-BiLxWW}NT2uW+aaxs;oz|V<EyT<vCcuQq4Dg_Bf
zQHYNb?CzFWLWhR2PEIXY$Gf|HEG?F8*{R{Y+t1E!9Gsy4ayQ0SXl|>>L=L)!EXsHO
z=?DsXteF}v5f-Ykq-wNhbL4!Exib$PWs7936}tKJdF|n-n&AkPAB~J{95p2(^J&jh
zJ&<B}R0qinuDzrUsi@$jufSxJh)T;N=g2>mXD}khi)&aiOY`6CU}%+JhIEcSSXSA{
zUkA6vrYT11_2Ut8>S~o5rYI}6or}{z+;~=7G6aj^emkx$9r8kc%@DtgT>%IvpOhpk
z4kD+kADCLN#2GAH*WZBr;P&RU`b`+37^fa6R6y?ov=k~8tZfPFn=&1(pNh+NKaY!#
z=bm3^8BS|*r$_ky<(x(Bo|ZAH-s#QyXd|EtR2|z7*pBeyKrT%`BaMvMYFcU8tT1h-
zt}TySzU4>&$l&&@zBKF~Hw)PNedo_%3#Y}K-hWGbcUDP2zmSL9($k}ca-GKU$p5|a
z>jS@6nMV$$hTyHQX<ESTo8OM+zSQrn)(wPTDr#T6+v;}DEJW4Szm$aJ<o8Ejc3*CT
zjy%e7OUqy_tguyCN6hr~@r%nW_<n*|Ze-9I+daCId}K5A&d5z#f0X&D*6vTvD;(@t
zb^{F}3~Xg#O%kmH4oB{L=14;86%-eOxBqVe_@%npuHIDib9=I_ib9vWSH;h-e^E~1
ziFYn!dBUenyMZ7C*tM#%_oo3{?1aZP<JPUbijfKvnyX39IAM+$0-kuPck!>105jdc
z6zQr*_q&|LtXx|ghiW}%uftDsYr<+)QjJVN+*V@O>R;7{AuY{}^iK>+9xFSLGd}Yq
zKUQ42ziy3}IvbIU)2HfsMmBS8Ye%gRuM^Uv=*!6E)Tgs+YbkZ9N6{3#3;qdDLD#jx
zdHchAqUsQA7lL`HFTnoU{e6!fK+M-$Y_e-VV%7*(wBF7r!>&)3C~#ix*^{i1xe}_o
znz_>mZM^e6H+lFg)aDkI!XBE{g<eQlSwX%X9pX;Pl0Ag364bOf0hmci+eMg?Kq7Od
zr;GH_(rUGPf3<gXEC{PX<G*;lQ{U!1z0Lg^MlIxk+!$5|$K|$obyuSW+KIouw4E**
z3tTUklPlhibHQ`5&!YzFS-8t@%0u}5%(Y?dqn}*SMXYHJE>^ts^vyy;yHo0Gcf(Ap
zlvI<c-zV;;oXp-Vb+aaezBs!~l8zOaumcDy2~%^6-#30^jcvdu$*>u<h8c`J!8Z;w
z&k+XRe#6-|M40V0IX3`6a}HkyQgStK9Z_6PBI!X}6I9DkKsmC^h{xqDsQ)(U28@~b
z5=&d2Ll$loofL9eC@_)t;!>=2>~uaK;Ir*!w>JQJXTfee+&}3hMX_sue)4pf-TPQ|
z{3fcKiS3lN)V9-nd)YlH+&h+qpjIn6AT_wR(9Xo(!Z9bQ<8WaT)SR7sRsBT+*g9EL
zv5X%>saxLEeKfkO-Oa(MH6~2|V{B;O!k`)(bxMAHi(4*<E1a|j(m(!bUVPFiCLP$t
zZKdwl>syvDr6bs9r>mOzW(yOeDjEJKbN8){B_3QgWQ`0zY9my6c+_77+YNh;{0vgy
z)le@sp_jJu<S)*qzQ#?l0f6Nr2?NV@H8G%Dl4<pD)2RQCzG<RGq6l*&&Ph0sf#DJj
zt*?HD*euqTGVZx2_W{kGy>(TeszEPeT6y(FKMkr+oO@OLX9rR(%PAWkRuL3&JKkn7
z;ry}2m7D}+_Dqd`03vaSyukUk6ex4XN~4nMQy?`wGFiX@^2#^>cqhnrm3YhgS0GnK
z$7n`oA2M!LSu-kBt6mQ}&Or9=7-3#*zrgpES3mu@TZ9I3wK4OzHgtfeJK)N}{GcG<
zwNFYDpMOi;T!EXvvO)nQp1xiaDbV*NUtLiE13j9a$)@v>!3qONM*n&IVs|A$Wm$y*
z80^SF>Xq29s;)+NHb^~UvK=5ZviMepx@ci*ZGNxLI4M%>#B0n)$7L#;<y|PgxVYY+
z5=&a|i*<OeZjsC8b}9YYi17wPsjg9VJxR97m>QDMT5X5|9txl&axE>;<)6e0)GVr3
zUe>+X7PXC^?;u*5s)#8Eg^YzY8#~t|lhiby)mKl!RjyJIb)zzv#SOh|HMrVWqeok1
z>8iGMK2dQ&2E~Q`N>W6bEQGHTEeD{)OFd7iMn<X1RWp4Jh6drw;Iuy^S9Wa-s@o3d
z7f2en;q!XiZ~!f~KZufx@OmXazBi2ozsWc^tJYk#jY+vb;%>@j8tN1cHOhJutX*}B
z=XZ+dZ|tU=(P$)!U+jGU=Zi=2OBuzfG#G(yt`E0zuv_CJh5#a-pgx3n_4}PJ5kssC
zF1Y*+8fm8YMobxlZa6QgBZHyYXd|TRl-*ux^r}pG5nWrS`t_}=pvl;`AP69C6twY2
z3rOAAD=#SsN%Nh)l)j%E7RobT25h>&_tBR=g1E-rnQs##4f>Ats}v{~Tiz;FtKA2p
z&qka*PT)y?b!~p)zP#%$eRn4h%Y2>$Wu`U2)nLe!Pm`B$M$%Dby51uzwbsOVNk62s
zmQ#gZg~d?sjHt0M=5fn<<a$Cke7_i*srbg_R+Iv*D&vaJap*!j>#sN=R9xn{NwV5}
zDJ}$20WchoFYaq$VcSVHMu&6tw4&A312j}y6<u8-sFQ`Rw_EqaNh$RX)P7tN;6?}<
z?cog)!T@c73HSHJofn7EzgWG2(c)O??EWgJwmOzXRTYSL3h7XT{gHwc{pVm9M2l{q
zqhjlTPWft-;Oj$Vaj;=Z7n-j4#nrJc*Gx3u1`Ehq;@uk2M5Nm4lpyY_Y`CnB6G3Bd
za6FB&OWT^5dh)pDT2uTqDY6LmljZI%drl<$zd6dvhfqspaj_;OnpMg}gB@BS8g%;h
zji^~|GlS-<OC4#UGWdxtJFQF06O*ffK(1S$-hFUgnyT`HXA+ToZq?EV`D&7t)v*%d
z$%7}ABLy@X(E^TIkQTUTQaFeIlq;S#Cd>cQ5*!?hIR}5qK$xl-KA2pLY>IN+C^O=g
z&QW1}Wi{LLb+}X7I>_FrVmQ6HWq!rCZ3?$RwrB##%@}|?VIv@=mpbnB-EWnuuc(cg
zU&OfG<j+}}@W7FL{hJ;H<^|3P4l8}~l!_28{C7Q3dEIQ3Z>B-ZMdmhNAsZSw?im>u
zUu<W4^DFLpTBAisQToZ@Yc?9k(ZpavG!c*WZ6!BS@9KPnH*dxz{8fR4n`mjm9K_9G
zxL1*En_Uvf7E9o@1?A0}fb;%HEUJ>uAK`GUaZwP9y`4>I?zZIgaI%R9pfP&iwX~aW
z??|10fgwsAk2e|-WLrQ_$8vZItU=sd3htU$U}m(F^`GpW{(R{6IQX{VqaBUu5qJxl
zdXLES=>Kaesq91!K+)7X=~0W8=VoN=$&Bo`H~XeSRD{R^dYXLU{Ez2&Ei7YUgH8Tn
zf#sV|T3jC9s@`nYt&n{CmWP~QuW!uPI8+(2{+urBKj5?Qz4GuJZk>cj{Oo!t*E~Eq
zkunj6RF;%DI6fQ0d40yoRRQCTjJ&zO$&)W65iIKyE(RG!;kV*r1ZKsdmODD$7|$c9
z2YklNj}>ip=<ZrdJ;@>FTv%rE>I8#wb=h1kfd9Y}11fex1{N8q$#K^lx8H<*6HuQ$
zcB)tKY!c;Q_=@ZU#REtWuooB?j(Gn}iGRTV@P|B7d$VNF_R;_g5$g*#i`FPN(`+Y#
z`{o5S8XDujnSjj{F%1yBE=EVnU(;;7a?vC(R`7B>7y9oA?&ch5DPlw(Bj&>*@1!4=
zOiGV0WOXz>%DbD|+?X1itZejPM<x&TJd)_}<g<j!gv?-5VWD(c5~%FD_Z(k{#4-hL
zku~7|bzZhT0-$~`jDs4GV)9!{eY?4$wpZ3-E<!wdRA;X)MHruO5x;_~wFqADJdNYE
zAwZU45>-Rc3abb+cWp;Cig(R!K-}DI2lO&=)Ux;hqR-A34uDnHJ*cg8oh3wLmgJ7f
zVbG6mhA;`7mkDb|fc(%<q$7-qzg*7Wi!9+1V9Z+G%wy|AYx;7{sg|ltFb=fpNKw2U
z(*{QeE3LWDR&?jaw6_=j<K}J-tC1iSO3co`!n1~OhA1xC7TG@3FBZisZn=Q+$PJqR
zoo7qD8gtZGhtAiwp>%O!M?wVUUB}NL|Gk7)kTz|r&W^3TJEGH6=iEyqT;=cdq5l91
zARrl6DT1Zl5Rl4i4U&lU8sM3_{9^9iSq;WnnLzKfZR-pbJ~~2%u?&ivEf4Tf+y&j1
z3WC~J|1I}SIV8iqm?9}Xxkd8-A_v%qlSb<<WiOf4i(MhQRH=!t69>I>+Ba5v+df&|
zIfgfQ<;24K_z>LQi%-xStZkj2*{MBE1;FjVoKcJOA_y+HFK{N*H2tstY6hK&VPLrV
zccRRw|4+R7(a1a8&?u%PoF56_p{al15!uMO+En2LaAQ-98H@JH<RxnG(kupQ)z?(k
zm2vZ~rGW-C7KH!?x!gga1I6p*M{n+%m>H6Nk*6I9mB0fE5$z^9D@=JRGMxh|w~}Aw
z-^YRzgcoJ6T()QgP;LD2FU?<4sy0|k^-Ao`MM%uB@;((e1PO0TSh;+%>Wp=oK~4$j
zTY6zE;LB7A>??*uyMTUG)llCjyvPXMfR>mbr=k{`*48#@RZ`TNZiWpXSzq7h8Yb<7
zL0-+P8q+%m{s<@owxajXJIlp=oPI2a0Ez(0Awb3I=&iYYFAkpclI;UH|HfS&Yx$J4
z8mvUst7gQg$WlfzjTY)Cpe~y$85RM617KRxCc#Ujuo75pMYz2J7xI1BXe3s{A(a(&
zsNtpqiG?>;%%s*Qlc52L1l^G3tAMSY)2;PKtN+!t(Uefl_MdQja?L+;mxMT;)7E81
zkS$*rsdeND_gLm{n>=#mglT}dkE|N!<+pa`&*(S4aB+28#nmun5H34y0XR74XD6MW
z?M;ZAcDvh-?cBGW!h2SnsKpCB3<Bqx!DAhrwzui2$G?>LGwJJ|H7ZO<d8xj3KLxR-
zcjx|sf7PfPIyhKEdE9)k!2qPyBL@BOz$z{}jg8&~mDJP@)i4xQpwDz~B@UB*Z+Byr
z7?(D+B2Ki0qgt@3^al9rkPpB_;KULpX0Q{_bUw}OnXKIr)SdZ`&S)k;1&|mI8<1A6
z4ly~(qB0oQy+_m|?o0vjS@s6jR)dfoNga6GBuiKSL`_Z}s?(gaI^5=$_+pwZX;ks7
z@;tjwt+0Se+0OEs0I7vE$NQ<HsNA1Zpnc)Ek7}6*d0IPzt-bwrt(4a$w_bdKk57yT
zy80rUwLp4D6o4nl1b+!}w?%TKA{B=0{XkRs6=l1V%KgbSUR;gN?5G$nQJ3dHH;<w(
zdwKi*I&vLm$XulVHj0-tt-0Kg-4*;GYHmIN;q}h7_3#F&&?1XTD$OCTFU-4m$>gEf
zu_b<e>7kz*v3j8mZ0HyyWS)4N8+vC(sv%F|qb>fQ7oZNHicN}aH*u{p-Jd@L{OzNT
zD%l5@rf&6`X%-%3JiO2~#<tSmp{ylfLPGvj0>-`i_umlEq5W|8Ci!Ugx}31So@t_U
zBy+Wadl;pImVG|QQ6z0dZbYKBVXF<h!^>-l<%ZJWxZyngMkRxKih|vIO<6~(VO`Sz
z!GHOoZnO~osg-G$+VRzXf+F>8Ax;S3Spr8J*Gu{BfEmo<y#_z#TNkgm@J=g-HHHOB
zAXCGWE)&#$*fNXRKP_bTPr_^ZRS}S*p<QNU>9Ci-iqFCajuuhRSqsKX$zAV2H-Ydp
z;!=RT9b8(_1+Wh4_xm*u=+|jxK)yH-4CujA$fYa(zObGdL||-I<z{(4c?{q;A%z0c
zoG6l9XwJ*)NDWtqs)poq#R?In0idC#x9N|4a1=zS;N8?k8BN7M9O_#z`#?L-f{JV-
zq>{rly}jbP#FbwG;#6P5pGo;jY8v6|Egqj%45iRqhA`|&p(WGos_P#INl*c(#%xyr
zC}uX+^+pFXZ{Nwa0C85iVju>fk;~6y02;A;{>}W<9OmG-fAiq4trLUUwvD|UgQ1fD
z;+1VcdR0x3t@%3EQ0Q>>C!s{r6Ge%YR!s`}60Y67i8+WFNK&8(k+?p3O3Yw?$ijMi
z{54xsgRq#34VyoNAA13~g3L`3{igrZlosS+{*D!S%GVt}-;Z60zE}Kc@f+8qFu$B=
zozN<9^qY5v#9%wTD1bW+ha_{Q>f<ugg-@E_8TJlgfT2T6iV~1FwtQRsz+JGfmwy6;
zHIVo<XlQ!YmQuazEkaIK9s^y(0t^gJB&2txwD4W9;oD_oR?c^Y0r=8qAhWk;OU0HH
zvf6CJP93IMTpX{YgtGJpJjT=0@D>Vgcqmvxd=q3z_oXTQ4IlsO;S4Nw)8Xyq^X~9T
zn|(-5=$Aw1*B9%Wie|(-3=CUl>M-5*c5^A2J$FxDV2IHc$GpwAd3l+ktlYfjEEY&1
z03GVTWsU%X2|$Rjpp2niPZ=d0aBY7FV3CynLY$Sh&Pgi>P+M&e8dFoO3VvK`Q;vAP
z6E7p|tj}F?EDT~{ZiWMJ(?@7}r3^ryt*@n+0F^%S%zPTS{N=8JoTM;aRtfZnayoVN
zUALWJnfIP8jn~$j1hy~?&}@;Ns<?unoMG6@-qp=?Qz9CgFKee$K4gWdxC$h03M3%8
zXpg80oTNIB5ws{)SZFjkCjhUo|5EB@F?F*;-RFM?fXbP?VThaClHcw?nDwVxV;uI>
zR_O}2#^YjQr7yBOIg_}&PEelb2n+|q__l#gw2k0I+)x660O<Xc>6CW8&zG(J>Gw*r
zb83Az1bl$ZQ**a2N8@HDShn1r?j8WhA=vL@!z26M{YkM%ZW7wRmXie4Q65g3cH@(N
zXWLe9clPBPcFexPi;BrKQa~tClhzak1I5pGb>(lSoEoj&-HGnMz6cr~$8aVWmydWP
zcszfrvc%))?X9z<C*n#Ao-J`PSm(VfD71Sy`u&mT{UdN58Hu_YSH@-(0fKt>wUPb9
zY>{}q|G0aiy7zX6!&GmP`%~TFnKM1XU}bN!l*X~3fYEGU#?XA-QtE)7ihjSUh@!x1
zxvye>%;xIoHvqi!50>h1$Nmm2bEhWshE-LyHd_(AKfO97l9N{LjPnV9FQG*CsPxA7
zbTpL9cF8KRVJ{x|Zu0`@9)ND9zt<rzrh@K2B{Eh$s;t_vj}4TXaR6~t$`5>yM3>jt
z<$1s9z1+6nL~q#8{Q!!jih(r?Amq%~(zJ~lHi4J2rz`gO0wU}E5KZ8X4M?Xbv@(<G
zC%9P@iqOh2jE3R!+vjF!Ow!+HgoQqDos@ayf_MeJi@8<~-D&SN(3pruS}%LBKq9z_
zL813_wW?XH2Db0ZP5a?Z>@l`XZ&v?MUnroa>bA=Wz`CSN!HKx2LIQt#L|=h`v*u>v
zny)~4r_E>Jn8&8tr#!}CDD!wrP*aR3Fj>1>#X-C+0lMi<l~+XJ_=OhO4c1zmQ-OQ$
z+_|2MX%`9FUh(3?F5Oc^bN_cL1LI{9t|*-Ovar+PJ2`+Hq~;rA44ty{cu~1oiF(0u
z3w0xI)-RN|1?}79QhNdS0LxJLjj<`K(N^t~941|I_-F2<tZ^WmHh@CW?{SY+XeBMK
zJN$V4!or?B-~BIqnvciUzt`)ftIuvf86DT$hJe1e?{lTw704YAFXHFfW(1DvOFsd(
z+c*!|WFf#=ReEd*xi&V-tEmpA^SCXfqz;vbVFJ>AE`XIWZ#eV=cfs1F#5Ur(gFbo*
z!yx|)Pj_xNdd;mYUEMzYVHzsEzIqGpI(=w2GFjFT<6Z+$rQQt1(&8e^;yU$6w_m@X
zue_I(#L}{<P$ID92jNJia7|4UGi;mUff!3+o#`<$R;ZJcT8&+S=6n@D93G;g%~!We
z=A2E--yku>G_9;gu0Uf!m^dPnM<iv!y=r0CNv(T=3;N_%3l<BD!-=na5Y@)J=yT^y
zeRHpm=BxBPFg&ZJE_<7I+<bLymu}xK?qf{5-)suRRu<2=#}6PAu@&y0NW|{o*`!0%
zx>HCnKPU(}oliG-Yhkxp=gjI_>cuQy3SQEWck=di3*}KBXLO!~q10>D9&U#<U!Hd9
z;!NgPl|E1}auj^4S%gWUeCn=dK46R4NQB^gs3p;x@?g{GXcnuktNC;9CxE*`+%}uV
zW9tL7B{ioXB2|R;+1~i8(Gh8N<SCcnMK)Mm{VB>yj91wkj^$b`#p$aKQV2s~GPBip
zpit%c4aOI-01Hb&gQd*-ert<H#w$;qEsl;Knwq)*3hL?}n`FNL0;2LEijO_Zs;MC#
zXpT4A+X1Z{m_hF#Kk$1um&@VB8W1{q%1*%O@#-=~x;gq6LrCZvh4tBQhx`5IGm4C1
zq0W5VD~-6FHTNssgDV>5Wu+8AK1gCR`nFP)8}e{%ZLRa>{b^*SeO2lkFQ9k%wYH_*
zoTKj@iYEt&9z}_ZSCxr?434j(T34i=^H9gpj(a1*vz&HP%j2la;;fsKkzX^!nly$0
z>e28YNa#HfaejU!=#yZ>CZL+=treP-Iv3iNEgx*?jsD|Uqe<T$1z^UOOwl5qw%AF`
z@yPogWB(X>T7;6~l9;E)qRT(0bA)N=Vlr&8Of4m`Odcwo<1)+IAIjBGcJ>S`ok`R?
z3v~=piuE?XFaK?&^mV*1#PwV`vBo-b`u$Ppra9AJ2!B3Ys|XAEcDS)^N__P7SsoK@
zy$b3S_zgvuF?hhh%0lOLe-h&M+!T!=@#5sfP|i6aF+L_sQ%vTG<<)bfWXjpzF_)sl
zbG=TetZR0an@aO_0cfkbeIi6T0A&oYU2HYHivw+)1Aa&L?#1rJAF`M<#<Ii($t0DS
zcp;$Dr;$r_0t5h1aslQzL5t!GT$B4NCt!HsuvQ()FI`Je#)CF9)0!0R0px0c<je>Q
z2uL3p-Mt@9y#DdJoC-z5jVpD|&~KZ^nexglrSP?M$F|+`LO@^fZ*4V-dVue(k+er5
z{Avj7;v(5}iBnWPnwtN>&}fp7ptKo;VEYu{IRi?yn$jbw8sKB93(W#3MtH|`Bl<*%
z80M^{mLpR~oMv_^%f?l}U~_ZTpg#w}#t3-xZnE}2(m9Z@Q?Q~r7Y3WsHObD*oe<C~
zCA`XLbN-rD(#wlSSu`~3n&BK?l~I(m=HH&<VGCI*eM(C@(al}9#P`%~6lSo?jd6_?
zP2d7b?|ieAt1X81$RmB+yA`O7n7_eSgNU5w3Lg+uVr*aJGl&7pp<}llU@a&$FS{8|
zz*=sSU{BC1tS-B^`K@GnoPLh8BMhD8h`Z*JKGuczA$=9oN12xIyAf8R6{mK=Zp@nQ
zKe$VUwQCE9?u_M98CA_9PqnuJ9u9%EwFN3Ppx*^eH`#G7wQ-@V(Gt9#dzJEfr2b<(
z#6L6E7mRXbqmy-^ArFEKLP*&WfNX3`CauP4j0q_wBI>BW{X|!ipVXOATzn!WU1rAx
zWxhjO0V5rTq*^|v<SLh6!|t`H?#cbaf9l|52S+6(r0P(<!=iB;a^MFkuaX-im@)kO
zoK@pSo;=QF83FBLM;-IQSxeL~(vihW(5YrGpcv12s|-$KfPw{8HQ#`f(`A9MQJ+Qt
zTQwP`Rm0-Rq-~<vpwJblcet90-^ue*Rp^2ICBEu=TgmW^lO<gLS>{7$bqj*p#MyC>
z?4Pol;rS5N0b7tNGi8L9jW<diR7E)+c3stUT*X1In?uWpHqbf&ib!0rhN(O!p8Jxn
znUP<^8@ocJCL@C!t(;k-?IqPK!QZTPWnk7dI5TuHY~1Yr?SD;Om|xiC-1zgW-V>)g
zW&@Q1%{I(pK`N76-J8J2I&aBRPONtvUUrdPC-v?9)Vt%;arDp|Gy0tjER5LK>kF8s
zH0a6s)eKU8Q=gj^XFlFcf=Gh>KXjVO8|ShO^%j?w(;v=OtVYw{Wy^z<bcRcFWee)+
z*JH2us8j7cfIH2mvVJdrK}8-8&gyC5Yvc_&=e3cgt}0d}D{G%di5L90&Nv=*t9hre
z=!n3T{Mu6aX*PebL(xbcy|W(AtDms+?(uzVx$}S=m=lzR2RQ$Vi<o&#auCs32N>R3
zNs<7|&o|UF^GVk~oU@`hZ`ah*_8DiM5`bpz89Btlr37x0GNm3lB%_P5*b=L}mOaTK
zkRkQS@E~A@d1TmS#gQ`mPt@K1!P$2}Z2D;;j+H{WSnBR|EiLSY?_uy2Ncvf8>+XWj
zeoKvBD{aotE!Wr3>W>x<=~c%+=$W#Bf0WW2p@fn?2@~DFV_Q)=8XN{ptjy1feDx>}
z#fvYR)QHu`h3kO#lqg$vb?qmhiJ3p>k*j&cA4c(rr-$>6XNP#?H@xtA+FzLT_f<H?
z#bp|4?C&Es$g39Tzb8NOctJ~_3=ckBzf_SAvRll{LQ{??pfYC<&E}3@WGX6|hP>JE
z5eYV@1$P+w|9O5Ed|j{N$M~hmV0z<A{hOfI6|vabLE&#3+OwRH(AH`_;t%^ltezoy
zqp=M`tMRQrf-cz#<oY+%uTQs}4K?&U897(BKzH$ji6U5sjV)Jfh^o2nMMDr@NiX7z
z*IPV|jmiF0t+_=kW@mkRR6#}o4$j44o!3)RGB<ykm{=7s-!(hPr>dd?z>$P`A~Qj*
z>BBA@c|c7y3Gfh8Mct~XdAu7gOq@Re{^BFJ|JB|1t>ux=>DroXZCP5j=!}x80D*Je
za-geA#&R-v1|`t4J2l^x(`}KFY$c`a`8wt5$Yt%RBx$lkQlY@$wA{?SmKar*%`9+!
zfLwCUN%^i#;Jfq$;RErkBzUqUi9-<g50>zklb>^5_@m8UqD0CASlm_g`%#*V$9sR_
zqsC6LShqcMlFp6pWuZr<c#r)6({c@8Mqg@FLmKJuFuHA^%(0cByc*8%o_f7lk(Q<C
zktZ|#GwMYDcrw3MA+~ij`KdiwMdTZrx*HAvg{4KvhR|&d+xSBAD=M~E4<$cb6mp&n
zz<MHI^IYhG?4W~+Y)Kj(RHaGl@X_vAk`^|B>@|gtd!wHM;Q*42>&@}M5Wm42oLTcx
zsq2{LH~y<2H>vmY^E#UIuiW`jmc{DF5yUlt6O?78AS+i+$tb)J`ub9{1v^(10H}Rp
z$YQG&=l%WjO&)?tTGC-bW&7he*G-m*17jI3fGjO68fo28SSSZ$$>Ws?;F^)sRU9@q
zHxY-kk-K=bxh$UH9?RA6b*ru}zY}pu{YKvYQV!&#n65}TO!pY#x~j6DpikTj<1rQU
z1`65b%nVqs06+w+piGYm*EjIC(MJ&Y)LRl-O^UH1^uNdu?KYilVYN#WMNT-1(KH6B
zjQ~3*;H4|Mw+VNDEA2hZXfuBV2FPeT${N-^U}fG3$9lMf*T#R{cX8~;tmbM*B2V}X
z=s)4<wp3IOA9~#(lUE#P2pIHRJjC+Ev;X}Vp0kT;z8BX!<U>1y)7=GJ_Xj(rOt&{R
z)<R1~?v~48d~0wtw2FPX!2kJ4@lnI&*=Ylywt<#I?R?uB;3Ld7L4XgV(Vi?0Xb%CH
za)5oLK%aE)8PjE7mK#<RQ8M(PDKS$ZXU3I4TaG`rP<&)0t*39*J-p7-Tl{cc1Q&XF
zx@nNOv({CJS5e^{$RtYlE4eUHO6B<><s{dwgRZsGx!`ia)Dybt=UA<B-$m!l4|!QF
zkw4MXEIs`>?+JivH+G75ZhYD+!u>8w<N*DqBFHaHsG9t(2&}JRFReFkG?8Q+$eixj
z$hv4hYR;O1oDlFqJ<Sdu6oid1B=poY?DfreU@xoX%KLFT=7rTTNur=~q$P=}=f_?@
zKBkY4vxQ~@or|H1u7lR`lfIkhIDTNcrety<`8+c=f{_7`?N{0LE>1szvu9<E11Qto
z>xCW2;~cRG!iI9lvUf+l;2E4Od@%_rgFvU*-npSfTKy5<V~0f{0;(UB2&(`T0BGF@
z7g0JOT~q#2W(15KfKYmX1HztEy-3HLCe~cI?)XVX{hcAFGDnNp%ry^glV}h59HD&f
z=0wk^p59vqzrOX(9~xYcMs$d)X}R)*mJdY+bGjs~O?=04y5lwC>;^E24=O98;4cMM
z>Y&F3)v=(efN|Yu=`|c_&=;{?`~3KB7N{E0lzVUF=?Cag(^^>iBZU&2$ut>!vm?S*
zXf9RtRgB`+4WO7`+5q2VX#z?Q3$kk)kvPT?Zbk++YWAl$HjRR(0}080)y>Ier(8gW
zHnPdfVQ`g`@0(l|?>ieZl!4qRj8Z&>#sI6p%9I2210O}xBTSuOPpxBQ<<(~7JzYz%
z6CI0)id+)#*4FS<SHgsKz{CwQGNn44ubA##Ora-mj|N&Eb8e@|{~i&kiXBc_ZebI6
zqT><8!I_J|8?HtrXOBw~1>!5{;r`(GU`=Ju*<5E4_LB_$>C5$n4sdXXeJK?R9M{4E
zcxS`lCBpSBsq57Dk4-#SqHN=2z0ob;m%LDxHfc9Jx|TVLN><6hk<vIKWg8lXb#`pF
zx3{)Bn*gXw^Xdm!ku^_Offg#J(=D%klf*w}Xf)bc=7m65LW8BSmVM;{k~C^Akm~AK
zH3TNIh#geO)thW46i%8XpFg1zls`=kt_CV+6+QcZn_M3pX`JcYShENh&bAT)Y?gpT
zU$f&N*IFMF!jCQY`;S-h4%^<?Q{+MK9;qAPV9XUPbObh0$od;O;LmXg1s9mk{vkWs
zJnk6ns22Ki>qU{r;f04T&-MuWy8h_;30=+tOHd}!=iH~z2f0idgw;H583@hkQ2p(d
z!JZO3S-o3wSh#qnmp4(`wS*pL@6e<wJ|Z_FVv+R|0K&~y%Rd2KIi-(}6l`f5iXfu0
zGHOQ|PACmrze~+B67eyH^EM^ohe=?2kdzIti~}G^02kPWZ4E<n8G$UFZr9Y;bj47^
z_1=1rChICE<tRi^wtx-PTS-Ux8YBYq9YT;afp?m+I)W$xIR_ECIu}mg82(VF&HdUB
z`r^6|3%4Iyu_e;)Es!jr#AJF}hC9=|1m+T_v1|GWK2aogQ4>Ztk2<d29_O?DIY+*X
zT3CpNeS4$Lam@TUwUO&p84CCWTW?Pd=Db#J3+6nIvFIbolP;3j6s+Yb0a|B(wkR7g
zq?+*_=v5`#+Yte59s#SS!E3*!Da%iEW|(0xtF}hhXPHyx?>SsV$g9G~^Y^?AWVM61
zVH!k6cZE^)@deUCf4fa8ZD0gL^=>OXn?EzKyvaZ)vHm${_>U0>pDF=K^)pem>DA>*
zB#o9wz>06E+VGUhKS0{~pabp?9DrN;C0CrA78SesibuQ0#zHPX#X{qmj|y<`!A$L!
z&QO#-Yy=N*dyep*1<W?+JB9LKlyIkv1qEkMrIQ`eKYu4u<$wW>XR$y7#|79%?Ecm<
zpfLun?JsPJti#&O9zcA~I(UCC4S){epHM3To10;zmwQKsQG+Ko5hQHniC0`?c~R*H
z7x~YLyYwH3i1>(KBp~m;0LQ$TdEsKNB*s433E6#|K7+$h&CG0N(c!1My%<0Nj*vC-
zh!8e4;hbR4<cR<0a2Rl4#@els!~yYhtB=?k`o}3W;QI^sRZ7v<Ix74|QYJ)V_WDor
zY;HQX>AM$_0G!I(D0t-hfns9(gqp(v;fo=BB8rS0!kIxQ#2oN(JZ)nP<!6Fs_cpVy
zf`jc(sux1+X0n9c1i(96YjRA8om+n`GO+<1TtiAqQ9XVE?mw&`pVp)e-{WZ`IfiIS
zShihcI}B8dL;Z2;&blc21iRFm-p2yI^_AvO*Cht9;pWsqHaOtJTH={yobAdty;yj=
zR8@J6E0*lf)t3fI)E#VuV`a^!uPM&A{4ifAm1tT~Q9c5>yQ@UTDX5I@F4tQ~7RqG&
zdU{R*EiCQTF1ET@+dX(X8S`ipX7du4@UkfFfm^lR`S;VNxqpGU-TnUrai>aVX&zNy
z5UcCwgD}OD`adpEl=CGl+Xy#cuAc+-(n7@i;4<gJVD3$QxANZD22qufR6E&nu(0D{
zbgc2N@8_;6En<&_g@s=+ljYXwwG|cZm%6%$e$gd45iscW940Q&u{CM6RWKnBqQD&W
z3$=Al5iYVAW1H}m-G0K#vDz*cgY+v=fD$5hiS<E~cK`J2pf{20!dol&)fWWgCX-(6
z3q_ph>PpNKbPHl!r02{iZznF9SX+DZ;@2@S*k#|am$XQN(in$eX#Pdm$gtMw^z`20
zkH&(`9A2pg_8lBnOzE4Z&lUD?TLorapu~`ePm~!=?yS}Ms_F7`A!HXBQmv`Eg+;Cd
zr>2KC$~#fqApS&H4MWbYWu~iW^&R<NUDX0(27%maKDkx2ikRQtOqIwF5-$?)eJGvL
zaPo4eo*+$&6!Q&*4Teq;KH9I8TP%17#+w0hg_s&doqnA^gt{yRsL9F5MDiz%$xNA3
zjX;bk)%YbnCUr~BO&Vtwjc4`di&JNRg7BNE)M|8vl`uMe{Eu<P8tK%etP72)23sn?
zz+*&^$58kr{jMP7F|#c2?sMj2(r=88-{+2!A|~GPxoArD2Uyy|XX>aS60>KkJ)ZA=
zq)6Sxi{z$+GCM=3NGSnwySbUFFtp;(?v*NMhNXr>TlOys5in}u64ufI#+~5CusxI&
z0iRhk+qi$xC>H|NW=K}n@WUo~bZxRXY<H>PHZowtw;h7fo~cB7EF$#TN+iN{rt(nX
zqT#iuwR$w)n+U+#YwGG&3nq=}h|n7=T)AQf?Kv}KpxhbtdV*2q<m4pHMhHlR=0=H7
zr3sN#dax)f`Y|8CoTZt?bFKL<aDHq0D57eR_!xh8dhItWEreS7eCo~Qtsn7tC^mRS
z>?JdiDm<tE^gJJB+vM(YJL%&P&M5VpDq%G&EG%Q!wn;oPTBeY?zNW?wn-LToj4+QH
z^FW8BVi=;OgZF6-ZFG`?+mG3`AF3Fq@@aV8vaQorBvj>hAxiPG{tx-QBLbGaePVbe
zcK`TcQlwgyoZMV+r;`PSu_^9+`6l^dMaS^)aQCw2&ZT+_^<XKoXUO2`Lwg$*B{#=`
zXd>(;4c_LxJ0P@eBDq*JYMLKe!!bE>1~Ok{=Y|=ID(_&%D_R}{<5PuFn)atwjnjsr
z6t0|!ce8J&H}E>nzfJ_P<sNc9`S_0R^HE0Wj7?4!s&Y$|N_Ze&zM-P(Cywxf2BJfc
z<O-9Mzm*gf6;U*4v}=>a<x?jN={h<(c7qA_m^y$!pjxe8s<_e=B3K{Ea|J>37SYRl
zAK6n9a0foeG{4WdGH@Y2l&1cAf~6$F|87;iRODHc1)29*!P`AA&$XKuUo_P87HyQ?
zSUen;;|dq4WY$!<WcCQBUF-l-86$hrv~El=@T(jm7NZbt(l7zoRGr!>ciT4w)4C<(
z#QHzehxo{}+Fn93iTu9;65e!Ipeg^jrW(gWkwOFu9DU}7mg;0SqWZP|wt9=``{Q-p
zVKRftPbfi4@pmD4ETpLHYwLySXBk4{EA!?0QBATqo`PQ#th3e{9i)1Cdhw*Bq^BYg
z*a=$t&8EPln|cEifvkex1m_KT?<9bShz=YiuHvV!lrOISio}e&e`AsM<)zn`kQ3ft
zo`v`##nrr~8Lo~rt`3#oONU_!#v}%Y-uSAgr$;3rF)?z^v`%&yR2}1;pj2WZ`kU>E
zmI*X~1ds7$83zKxTc!|)K5iD@uWI9s4hbkcMR9+`Tm;a?kW1Yszr#mj4}PnqqYj_J
z&N(hK^%6bct5Qs85i8sG%$is~7xK)=9z?;z!z-FK&6+Z1W&(3+n<(a|!mQgitgo|J
zuIE)!Qc6W85m~tj3y>m{EOk6xJ#rxDx5xYfLAVI^oiIYo4cu9lSv(HZ{?_-7Azk6z
z$Zsuqkg-rmvWtLCMVLK(C^N8oMKC-(oU~p#{1l1D^;SN8$UAvxUwC?Q@}wLkze)q_
zz`kQTMn-uJC$^Aazz0;RNMDHnMi9DZj6_DP`lBfA!KN9Uo_NvTxM!TKQ9%gE>R?fa
z84C$uj43qQC9~yFiBZ@rRA(5F%kmjAZ0P)SN#_{*bwGLTTHUb{8{2q<X$cJE4~c)j
zVV<Js>R`Uyex;XB5~4W%pBKQR8#)H%QlVFt!kDJsYW)meDrpcTtFP9|tyDPeQK(2Y
ze{5G^nF`EEfH8Bb!_(<s1IEQ|646Kv`u}bz%Sphi1LrCiO_#b;e*rm11dsoV1S^!)
zL2Hh{4n{uda=Vl4QsE0WIFS9YbSnA9M6Ya~c^Mh6>U%sC6=#^lJnbYrcxS)2wfX(0
zu$N~Gh3ZlGoP%BVIk|=NhicRbVhgi}?CB;%!`uin(%>PQ&+wIMi3qVk!bf%aopS-X
zVBc|g`dc$Vx}DD)+P}+DC0tvwU@O77#n@Kgg=WbTBF!ZAim_bD5Uq4tC3$_`eYy+(
zdDUh5b?^9|p(CdL{oZta`-eP8hOiN9GB-Rl)Rhc4(=DKXPR+^LynlDP93?6&e3+Ay
zQ*O21?h*O`nTr4KQgZ?uD`IEQveN8V7+I5n2-x}2`#Xlb++JUGhw%y9(Rd7ZoqS9)
zVoPwAvNcnDe0(i<JA~F!wSi<y-;ylw&GpsF?xLm0j*CB53aENQE?1-sxr2XN5ICr>
zhO;Kt#CGc4^aNe9ai<czlZCqavptGQ{?a5SjkFQ{Q!T$$MrFHC%jwruzpxlv=ue)C
zR0(#L{W$`FA&h?_`s63Jcs)4f5i#&T1l*!?3{6c<O>$<OnQXKT3=DufnXXSxPWmJy
zBpd_z@sH5VbxcgmaBsy_Epo`Y?_5uqtB(Wv;3o~jM%8BG(7*;xAoaQ(*>n1#w*0}l
zpo(o+!xJc(y#o&7QK5yJG;HnAHC_jcC1%%6Ko>7mqW_3ZoUU^yyb!_mVT+nmf473D
zL?67{mhL&|#u%;WcsnXpq$(s_Y`J0JWhM>tKOY(%o?j_NeLh7&N54&8la%y;zQ^*J
z@n~mbWMouI$6^Zt_J$fbl}^H&yY_d8IcX-e!OSkahp)wNI%YjO_>WXSkW420FO<x5
z4}^Oa#5|Q|GZwt24(*3Uqwqa;Eb*2#kMMD&esfS0Rew0#MpR0@_{lz3gzPm^Y6)QT
z7zcppI8W*D!!9G9=vGfUKEKVt-T8>IA~JdNY%!ax0lS)DnyczrDXmWZyr;eRPuzkP
z;f=f1e0J?8WM0(<p94CyTKfX9k{A@>=g)=0aWin}^7q+Y8BdydIU`OrVWq`r!Ip)X
zYKTY6+rXu*oaf4vD*gV*kC3>$TA9Fb=8<5b(RbkdH0qDU%R01gF5I<s@rrSpeL;?)
z5s>Ulq6*qg^6&i1=F?g6<aHgB!?G+?^Q|eAnejHO6UTM3P)JBT4NtAiF;9vNCqz-`
z5p$y-2y{!T43LM?Km9+l-U6tq?u{FzTR@QR6ltVeknZkAK)Sm_O1e9gZloI|q(Qnn
zrMuxS-v9T_+_{(0nIm%cUVE+Q`PJI&V*+Fuf9=YnIJi?Wz|_v>1!v&mE5&K#*SPfG
z1jU}t7)ETFRJ1Wa%;Eje(0wdNFun<&MamWO>MAMya`+vDcqhA_k|4F6v9Yl+2BtKV
z#)k|%D?>%oPlb3JBT{`Qp9)iKl8$p~&cqppAp&4U6KI(7@bK^jDy`3UoanFLj`f$I
z=%n@Q7<V(#)B0#1>hL+hG^(ww4IdYpuSnj;_M_Em`!X*N50Ap5)PGOUKs3v<5vHRQ
z{HgJm(wW@mJTfr1#Utlyc;BmX!+T}m=Z}C5>SU<Xft2Ej!e=iTn6m~D85uM11@X1E
z0YRlX`QHOd3I%`fJS>sB7?u!V0+M=^@`7%-D7z(ujvjTHM6zMqaYp{;04-u*K&#~N
z81h3BKkF6oKwB2F;g6_1(FoO$4*<}!`WVOoj#>u336&?o`!V$}RI6NVqV{Ls@AuL`
zU_caoL|37>;|?RcN>YTBz9fezk>N<^85yYDCCKZ7t|X`G6DM`n)yFDaJ*qYtN^+T*
znNfD)S>9A}G!hTTuP`t9)8_r)VjC%De5z48zVBokfzK`#YWv^136aL7^GcX7D~ZNy
z<k7|P2j=!4Zg$?AIviGy?8!Dm4NQ<>4>0&r#`v*mvC3rxbH1Vs!qXj(Ug6}2tN6-)
zPR-Mx;2sM2@R?|7OFX87oD3F<6n~<I>Z^jW=QL&fDUBg#6J+0Rm~R>8@_s0ad32>F
zYwgBQ|4N!bn|%A!sY7|=))m<s#&nwU+&j>c=C=&g`F|SI<$dOyEw(qPdifEgIbB6X
zmLs`YzIU&WBUwU4_D9d#o3{E(h@Bexr5+&;`kB6GuZvfdhZ*KpgQ;pEjJjAkg+^LR
zs&8L<iBH2?twgTy0aarqA#Tpn7&xh8{K%aS6;(Jl>0*_3PO#{)egDCn6|Vo*j-LO!
z)VIHLlRO3NM3|}sutx0v6hrJlrlSvZ*S*Sa-=w6ZcFOnxloc1a_tz&B6cp*QEz^6%
z!%(IoVq)R=$^TVbxJzd=uqnAXZ=r_1`aOqsLAVl-RsH)!9k01RG)M^9KKYf+GA$hQ
zK^8$Y{>MLn-Aq5lqen41Dqg+p=S*da7_q0kf2&KDE0n68-|yWU;>+&!pVBvMhJUh-
zO6Y!BkqGOXK8SrHQpUM;>?D37Fq1C$fLP|z>10zuC<`-TcizUJP!_Z|)~)t7EHXU&
zyiUcd>Bo-^Is$_9tC4Ev^CSlC1x-!OCmiz_Xtw2JA=lxjGmN(dBVhPxf7--+-`a}&
zQg*{a_~W#9FOs*EkR_q()$n`uinFG)6O$b#h{;ZZseP0zl7}yVEr|H3U0xkib<>|I
zmYjct|E&&eYrxjfR07GI^wsYTQxP@ktAjJRAD11od5d0WUnl<4zH)`%|N71zv+o{Y
z{!TYhY81}J)jG;z+qA(+s|duoy4m?h?y4s(aB@ujN{=xjq|>d);<Q;0G0(vlFNc}F
zUXfQXFDJ7uzq-fIDJU#@lUKglTC6BeVb|&VFtp10gwP=NrYrd*Dg}jaL@HeO{b4iQ
z&A=k+2w!<;EA_VSoVP%9GonU!RZwp>is-@6xW;ib>t@lq!Fu-2UU&AuqpjlL&VxUD
z>`%=J)(JuA1ggc@c0}&R=zZbNeFa^hK?pwD`bwX@NDf=B!`R9STSU!s(P3p~-)?Iv
zy2|y!5DgK%ya~kdz1TKUjo~RLGc|mm_mv1V6qEz;A+<c6qhlKore))7)(I5{Bm8rn
zzf+dlO_y*SeR?`EV3<g`vO{*Y40I}9PT&}GmYmhX^$#09R^h19+y)BUkh|)ip-(yz
zEiwfQrKD4;TqieRAU+yq?8=J~xRsFIB9AZM>JoZ2eX5<`8*4s`r;yx8q<sHA1PJVH
z?Udyh6ZF9-Wg70-(;qS}5pg`t(-w)p4`=-vk-x=l!5rJmt`}Wy|81(jf}P2IeEF_u
zqFbPF>6U9A40%Rm5ymT65wVLK;sAZzy1_*}YLf76E%O|Wdh?MQ|D{r_eC=sF_fIp*
zcEyu&@OJ{#pD)%h*g1n|LF=N&pFfASnYp-Jf0CU{Q!CRr(>(tRJ;a1Pv?w7Zg>+u;
z_o#!pj^9b10KaCl=`-K87buKKaV(r$`!!Ol7r%F#>piAawR`p1OJN^MyYkzP8qAW>
ztZrt?a0g{K$Ze&Fp<Po<qep|ssH<Nbs2>;Hei-JpTV)g$_8CR8*z9Ewp3=l%(cE0w
zFqU3;9)6j#X-F?qv&@^e&^7;<ih9s2AU#=IP{a(Gozb&sRlkl!r}hZuE58_rxE*hs
z)+)*Y^LeE4=1p?0x(BPY5RG{=wBwsV8nW4IiS9;C*WL$shpP!j=SVz(B7^&7(Y?i!
zTqs3~euD95>f^3S{>T&g(;s-c$DbD6RD$ygCpwv-#B<f&o`^Md-{a5fU5+q1q9+Ei
zOzuS!zi%;Ye1zj7jPlu1GMaVv&dknU-SG4CllNA2Ql7ms?SpwA*IK%hB}aQIRq-;Z
zSi0&uRE0?)eTo|VLrskbLi>WHz;yk12N~K0H}LU~@csUuB9mih9exUiKMYt_d}ZO}
zBd4V-L#2nJVl%V}2i92bfiL`LdNmnCETmmxo*_SjlzRIe-v9C5W5Ja=)J37XK3x*a
z&F#rrdn0u?`+eSuc*l+_39xd$+xoirkGOd1?FF^Zefs;kl9&io60F?@_{d(4y@vyk
zgd7oBbfTYcpg5L{8yr~S5@p?>8beA8-J)65WIQ18n(BAIc0C&5dcLsM!{Y}V@|=Rl
z{tyUr(K2q08u|38JOARt{@y!*v3Ib$i(`xMZ3owX$e(H@uZM9QC9w<NIwIFjrC$gJ
zHk4btTy3^7-jYEqNugfmQ?HKh0DZULz8T669bSai_Mm)hE0t7IXAsg4rf})u(QS>=
zrOQu<@itw$Jmkxb>oQ%A>>k6nY6ce4Dj1&$@Hl4KMuq(h^V^^d>$H+{b^dZ&!DFY4
z>|nip`&OXs-mqbj&dk&l4om^jWwr7_Sojdq$764b7%oYcUqKF%Q97RyXp!xmxUEC#
zi`=TYM8*nQF(cykimWcb*%aYcOnm$W_fyS1`Tp*X0mKfE)qHFY;EPpIup_a#f|pjU
zY;JJ&ja2R>kltPKcb&{tF3?O#lN_My@`Kl&jEa9>IR*?RBBnvMD1=eZMvRzR8r006
zkCd^ek4O)jI=1cY?fu>E?fj)x?)~)mSP${$@$oSOHRNZo6YsiKY$AP^@_tx}(F+dk
z@~r_k?+d9)m9J+4@)i41pz61CSrZlWAB5^FIx51F)jES8K74RBGc$XE$lypHsq<#1
zsG^xWx*kLg+2m&o;iG3xAL%A1Cl?WvLI)-IL0G}&_h6Am`M2%E$MheUvG_Sg)Eo9p
zb_@vIC}O>QX^M31(MrRO!ll#AZ*GBqjpDF?PvTWlQc5#5F=1e3Yk!8yij0cVBVU$&
zJs!JE(P1*P%C%CogUfSupZjjlQqQ_xe;prY)EAr`aaIE=i@FAAb;@W^sNO&eZ6jM8
zP(@B#9DS!n*VmlAI(dA0@&wH6^PXYTf&^5^;crXN9K?Y4XC;OP`5T!gHWkTFeJ8zr
zci&4lKBD~$sCpkByWMA#AibPnY%qW1qHJnvnpbh~<Tu(}k*>hFr=HjJ&ZTA9su3Q3
zC!#4Fiw-rO)D_Rw=nG<ds}jqgo5H17)8HThykb6Ml!PmKc$a>szF35+{^v0MIk%Bw
z^92jt*=<O3uw3|GOie39%At7t$To=SV`PK<>m<{JBj~$4i~W%<Iq;x8EV*rvS*n7_
zjbW@@A>mBT%o;|oCZf$oGc;M8|4mJ`dEPK4B`ImpCmjb1dz-8ofS{;hZcZas>;pu%
zC=FaQu4X_oD+v{PGZqz+7ICNu)WSDQPHZiUG>*=7yB-2K=pwB0?dA%mh_JAEM6W0e
zrYBx0vkE>lv@|B2MrP&7TC%=^ZPOa}m_~S5mR~UXX3XPw+r)>usKhXdic}`eP-9Sz
zdB_N&WZc}`bE~Tzg%t<T_Dug;u&B7J{vrJ|WFN=R|F?{vD51!xF2%~qO7RAI2r?ox
zDk|$e|9{ouoc3dC2{L%?A=OD%G1b78K+L4X2{O0nYZ{0C?A3K&$9unCA0HoSq_;@k
z@V66tj)pX66M6~VSW`fP%a^Mi^c)@@%J=fqAPBp6S}k2VC$x;u?n7m;j=C~Q!AsNd
zU`EuZE9en)n%49#Sk+Uek6>FiEPiK|M1?97d)V(J_&9(KBXnwQiqH9&p=H$`j;M;l
zy$g9$9i44!{?-OpW4+xYz@??_*R%zZLA6F-;sj$KL~=xSlE6}wDIOzL;Ize?2CZ^T
zls5X@6p16@+_F&7-Y_mjQ5$dWTPLpM{0~{8y_u3#)@Spfv<$U>)#b;F;u}6q)+Wct
z#RW(i;@CpH6%$-K{wXGu*S&sA_DVM>sTgG9?+*;kk-(Inkm6F+BQj%C73>WSL(V{2
z$B??_qN9jj7k9?w<m60X{8&c1br^T$Lyt>LWY_RWP?!mo*P}tk&ULDufwoN!yl~DL
z%tY8G1m(xU%j-$XOhrv?>M0OB^WDTP)U>sA(C>d}Uf<W#L!UtWJ~Wmpfm09Shk~e;
zr?ex&Hst3pZ@=#KJy;maG&ow`@pv7V*iNV%lBzE4#f6wEbm-SErEz8Z+$79wv-RHV
z@DV=;YKdw`s$bFQBudH16*l#t`T0KvlTK!I*TPHop%F45IK`KGH@Dw)WXa?E>=ijT
zH-|Z~2m_$=T+SpxEgCTemhxflt`}-3^1=%mmpZw%2T>e$)#i6#;A**=rKQ2^h@=>)
zTy$rXp`_0p-+Cal`IGo3EBcR?M_Ln`^#H8{&r28;%`S^vzj#zGQm6Ym%9CM{^2<Xw
zy~}DAwk|hjNXq-UJ9i9jO*u^dk^WyA^v?cSX$5b3bYH9}s^+XXDnmm<PcJpzzo+$d
zq^o-OHDsdtAQ*lcqfV>bI&u?vhV7{5?qb*Rm@a@6kPhQM6p9G!)OFtww56jWw1z2P
zL`IR!K*P2}GKm$3b|ENK|Fi<p?dEJ^A(JsiwqLMqk#9aZCS+;zc18`(X{#o|n=~xS
zqJ|h}u;j8p9@Ny-cz$nDcpdjxP)>lk5cqY&U5Z^SILcfj4LJz@7^$mmRNdJ{%e0x5
z6s|I{X|yHuw{O>vt~li({&toYedN<m+U_dTZK)3im4%zgwh2R>HnQ_UV0<(H;DVj*
z(}A&yWc2iH5{JBZcjrPBZ8KfXzJmmiXN11KFDHz;%?abVpF<`ETs-6w4m^=eQu+;h
z8X1PzbN8``h}wiavR^NI1uqaOiysQ*yxLLQU#m@`FOan==%CxEdTN^ONL6++00dnd
z6<*6UY=;MDpL`PyAEJd!c+&jJn=5WY!@{`9`IS$xMb30-7_@#uC1e&&olXk4MP-Nk
zZ!ZFPe1`2gXkKwYTBu{s6J4U-!&E4pq8eSOv$WJGS1T<rSB~_S1(f&J$N&)la6t2!
zkJS=k;b!meV7M*^NpFIdWt(4%NA7CZn;RPw&blY?OZ$Pxod<>)EMW`Z!sY2%;^O1G
zWvC|^8NXwTi;9bP(448i&Q8uP1lDOgrd#jOm<iOWw4|U!kfl-lnZc@xl732D+{Bb=
z&4?2h;U9o$#uuLQGBU$ROd}ZdvPrm`yfAaYv;jWLb3j4@=vrjnAad5VB_<-uBp+dL
zqr-@&N??Ol*kAF@y>xDMzQzkesvj9JZC-UNLNNIwCPf;^3i!6)ies0idY2=sTanRV
z{a+qbxdIldSPo2ZxBv5}`#P`OX$$MpgL`@i*-2Aa7?_BpX}Ye(zj=s37<rI`-U@h$
z*O_biyMIxr#?S*C)O$9c7{?r<0akHRL+UDii}}mOzz@KnxZ*(C$k@0yw4H+|*QqN2
zWwUg#PENv#V^PMySVbiPw<U|+h8T_mOpI*;_FGVi1Tr)YLbxTZGH6Wv(e0f&n`Et+
zRAZ!F^?KpCJu9;cMrZ?96CS#=I4VHhD>Eq=-M|SenAH4MFv?ZVlY|k9pwHb(fs6QP
z`s-#b6E^No?nJK;Vv#`P7c>tdK&lz3sd(VBJ|!5r+fZG@c4CB8)7FK}KzK=`$)or5
zV+>~0cY1V_ng?R+U5epDXe(^nC-s|L3D9E?amh}K<wy~CnNVH#VthKn0|>x*adV@e
zXRdVuva6FkQ5gMfcZA<p3eZ^5khB+;EjZajLThqfh4nuw-$uP95Qc<2O)F4^v-p};
zPoQD9Kar0`-nRC3s@JZ?GL1t6$nNF}`A@yJhykPsuvOUOilSe7zv4*6BZ}##8}w*x
zzj7cKH@D^%2j5sHPt@Q{xfKwJ+Vn~G;KJx-DG&k_m_J8`tdR6YPH7j(AnxBIaL)9X
zs8?pSJ8TaMf=OpIN3G0dup4buKZH$_ig!a(D`j7@sFP#<h4Rga+$isN-2_Vh4r+;2
zRKu4wcF_Tu;g1m_UEjG}4skh`os?m9X9M$wBX{Ey65a*H37SKCnMHJ17t!l=@w(w+
zA)QyTeIs4M9qx-z5if4>MCNxKDRN!UnqYE69~c-IIdt*drsI%@xEvoJcg_382U<sO
z-lC2Xz@n$4?w`R<a^uJSzSYG1Iz9r;fo1{9V6jH*0zB3U692z?6JusjWB4yjVgsxa
zel75^U<4}FM!i{L<(<qS-7G;~TM*ZW^NwO#Lypz+R&N+}8e_n^D9cVhJ8%&i7Kwc8
zPzXOI@SiWjI&JR!Ibo6Yo$OPyq889X>wV(`%xZ)*U5fIv-AH0#l=WhgGJN0nZrv7S
zni!bT_sR}D<d`qbWhW__7lx`d=$C;8H2C8FytlhM%RrJEOx4L*M1D@LMGJ@x0nS;`
zC@KfsH|^QQ(qVwBA+GT6NQtMH6{QqiMMq9>X}O*Q)b4kT7FQtfM{pQ*Qh;7VH=cB;
zndbu!#r=^ZIp_Mx(VV+$_AQH2E*D%AR(_5(^pCc^#zH(+)4$TR5AgQyfA+|>=rHB~
zYi@_oz`(>*)_@Y_QvW-EVZ+CfUJhBM1S+Wr>-a5*%ztUoBLLXyH9%p;;_|0Wr-1ve
zK>3PDY_bQy@61ZiUXdEtKuf@2Oa0ZX<f!7=Z*G5w)#<~`%iE%DWp#K}VHYiwxT{6R
zK>teH@V^zzXQ@e%V$LarW2>~vhx~4J(p{jC2~q!qH#RmpnUkIL0MGl8m9=ocS>X4a
z6Z?&UqIvM(BdltXH)ULo(u^?|p)sr`wMehH(XXIVMZEkeD`9hK_Y(hUSU0>-h^_Ub
z4>eq}ixmeRyt0!?7HRbg7Sne<pE-Nh?aJ7w_2obhf<2|ggt9&xgHZcQJg8ccUZn!5
zp=3O69!<=*oNc(8!eJMXC3fdFe99GFFs+agAD>T<L!&0%`0PPl{rvfpQ|C_W)2B{8
zgDjZp2RJZcm{oIj4+Z$gU2$^MsqkKrgGi&A^Z($zXw^TRa=h|J#PKJl1ewoh2`~Zg
z-=cT{&BlF>Vq~!V>D5v|bwGSSa`DWP)D{s5`iw%qN(#DEX7*~jxdPrit$tzMj*STx
znl5CSCh>OqQ_PuX0X@p=lC%pW&{9Knhu;0|j;f@pf=;w|f!e0dph!OI!@$G4%PcT&
z@sHf!-_I{!A&OG+MoUiWIP2-_JDzg(t|&04c;!5sPcphZgQ{G=Q$&^-)P>Mt^nv+w
znpKp(&gz3$i?jD~nF>!*kou3HM@$K9sx=0i5pH2N)8u1Hm5vdh^VCf63=*dP0-lR#
zvGhto681r>Nuq%q6C!r=+80~RL~RY-ZDMI71{?>vh+FFL=nd8NV5o3|0!L_Q72xJI
z%%GoBOPNJn^zy?~+TSMr#mUsgW!D8mKog>h3nu&)^aEjnb6UYbU<F}JMh0P-`GOZ<
zew;Q^0=7A~D56-pS2gIyBUI#JM7_ptPzp~{imO2t1dzTLApO|Ygb+}b>$Fmb0ch(d
zCxT)?vCq%XCn{D)Wj#J>1=FgnBL6+X1h~zYaaT0`{iu@?Z9jViU0tZyfTkL)e|R`z
zmW`nS<H5lo3;``k9tsLdugPvbKyubu-t~<-$GznnmEy|cPCAKOzt_w0M}cepu@sm^
zI;+r~k{=9R-ZM^%H&dajy;+cM^Di|slV1S@I1tSh#<(-zM@$`s5sO@q^&;$_LfpG@
z3w~M@MG2L+MvGzvp7=MSz4{rn4I347ZkojHsgD9#%%q5QB`#3RLsYc6khUMa0k9+#
znCJYHXS}|+&?c8U+{OemeGN%e!|BfyDXD3hP%F)35U69ATlO}SzRPMUgBJSxhld|!
z(0&X$F52~-HOAeoNV1dIxI%}SU^GXsmR#?Pfwger^&F-8`F*tpy)o#;hI!zn1?+gV
z{dYP&RG1%m5@xbV6OMY+(sGtA;AoHcNlgyOnSV;%Ua~%CN7ACwoniIrq}p*2E(38p
zSec~*VtHB>mjcdTZ;LZsmjA1#fiL&Cp%c!T$T*BW9-Uhylw6SxBvGGLizO0E84}ok
z#i_Q3ZT(7fK-=t7Q5)t&DeF*>e(LV&q!qwn(nArNPVyWPSEC8S=&`7)=SY=l@uTUc
z2@4Mk(_H^txF<q&)XJc){VGhQ0~C*i{E|OBbe^k67=MMP?B8w@E9L%pF0MOkw)-&)
z77`+T<Ql3(SXkGf6r`M>!9}k>p-a7$P0M+dvxuBO^jK3gM?LBMA1qM-g_aDKk&1)E
zrJ*)l0asE|QV7IwI(Y{kX2z2$HS>>BA|fL0tiLG~MYkS)s+|S>;G-#<v0F1Vi0^L(
z#riICy_0@ZY?4sY_1X=nZfM<E_#B;LXGkaAY$8ldRv9gEn$WGSE#}vt<x^;Z`TnPl
zS0_1SsGQ>0RwVO}qUaPsvgoai#2?H-oDqc|-Z}p!h&}{9-H5{0A%8Ofj1FuCW9KK`
zS?yhqeQ=pL2hHty8SG(}Vv#VNIK9jy6$kfDn*tr6wQK;y7jM^cXB1&Q5T?TO(#mYe
z?tc(AC#Tcg{ys?aCbdOz-jmY<E3dM8b+Cx^hRQ+m+^AaP)t*CyaxNgL2zNSw698jo
z#Z)NE3Q4uj{C2EJVr`)Bjy$1}Ijvv>2>}6D7j-!hmVv%C9D@-y|J^EqJqc3&+<MS?
zH(Ph-Ju0qu;KRHpO|G&Z?5)_KTUadU^TU&qRWLmNKK4OFx~fiKbTFt~auJ@2QoGkR
z5ZP#UkGlfwpqPHB2`B&9P;!MNf(WyH2fDZ-l`%MW^HVRy5>4W6GtJdCvvKz47%X}m
zpi`7UR?uA0u*crj@qh0Hn04ki<I7t6h4BzQAtkKHym4I*X(~JE0=*325mjnvOB#um
z*cnf%_A-bq4D`1hfAA>O=80laVi|#uwo3InK8;}~S1Q9!ZgT9^_7s~ndlf1864l`q
zwhs#r=lKePxqr>aZ0REu-Z?sQ=8iC-5cr|7s(T{LgaeH4KzUx``=Y?)O34m4`9B<6
z;c8&qC_n&!I=Ov#I2j!rlnRZEOeAQt(-jdHM~hRV!It}^_8ocGknxXjcq|nd5UjC+
zrlz>UJu_!qY>{fsw*+NFneV+y>XWsIpSD3e6RWoq6A-k-|H28tf+0JpsYb@&MN(o_
zK}X7?vO^qKtl(XTt8qD6z*j51ikr4*1KalRC>b1dWti{JgU*)_UW0{RqdU@9*Y6aj
zwE5;|W%-sva3$$Gf)AyeEikzOJhC*pWp6kQe7Enq%>HvS!Msj;c3QJnK4}F{42+Dx
zrR5J7RpJ1Z)hCg3tI;e{Tume)K45Sty#D~CYNLkfaF2^ZvyCApGv;kEAHLRWnx|bp
zV-CjDIBgM`VDo+nBCs6<9J<tWn)!0j-JKKu$ejk}7`ct1xW%>;nE8+wIJB}&wG)kj
zibMP5iY)4x{#)m#F^&L&6vOWrbOR+PO#$tP#kG;%qM90Gr2af>AjJK$qzx++QRcw+
zKx?gfWjAG^$xK@$fJ%b4R<BiF?hi?W6CfR?JA0Mi8Rt;e!-&u>=bC^bXJP<z8ueNZ
zYIof*R-X}l8O6h*lHizfHd<vmJrei=<p<GT%{_3vU>STG>8fpEu+u><`$L>E0S^0n
zehZ-AVbhDBKdw($Fz0d;YMM)b#5+HsnRL0jO*2<1`4>u?lUyj;d_?(tfaN8V)%8E<
zF$Q)U-XaY<(K3S&@;_yhQ2TA-(D(mnz#53u)Ku@L>U$UAXTm%$?0TF`dO#ovBHc9I
zYx|Ld5g*>n<RanRKzUVAr}Y})?b>mPL9nyQLaQQutt&A9E*jQ0Y(G-uePwD}r}Y^K
zGAY?fhe3tN(D3lI_sJ`pERLH}iLVxxGX=lXXw#!Tf|gcC%L{3WPL!fT2G})(qTGXf
zSKud+|Bo++S1d`!b1pWnndgE0?yQRjr39{^1<$B1z)TsZ3c8ZaSrbs4SKM9Sr&Xj@
zcj)WgD>yX}G220!SnYf<GpmdVNw@pSyfiuKq)TFmdtV9?zj1x1>DJ(^BDeD1qUjk!
ziR)a@mSfECs4`=skerx4xT-PRkqA%^!~h4(#>>l#s48APomeR@E?)S<XaOd73Q(Fe
z5vn)_ZPEk~&Hz|x26QeMS460uhs8{sIH8*rJtnvVaLB?>R%De8n$K=NsTjCOj$=?6
zHK*zDD71h2hJ=M`k){S+L}y|X^b63B7!a95VA;UMX@~i5*U__3TMOcg%`he$2EJ;7
z{1pG_$W>%NRjSLj&;EdT1q(ckH}mrH*y<LKcIX<!MMSvRWGziN(of#GMkrv<9l69$
zTX;iP<!*eimMg6J)>zb*b>fFjbC)sLccPxJImo%ec&P`BO##V=)Y^@~PS2uk8$Zp?
zudNbUWdC#KuJHFJAc_V4|Ed2yIy<=eNPJ&FSks^pKG{%3a@_f8J0&HBGvCB3xI@8^
zfIv|%_{{_*SlbnG`qMH)h^w{xKzf3l!A&;Sc1zN#-`e=y=tDz_Mx4-J(~?F_R9%E<
z98nAxb&IA;DLzGmLzPc_6d2%3a25I(-`kJT8eyP<johhW;EL$A3$LSxbr7s|eSM1s
znNwL{4(%VK!&DBojQr=Vo>da&yrX1k?t*3YxLLy^`N2+xI<#}9oSAJb+?o5<J(AHE
zcQO(JRzreQ7ewz}QUk)lqrK|lKmRWyo<npjb%^XoCFYW|mTuKEbX5&{Ym)q{_A#EH
z1I1vQ6iBPP-MW|=<)ELWPd%02d>*0zq-|bua1RmE{db6&S*V!qJ=AwV{K|Qj2rGWL
z8rxa*eL>7bSTFa*Y+)d3F+&e7!9pm>8woqNn@}rt)&wE8*XT=H!4Vv`PP3Eww?=Ik
z`Cg;y2;k;l*uZ4-n!h2#S<T6_=OO55W9*WkAtqm6BT|7&!V^2AU(-^zfy-Hn)C;UQ
zXknL?22%l!=kguY;tse!&Jpab@?oWqaOh0d&i?xKD+vVrsr^VzlJFaTZ-Wilq2_|)
zhTnRjH$l3=vnt~GwfN&yu3wm{*m(+WzU0pu7A5wTbpVA=2B_WrV>#HT;evM)5150s
zB_ky@$n9SLT4}!EWRHdfdy0BWMO(^?LZ!Db6n{JvprE&hy4T5_@Y~ZKQK-0K*GpVq
zo~P+mij+>506f;;QbJZIBTO-P#D>u)MX18R*&X9Qg8*qKK<P{aiEV@c`L|GyhA5p~
zv!{0wYYAs}*$N-uWO0T1f=!;GLzk94EyQmuU3){Ac^_a%jJcBIJz#_yAyX8#t({2s
z@ku0-BgQJ(O=V1kfia2!jw2070s3UsQ!ENPV2Xx~s>>1w{7DhM@%O`yeIYEl?0Z`w
zt4H>yC=Ee|_B$r<lh%s=&N7{KIUgP#(m!xpGYQeKg4DuJceW6k8t@OCo2Zs34QznI
z!Z(b?_aGV!sD;zxfK#)rkmYt`D=F)K!?0)wQ;qfsc0OdwhjG7|asMzt{WYz4%?d=D
zD_r5gX1E$~f0X8Uxd~Zgl1*9A@AD*q@{ls!Ij^?2E^s(PnjIxDdEJ(|_=b$bW1cpH
z7CLyPL|X;&nQtsCEaF=eNGme`XD5wPclL9{Ldp}68zM4FGz|C<u0N%Ux4)1`b(w>x
z`QVFy1?*Q|QAeQ^1$??<lhbj;Nw)IJ?)A|Bxe^NlAt$HWC3KkVPK!EJG4rWZ|4cB*
zcnmq=4;K{UODRqbpA(fl-=zG0<3xh5`3(&^9o*Q)IcV~hVkjLC!b$XQ&GVfh>9pv6
z84NT-BP6Wk?Em#Ds3=p;{I2yIat8iDa=pdDNoGt|I)w!pj0u=Xl2G_@XK$O{aIBE9
z=R~_eE=ZA|Mo#)-y>s<Dea&bj9M`;WnJS5B0Y?`2vna#i{+?DZSok3#8W?#4w~9b9
z^yOnYIR4V@O>Kd>G`p-e&GzRYf==p9v5tMQLwauRrdOe79x>7ZpdZ|PTqDdFXcuVz
zBQCif|K`z!=BT>^57QwV-?crMT6T@4?-(^9YFf!SNeS0jVW^LK3gf&E?hg(D*p>x5
zM0#lj3<wAa64+EOT{zWR<<Nffe)C1i^9;1K|8i<06#8I(E`=QUbLMk{bqw!gGk9kq
z`Y%h^^nGF^<jnl7FFDm=_86kk&BaCOTP!SgamGl6Eas)a6T^g@k4u3RCLhV%=JIrw
zrU8D6QexEMZ^LNi8l@u{5sYJ~eyPQY(V2h;TPd$}<O%R^9}*I>ZhM_P0VfXZuK+_?
z|21u9DrJw403_BTT4Lxymc8<6IWonN^c>GVceHTWG&t)vDlwi8=7ceCwd+6`RXex`
zor~z`=rk9YFFNbKjE;>}CgN%YB>%<6k|IY4=+aV2MduZj7jCTh0{faTYn8_W*fNol
z8eDcjgz2*OO39arTKlH5<B+-Vk>MwGBgOIWU&dUt>8ET`$oVS0JfNo$q{x4eNZmsk
zcsMy-er<Xekc=Lc3*x&t<ll)RP(yE^>9F?trrRh)-CY{{GWWh<k;K~35TxZ!EeTCu
zw@h?eyqSWp7}5pp<ocJ*I_J!9a6PBu0ND=)912I#$b<h?33YV5+>rB=-=cr$3-YEy
z4-Q`^f^FUWuqg*p*xCgySL#r_M6$1NJ5cIL+qkGQoX^iBv~Z;wU?UY8_|i>w*&$61
z7u=c*s*eP32U&wr1}4BB1__8$93_v@y+Tz~pr+XjU<S1@P%p))WPp0P+dA|N{X6gi
zWeO$hf1)6o;aC(wTa0P@C^+pVAIqFD=Lxnj(b#_d9Cs#CanI^Ct>GpkC*NRdA`HM`
zIS%(!xy9-bDu-gCA5DI}J4898yP8OY9xiDukjozk@WS3ARfZb2@3@-nQhX&UqsyIy
z-D?gxFd~i-SuKjvt=z?%ZT&636PeUX>&nkEj{sD??pcjmR)hN|FziDR^ki_8+1DF?
z&keHF>d_r1<Htv;O|%9?Uwjz!)(HHOxc2smf#p~0FYnEWj&!IK0$=&HUj$W{Qrm4G
zEw)PtN|?VY;u+!E%jwR}-hqvKR0M=u6^l|tfzCx(T+Jp;su4;A*to%I=~{oKIDKTk
z@J6iO{&R9-xRTv_!T0GkXs1bMH$z~Tmk?Lv%u;b=+S&Vk3_2#Jqez<0DOvrGUq62%
zxjm77>!HWTtE&WiHHE#Zj0o;oPj4a++Ys|x+?Y;jnPt+%Bj|0(+Wn4X6-w0@6zOy`
z6)Jl8z#edOC&<8u0Wm#Qdhzq{ctBSPrD>fi77$>@JkosS<w$41)+jmfP%t&!F;|HQ
zCq)QXSM)!l@bkq5T`(pAMVq8f11WOW=JaOnw+@l4f@rS%yDtXY1`^CY@2RN5Ix`ej
zG(`2n;>&a@n+!vb+JPYD0g*GCthV?1?{AV55dmvr=*g^0*=+UueU1mvUm(RI=$Y0G
zRXPm~ryzwLh*9s_y6hlP&n_-3iE(h=w>#vvu8ZX7?)GJS>3jnPThYB<1#JvjSYZD1
zH9-5agdj|u1*g~KAb_SLyw8Q2OpQS?G#SS9+p}cF{twXr5E{0?jq9VBEb{>i$Mkw5
zg<_ftO(8wZ$BMa~9okyZnm|VgBi<21l7mC8Bo$x=c_G4O4VgX2_ML=rBSZYYB9jit
zpRIsxMxs+G>imqx-}5tCK<ew)ub<c4H}f?_6xGoyD2ejPILT-0Rddw*h*1B)s6Zk5
zjqE#JACKpDo11e8(VX5Tz)aDvITIyDToI28rAbH7%TwyBuP?i<%C@*1xoyRY7im<J
zLx6OpH6bbKT2w({oFH28`Ig$8N2ouUyQu7aaw#)l;kk7?FO=HPk}0i(n3xv@Y>A{g
zS51Ogdp7iNDy<vNBh0l6(7Jg|J^cWoDt?2T55O-S$f~HkyZSfn*tUK+U$d%OqO!kS
zqFTy$FjX9%my9gDP6#uT`_Vp`fV@>&(Iy)6KS>!mAroMyN=TDCA+OkV5=&Fw%h-fc
zLD-b5iHC<L4Gj&QKMl@N#Bt;`#L$p;bG*#ESN(^$dv%orqHxl^Z*0ugf8dK2xB<a6
ztQsR|gJl_P{!hY_cqu?v;Tc=MO0JXt_H_BcJ|o<0jt<=H<|nG0<9h2wV)NOG%vzNX
zxSBP79nzRs(LB!og1~Jsu&SkMBesAcGX%V~UY>4NCsB!boE{rieR$&&6R*$`7{g+c
zC*S?lGe$h8sQL}P_>;F}E6(6_20Ud@wNkH*3>f=)?FO6W+v`PJU+1%p-mdLNNxr%h
z58iF}Ln0W{oE|BHY(DpMJ-?B3&JgJankIWr<n8!GlDiK~g3J7;)J(J6;o0lmAqOva
zW4@QBBWaSJZZ@k|u+Y-?iD#Jj_$4=o^U7#%-XvZ(2HUHTOU<l8mZ-F)ipdI_^kc;u
zi~DTOt?Qd>7NRm(&L+W~LDiE8j$Rx8IqlRuScWhxUqGMv6{$l5U6@Ux|8fGsKw<P1
z@2zshqS5X(!{JhWFXlr<1BEdY3Gr7?c(ht;{o}>l#?6ZHlrnIF)Q;ceZKa{Z>349B
zX6<rA3w3z*tKJi&dYxsq?E@^o_~NRPta16yMVl0a^-SX&YjD0CA`<f)i$tiP!+_{H
z_Z>*<{(A*>;K0AZAK+g9djVMa|MTMi`;-5_w+tdu%X7y}eTL_HdKmE1zu-)5tnv9A
zP@?L(=yQCSefZ)d-=1Ck4p&0rNlXO^h2AcEm-XZANiqR<qc4f3+<US&_zo|D>+aW^
z<%Ha>Q53tQih?wuX^FJ%JuI1RZn55l^2!ZTSpU?D$te_G2TM^}t9kj1GE*i)bIFfZ
z7il!H=%_0;{(N%7T;$m$YD5Q<;@&E*FBX{{-m!mPY|5SK#rDFFJ>s73X!bIEkt#Iy
z^xeN(%=4*Nme0;lbJeSRaedv%d~Tc~%6xTyvZqq}Pw2yO{CyPI+5@}4oN>jD*vf5v
z<u;2GaxZcl6W^>>42%b*DN;CYj2mXt8@`I_M7P^4j+%XmX>=kR!WsK1?3Wt5spr_n
zVbepZG((9oQ}QM->jB5NrI7pincC%Ksjo%(J+s-u7e-SaH`6J)iO>H{`so{rgRC8f
zBITQFzQsjR*B_goea+fT*!RsQmUKL>gpYrGp3QO>z?{!Tu14b^v)_jbj`B!Ff;63>
zrjGeV9UHPB#$x>Zu>q?Bp4djbrb^Ap^OD5t_8Eoe&&|k<#{U+U?|1)#!QH#XG?9rH
ziJ$g+ZG2~2laDt;kq~$I;&<z|AOAj*pxGVv+hzzj|B|p*7Md=Z<hs;zv041RuiT+r
zczi@j??vJpA9iLt;=)?xQ1lMBKWDeE$~`c#c2z!!j>1x33!l#CG4{##Q7C7iC(!v|
zqD_$k%C>pn$h+8V?AO0e$m>i2+2Bb@_L|iChE=&jxHrsqx}*7are+t}Bt8a{>)l+=
znIQ+$KmRf`^cP`*argAoA{Ml=1@z=2BNng5jC*QV32=vP$tNj)V2;tMv!(kL>nuPK
zc%*%Jn=Ug|;;kKflkGz-izlB5#qIt`^U$%{&3{v$<1wNI>r>$9MFJ+|gF4ZA_es0)
zxw^h$jS`jCOvOksGEU0lv^wSC;-B;DBVGRs{l{wpdGBkyhLn+71k{2FS<dQ<9z=S<
zm*INjKPkk-sGm&Lu-oF|=j}IOMr_*>n^jAg!4m^Z;9&mmu$%Sjy<&wy&GcOD4K;qK
zIps|4ci_Q$a<V=AaB$9^bbY+gRo&guY|ZPm29J@<NO?3R>4AzXl~}^5@4U+0bp(HN
zLQ$ql0NTlHx1Irl?dz0Ag%_jC(=%^;$9*_<R~LO$luNmewSYs=duxth?=#q;#RhnT
zr6h)_GVmNN@PR~HxdB5t;o5C!J<#wemurDAD^8dfH;0CQ!Z0K5{s@96cd$apWeUnS
zuv_MJ!TyH@70K)`4e!7j$8Huh>Nq}AV{YnYf8#gNZO_Kzt<`T|w482_+||pF$rkE9
zZ@u2`yRy*?ejiOj1x63r09~b=$Cz5)^`&BMacgjw+;CL@qCns>Cf)Khx7m4Lp+i7Y
z@JZy~e9aUp%9r7%8|6A-*kpfLbnpbDgGC!-P(Qw0gs;Q2L?im)VvsY`300(7j6w1H
zH||+4&cxpT`f|3roqyHA>?zn?Evsa<Ox2)FS<VIgawPWZ$$ak*Zd>L2e<Q;w9T5O9
zzt^sUBH0|hf77(P;){;6`ez$|nB_8x=uQ<(ChFrE{PeKtKX}+}_i~e?1<I#O%+*XD
zQHkjiC!28yGZzj|xy+4*8Z$|L&m?bib1OlY;UmX~v5fWVm>9m**~1y_{Qom?QUL)v
zo~kyegRY*(hrfOKa7Urh>hk4x>-pxdSTJU+sq=jF+6v*j7g_d?n$-D|cq7M%<(`_x
zZ!*XF4Q@uQ*^n(&i&Ba!?fTYpCa}7WDo~AJewmq?K%Tl=&@x#s4;EkSLKYF>_Vcq_
zPBeNr*Aw$2t$8rqSg51c4GDQ7fti6yaL~+@@=v@ghX~x+I{PVl9|dN>{dxOC1~|uM
z%*q$;%vmo!(AJJ)Z47fYmhk3<a@e=+k=f<OUr)GJvY#!Q_F&lQ)V9z<C{|}bGU__u
z$%v0;Zth<lAhM<2(ohGVJlvRRk7YeRRR390>#|TQ2^tt<T0P;*iY5Cg2N0SDC*hye
z%u_jqga%hg+v@RJmZx@O{Rv>T#4Gi8%{SiRS4q==<i5e4$Qqya<5b?IG+*I&-tLAl
zTTf^djOr!qUR~hf4X1M8`Jw7&)8J(0h}to?_`GC-PZZhiT3p(k<^Y`uA!|9aRr*uh
z9^l5*>dWY7=Y!@p+p%J0n-|WGE45d`o&S!rtXA9J{=1wef&ZJTY?0EHDSpU`^lX-V
z^FRUpy#ckp^&{Wvm`bJQ_oQ-)(6ER1SWv_6daEx_#LpM&53hp+RQ^-RfHV?61Y`E6
zZEQ_sO@^GB*QKqMCC2>AlOBNZDW64=anJE8@(^qUVNJz3-18ewd$Yjc+Q?%OjZ%(^
zBQV1sujildd<p<Fh((@|F}5=SI3K*Y@0EcMLnLXAO!Xjhwf8+hfI}tF-70$ue7LE;
z4NSFKHF^(PiWU}5sYB8D2aij>XLjLvq8RPi>jYy$XXS!{ZHl36b?DnTO(W44#lP#j
z<up?!>l}W(Ss}j~_qP-%NEuyj>TrhnV2OdZuxsyfG$)ocIRMV9Z>=>JuS>Ey7rVO0
z>ee{6RD@PgSo1Uoo-YHD^>rx)!q>OY_l_!LViGdn{;KPE*^0+21@-DcnU^_6d-$J!
z(`FCitSfI#O=_DZ_+XP4qQ*ltF90T>VvG)VMk=POp3Fv>y?5pCoQeBJt+kQLAe$W*
zv3F$BWoE@sT+?y$iI>K}_iwk?Aft$$r;q+*{fd%&!5@ry&*Q){>CNuAGR(O*ziwz{
zsrDBz5FGyv6FINTcEeOQ-pgYQd8JykPc!EvbrjjrO*|j|VrtZ~$3&4NO+9<q<>4ta
zfuM8}GMyV6xAETKgbl>LZ(g<686TW;G#ShK=h^GwVVPG-0}!%<=laSIKW@y>Z~DEh
z?#O$+^+Qn6aqLOJvDb}EsiSZ9q+iUk3gwo0C3Ko&Y@%1jDu@;<JchN~CCCKsg#_gF
zWaGzooDOH=L;F!5eI9Ya8x1AKqGq?P;}Xk^lmKTAKhuQ${p`WoC=Ne+{XE7u22S_x
zpyl7UrQVob{f%YLKGx@NWb{&xhiOp*t6z-z9!+G3FX+LdT?|t`%2MA8UhsYPF3KB)
zZ*jc<YjKBmS(rthXQ67^U_FFPz&UaK@*EB5$L@K8YLttRPp6VtnZyG@VLq54AW-st
z|Gi5lpQPRPAR(6{$X97kRld@^tki@+1CD;mAti2lauHi{C8=o#>2L^|<M;XDSjXMa
zrUOR6b@UWt-Cw6D6Yl8f?<#O*v-y&?zwffx&JehNbS@m#+v1pnQ*C_OUWcA<?GpPP
zLNflc9}7{Y_x$!%n_gg-yBS}TH>6&GirWlEGXiqvy8r@1t;=5DSX^~s*-zt!tO(yp
zU6tFlXK%jwZI(Vk!IZ02!eLh`S#-WI#m&MUyw4Dx9m`!YSwtxu_9!fwEiJw94d3@O
zYzZ9(7gQq%1Y#tAhQys;MFZ~7;C*=iIcu+fU-^CN`6!gpM)NL9h8SwZZm-!x&G|(o
za-u{U$C<uL$-92>Y@c;(l1%Ni59Yn%PDginI&%buU;InxzTW-gz4mGe6nx?O+}(Gh
zz_i7P-6q(5WaJWcQhHft^Fd>vZ7j!ds>r?cK+Fg9xl9&Ia<l7_YMF5f5JOY*-*I{V
zVbyyXZZ2i}#wBiV%`7zh-HGit3d{8P82v3sp;9W5yzS<140^r58O#AH(Z<ciF3a7W
zz3<TikQwbunvahfGwuA@FZXnSWgrbcO%{kO`S9*$%HgY)irG~VbOC+3SsjDUK_nmp
z6i6<+rNirc+n!vW)!LdP+6g+rY=ffy-Z79Z7Ww&mTf&L$M;5DL$|R<&-HFr|eASYb
z;i~HRxz?_}S?$A1Uk^$gR-$3IBP#WR(?l!+T9_2Pml><}6^q@U?kD5B#fGr>65ORW
z@_ctPSr_KxMJ)FG_h)}wUFR;2qWI7%FImkAmpaC_f6$llU;DHK{%e?NE+|0*uy;Px
z1+7x-!TJWDozYGZsQriQ!;P5*XRn=h3L4bH=iz}(@unJ~ZsFca<PAU*==0Tdl0!*V
zwqp%<_(tj&K<XyRC)KzIMm{}Uj{_6{D-js~C;I$xNckLB1Hzg(jI#a200VopE3P)+
z*gJdhrbV7uaBzJpJItF;KprZsW1uHxU=mcC@sNilF$LYw{uZdT*E)F}Q?1bu7{T4s
zEen1K2h;V_Kcj*`0KWD>Oaj(KX2(SXV{EF~pLNo|#HFz8@|>J&*wxlcuj?!i+*+b^
z)Gyj$(E8gdT3WhtS{X4<V}T+rRB8<7DPj!uyl=X6vJtmWW*Q00ZNt`=uC@F2?k)JB
zTai_Fv#c=}^SLUCKQXHhL2>T^B&~QGw+<00wwW?y`MM*4R{3%s(IiUD%gxxau@vfn
z5?n^V%~R!@1V-bFv1)7Q&pAh{YHK<wF1e)DB9}|2z|9IiTcn9aKlyp>Ez?BXiLwo5
zJy;kScXOBnhEm<dR|$C;#JNn&SB=J&dnZV|7R_p2p?VB1pxW{e$BtJ<4>VeX<Kisv
zCRKY+cx8`|miTNIG7H7=5x(o@4Or*@*ezKM7YG;lFx>BaTs^T~L8-;n%CX5@K<8>+
z^~68G6;~b5(U+43UY$*9Kyo41C!0WnQ2JhZ7mOgkfq)=<krWY9VTlMHHi~Y`7=F4C
zi;JZ)hXthTw9lQ>Id<u5N*PPkJkC|?P8MHC3Xt#G>p>rA%B_LcO4SFB8LMagtRqWI
zOt;-gL>usF&_+D0&*k%s6kh>Zr0`xiujpp<_xqm#k;7(zF~|guHr^^qxASZ!OZ=Js
zx~rh4&)Kzn&-?MjHTC6KyW%0UV?gAO4L=_Hv+OL(_MsV=bD8_u8u0eo@B72GO(e-$
zzBJP*WjxNduk<wgCzAAP98wNc7@z>$2P<E7XmBUzd0v@rZvsvT=0pw|c;r?@Vz%!{
z;QA5n%kLPYF_gkqHYmT)KMOc_js$|*yJ`Iphl@4He!!zw@OXACgv-h3xV|n<pXDa*
z6n`+5^z#w6vKlZp;H0k08bEFYU%L}Nm>swQ5l1=SvHo*fAAO+}7Su>jT<!0p2hPfd
zI1f9)SBqI4{pVuhphT-T@np!|j~%rw87>mv5mdAPON8M~R3$F|nJkz?lGjo4T-lgy
zb-Jmy%@D>VF|A(~$5%Agj_)w!ZF+D6I6yhV{FD3ifP2%&TQ>hFNZrAY<2l$&-pjYW
zQ!0B<T`rji>=fIFp4$Q0<8#Nzw4gYbf0V!k<SWK|A|+Ck=+$7~EG_;}Fs=Y1#s18j
zJL8^}h~%Dk@_pnsIDl@S&Zyg1n}wOARu@oyc7^sNS~YjRd@twk+7~XlyB}PKFgw`I
zFBM*8&)C|!(-FI0X#e%$Qae>NewUf0dhE8-1b2JoP-oiN0#{nY*Ix0`4$^_=H=o6$
z%|-@c^t|fzvm8^w|7~nMOqiY8f#Wbt3n-S*X|mWa&o`Li3?&a!+{JI(;9M??(p^lq
zV!*85r}Az(12fUP6jWD{evsF&>i{B*J2maOm!~W~&0vsRNbuKY197^v$`kNB7BPI$
z1TA>z{P1%7cNP4Mo*JWWXve^o)(1I3M|{6@+hUjHT{Y0tJC#+ZJGY9j$<B6P8Bn3b
z7C5qC-5an96Y5G|G3B-E+p;~5&m&!)KW-2=MY|Tt*=djPxL(VH?n>3ZD~Bhs3E?*>
zUqpEZa&HT?)ur!_JA@h)JtZi~hQ?$dAz3&L8D8i3q?N@#$T@xKx@PG<zY)<pG;f>4
zp6kl2A#nrzl;TNL%iiQ&td}6G_xT*3O*x^uF)*C0*2jO`)m-GW@0UlsUuK(X2zk$6
z!8iu2>)8|BtDic2(L=OdC06PX8MQs!+J8lMMC8@?hU<i{2)z2`hy7Paa&q4By50B+
z#{mbP*Xe)NI2q9b_L-kg3bVR_wpr+5DQobN`Vzueabi199WZM;;`-$4*{_>dCix}s
zN}01#*<k_+yiF9S2d?bcuBFt<Ng(W4cbFXU!k@Bj`b9$mn^^T<4YAEiEs%XI4ojAt
zdGZM!GBZVp%6ME>Z16sFLnLMsMXrA`^N*pig3gBlBS`W)`DH-|@1(Z%UG1qGNR}?4
zy#TNWg><g4NYi{nknu-0sk=7J_<UIpkiM9_SLxKhAdat7DM0%W$~~nr=+Ei&shz(c
zl6?Nc4O)%W{2m^N4v+^yp9f=uS0W-VYk)EB>|O+BtJNws>Bj6`55e7s1Xfm$R+&S7
zQs8|6>ncKeuFEa*X>UGLn8D_lq$9)uYP?TnOKz!E+*Dwx@`|YB@QLaeNGL>Ga<oMj
z{>M2SZ|zC-ngu+`;7?o57#)_{PBIoKx1Z^}8W{b%5Rd{jU*mTcohj>jw^E*Qrn=c2
zQo^A=;4E^Kn?0!U0-QDmusrv0go=SZY&a^OJr1Vy;pT`87z`d4Pl4#zIgVz`SLOOT
zt=7)l7Jwp9)NT3`5g92gUv4}>c@qam5u<f->f3I6iNO)ITn#(6uSfTOblo|44UlZa
z)NE$kW(hQNj7Xl(3>qUofeq&^`tn_zOFW0!m!TV0byFN*cT;!oU5y`RB7tBo?evb!
zx}|>e;u5`BkKZseSR<udcuZ7*=PDV8seacJKNbTP=PH>X6)3-fZ2CgY?`p47jSidg
zho*%8YP@#V#<dq)@Iq}QWs#OMhy+QgD|i8Tl{J)6lmBWP`YOfWNa9!3V)MaH@K4m^
zKM!B3VxKj~$E17Kx`2!54`ue23{ga*+7k?}E{4Dt4S!&Yud+ksZLt2pEPdjCDz2;9
z!VLqHQoLGJt=&;#i2Jo8pP2UVMH$F57gOYFBlowOcOQ4V(Qd!4@J0YXV#)Cm-QDpF
z)%hy$i>U4L36*{5mI3^w0&<!a>Hl^A5^;O@KBC%lfqk9s>x655OSN1Zuh$R=Ub|Si
zvd`3GBa_V?1q*C<#of$rKM6E%j(P<S6FeVfk(=<dKR>kjO)Mk%(${z1Y*P;Lak?nA
zufu=~mLU=h2U73ii_l%V4Bx38FW_^LLulEm!ZJtxJiw#Wt?VtGPb>2|xr;Yj4Z`Tt
z)pT_K%bVI)n*XwUwmS&l0a1mt6kVos$B_s{7ym52!0x*O8g?qE_!SC(ib&;Y=K)br
z;;ccbyJc*ju0q|vpefsaKogBA`!vkCuc(CLd!7xJwx;t7v-AWK(2!<ZjUU|O)Ga_}
z1X9t>IYZ~ArpUrZVsB)bJsPPQlMoyJ*U1skZVBf-;G{H>CBJEi>Ss;bczDCeY}e6<
z1Os+^0~AOj(`Z~DyPh7-TU|_0R1HBCma^L?XZnwhiP>;!lCo^sY2-NMfy65%$6^}L
z(-)8|T<Dtc0suMhz2E{k+SifVA*2G#@%`4cm7XmHW4nAiT4Y9<aC}F{0VJq22mK)q
z_bpu1<JCXkA|iy9+Z^|n+R#9vOJQ<E+rHG8^_n6*>(E^S>9{i_dw}R$=ACu22++I1
z7}F~rF7mnWHIq8ORpg`~9oqi_x+Z*T>{FQS$wGA`$S%V|t@LwR+G#|b4+jCL#iyJa
z`om5A+a{@gdEn2Wqiou?`!`mmnfmDh8*QAsUEW`eh^F^GL-oQB!jV}035fa@SDQkg
z?hf6n+k>gL%qlf&34kbIH^B~^Q*0-#e+$<Fz{6lo_NyenHLNVPvDZ{6ng0feYtG;<
z!JT#000<=s&6bjWcH|*~hlz=E)i0}#{}QA{pS1di2aO)8jTxz2^|$(){-3_iGpeaz
zYr{b)A_xZQAfSLC0Ya}4q=YUAN=Ld>>Ai!1f>K54O*+y=#n77+0Rt$#iS*t}0)#vH
z{(NiQA2&a9lF6*h%--*Q-ZOJN0OyLSrGu*}w_k&}FhyPnpTraag1*=x`QsMB_Uy_1
zZB$*PP7=<1S(NojBt#gmKk%fZF{BQ`Glrj&z82TO8^aZ2q4HjyQr;U#pd~d}g!}nw
z@2^-K&t}|$Ea?z@;HMC9S>Ev5)&e=-$}UGD^H*7X4N%|qpy(8Z-8%Iz%S!#e?X0wN
zbw2(b2nTyDb6#gApegdL0}1reWwECwE7!`MkmoZ~@yjhKRi6VaV2|M~I10!UQ|9dA
z9J<$B#0Uj2RRK_vjHg1B5XMo?<;a0Ih#ag5DseIalh!E+r1Nn|3yJ!$JIyMqI~|ZS
zIv@prxSYL$$^nm|CEp&pGZ!;+9`$youZF!v5PS!3_e7bL&0Fvp<8vdg83L~L=pT}`
z-`X{vBJity(@upo=e@w5{xQ>^za_yE{C7rSv-o|C<MaVtQk|2>2NddEYlic`HJbt7
zZ+-`sAv=KXMVr;dRo-9{dVrYbn&RJUC9nxPxB-xE@$)RH;j~cgTeH^aI%)cSMP;C8
zKB|qd0SqPhtRpq!{Me*k#$WbeF6gbdU{<9h>@=Dy#{zs-#V|<)1cIoj7g|~MKCVE|
zjE{2QwHlZ<yVK**k-=!;d{YZ_<>kBcUiaqdQ%MWHDOXU|W+H<B=u!#-`V8F2^BRN6
zAD%WqSPi2KpwI~d+vFrLqb0o;#k-pJG!qx{fy@#*`anl+g$^2>1_A(|&2bGbd&cW%
z1pRCr&`cb>nF=7w75y^gJwdQ?frh~nx551LW1haeil4+FZF=vVei|3_b+VG$136jD
zrFsu{sLvp3u`a4rZ_{tqRU7orx6(|%-RP?uY6oAXSJh1db1Ah-#nl<FG*(Gn@Vx-?
z1`0GGGXLJkr`H5(!SVvaF)}n1Qq*ts7u!FsKevp+&8$wL_#WJ_0>!4Zicxa}kjiup
zf0l}#X>b9vArp|xT*oQ`XV^GM*)ahNx4S5|lyfxW2R;5i#*cm0)VFGz=T|_-7gZH^
z{n<Bws{Np(b@2*u`E#R^vyHt4*S~3>qzWJ?h)867S=y!yW1l%k`ctF_bLimjs$E!r
z`)uZ>PXy}LJeGre?aZ!rzC|{h(KY)_diO*eWl8($IIiztw%w8)C;;o#)jf{j#!%!A
z+8h{Oq@VP{L4ClLoBG@l5YtWtr+fgXZce4^R=y}pz~1n4Up+wb2pEGhf(XXT5qL@f
zSkerkk^*Syuv7dX5Dhqm!LF&*Xt~MyPq7zZtpS^>VI~xy{ffbFQJaI25s@BtgC%aw
zpT=rs)huVr#qqHQv_fFV><{1J*YxbOt2fFZo9zSjwLSABGx+WCC!@olNKY=uy_~;j
zKrxUY85H16GH=c5yYU85Wm9&6C1)W4-O~!Cnz&NGw|bz+Y~l6Y;S;N>L-l5N%CMkY
zE%M)r_^pHR!YJ1KI{xy4A0%V9iud|JYii$aSjJ=nbE`YA6YYC4K-wtmbp=2LfHO2e
z73b&N&!Hdi6opxqpOSz6h{8I^oyraKorhi8b3WN&1h4IF8pYyxi<7{3tVx=4qhtJk
zc)@!n;#;6<uIz)?$DK*qJB+^e)@4tO&_5^;2N_Qlw|<5Yyb0px>gnJdDs`>3S$d?{
z##_?iGy8T!JoIEnzZ~5KEJNV!j!)*3cvW#ndLY=t#rl$mc9V^(J;9dm;KgZ4Be?PM
zZ<rw<Y|H8TpWS81Gzjnc4cb3~+@oN?P=zZu8*EYnLe4qo&H{k2(9(~2KNjrsAE4N$
zmDDU0a93x4Pv^cZ&NA-Pl;y}0Q2Ls}Rc4_o@cEm&>5+IYvK)A*nwDb@Bn;+&VeG;2
z=S)p-*G`{q(F?ckXQc)bk`pu-B0s(B<kme0@S2mUOMGGDEZ$WmR>1`_F3?6wgM1?(
zL22Q2`7eKP_1t#;EJBvHFO2mVM272l7I0+jh%dVU;q#L^ChjW+)F&QPL7s*K0Jquz
zwui6(Kv@V9+<Nlf`vBRwz$Ti2pHkcQvoFIsaJu)hO1;h5+QPyzTReN68ib`Yv?y7u
zH-_?=(LJpN_9B(0SzL_b_X-?F<Xa9N`%6WWP*lVDV*AT^Kcx*IXsP7S8n)XPi{+2L
zu}XIxFLe8T^Yg$RbWm0@MhrNP<c0h$a)voWfXld_6LdE2ffWh6cgv!!?a+QW0z_K(
zCN5#v+X&X+zkTe=J+4yro_&0tEoaVk!_tyxx2YL_ZkUA(;K3(3X`*hUrNB}l)TG}t
z!TPdmWCso0-7halK_mbk%^I}Zkcv3jh$bP_{p02YDhLKL&96h0`m=rFT(!P}995W(
z(%;zDIcuK8niUrzZB>)M;<G*V0K<dHJP%mpUVn-HenGI$7RH+8B7QBY>s_^L94zT?
ziUJ9}cp%&HdoPWwrXJl#2xT~XH?kV=87xI`9A>8(x!S}xefS*=@2u|<(fXf;tTuKt
z4xlxrqvSxuEs)Fa5}|PV)pj8(;BJmcyxkz=b$mA^Q50zO&FNsnM_2&A$ZsF1rI{1}
zD+_P9pEm4x3+vTa7<OboDYgSQEO^26m&a;tF(=s%IL>#k_CBkpwzCV$PXGCPV+^2S
zjkkZzKk1dUg1^7!{9IUCGt*pcWAx{^WN;?lOAnL9;T_!RC$;y0i`RIvRfqS}m~a@a
zD>2XYH{dM-FFJ^M(lqdhdIdZ!Yb#4y71;0vzp_e!QwfvV1jAn8(hxft7G@BPi3Fo%
z?(Zv+#U$biPS82@9A(kL@*_*jxJ`<7{>}qd^BAA?fM8^U_4NXl34|(>m03_jXAG0v
zO@6#p?qS>bOTB|+e=uDUFF`v>Ujyt}WSM|PaK>^djUF9<Dr5IZ@9ffLXFETyd|x6o
zgh|Q9G8IbCK%5#O)b>~+cY!Ru(y$&miM?V`GhwK05+DdOR-NK=a`LIAs}qZ_=ruGJ
zyfKi@A@`9J`H?11m~f4`O`9|!(I?H9q39w!jf=&WZCazSImcs}In{4@cBNmKE@U<!
zXO8l<N3E-bxcaqBaBNH@d1cem?S4h<x4N5`Q`QBQA;{EN_fd9#pA7@;e_u1TWT@5j
zQ(+q4ht$Kq3{>4Y2!EExwsDZ}S5lYRy^~{fHP^P3W2%}&wKx8a7*wkGvPh#v-IL62
zC$D<>`fpvsNsY60SP9|*0VLU_1!)x^?T*fri%|-f)ktMyK5;f=h@mAjO_$Q82B$V)
z9m^%%2}yWhH3+H6!k~<qI8h8{&@X`9qwR`Ca%n{w*~!+_>lrRh^O?oo_7}8+wTlJ`
z?>REZ4wU090}L6C^`Dx{8PGFMPSx<hDev&mcn@UX2!X>Pt)@w&S}RKyWkXTLNB-pl
z=<c*++D0b2*Y;9bgD&pgVtOIR42J{+d4<C|Z;3FJ2#6VqId*G{xgy14yB#@5NZgi?
z7zdB1YgOPu_D6unu*}U_KrQofqI5*511N&xvg|XopSlt*b-{1?J4$5xJ71+@)m*FF
zl@#n@6o5xwF&@6rgY$(8oovy1W0-`72@a=qvatVP?ZJu9F8!IZg(UR~DsK@9Q5Kdz
z?22;|XlzlSwni$((x@3rh)+Cfyr5VN+`lv0{6+Qju5?+vwD>nhq2c+3V((JJFN=G&
z3C&x4n*lBj+&$^OXSd~p-<9dw3Re6HVqyQF@hbV3rbV=7)rjR*f$Dczgo$USuy1Mo
zs?3`8iO-zH2h;e6E-pht*_J&wJMBbD>>T8sj5D~$4OwpU5gI@Qd=^z+z+oMzQ9a1R
z(Y4=p8|&>!3tglHv=H8FWF4hN_Y_M;stqb6?8K~oMM2vorOtwks+3>0g+92KWCu6a
zQH*e9X+nP>w%M=R#%g1{qE`1Yr=@#6qDDu#W-19phvg$(1M1XjkKZ$>@6MegtR=UJ
z!P))HYiE=l>K`AX_Q-myg#f{ta57%Lo>a2@yJEhwPw9Y8CdSI|b;3cfa#TjjHAiD6
zis#4gn_T&0-!rv5OmLQ%_4CM|x(ox2DxxEm6-|%Gh65HF2Aq{ge!P`99uOaYY!F2l
zPB5{zx0}=l%^zY@$`AYDfLx0tD{*i_BA?v4?&tu4+)jBa?(@#im(A@D_xPqaJs<5;
zG4YP+>6m@2Kl4Rb5JjzknOoY;OC}d;K;h<UN#I8LZhkus-J4Uzw&*LXX;~gGMCc?A
zLem(TkZ5HJrY<PhJV^dIB8@8J#)@Ov{6ZP6SaiV8#V7{Wx2bzI2K%SN1}#`YdZA&r
z-G!#q23M$&ar*rIq>hA|4yO#c`gyw-t1VB%YQGtLv!ML9%z5{u_4Vqe9i97xMACav
z(b1C$v_Obk0$W4ZlLnn=!jC*O^13{K3@gT;n#5et&=`pLi}32fMweF>awo`hZHu`2
z$LRbkXt|geu}&um6ER@Dfx(18vUH-kLqcM9_riuO-I!93imO5^#aG;ON<R|l#xYdS
zda7|EoWF;$zl(~Zw>~PIHh78ju>HOn;J%-r2F-a-uAo$(Ks4H|6&u=WzA5GUW$s&9
z*{@@a(axmhqZ>y(=jP&9u7pP}QGE@8APRI8yEIypvtG&hd{mO&ZgzAfgrQlbUxnKU
z>%}p>MzJej&zLSVGEOu#owbz)U9CoNk$}ZLn<;oT5r=Ennf}y>sFNF|bZee_W`hMo
zbNX{>*NfLfM$DU+HlCp)5p2Mb4bX2a*F0TS;nr11M7gA>zX_OU^;f<SSs^|xNzMLz
zd!_#af49unLjpvd`&uYA`_?5}y_4AHEKZA>hQ+P7hZ#x}{%(QDS>2!aQB21i?#p_8
z(_>6rVdKN@P4n$E;lcYK3?!X1SNYrF8|zr76+17{7v9o3d3gf&xmCW5tqm{LhrJ<P
zoiIK@S(Og=+SIX2!pM3J4WmZw*gmMZ<_;e*GV#%J(36il3b`p#L80O0%@U4aO#fI7
zx!9O%`7{1XgAF;=wwYM8PgPwKF_{_Q|J*zAJqq_>5Qw8bKh&lU^tkaeKh0(DtnA<Z
z9;mhzR7UE$eTJDr-N3RAuh4yrwx{=(h3GlXYXs)D%F<$$>PYRj#ErXG4^q6m@+Ko+
z_uJru<MC%9LLTbxE6Ldo|8S<JU`FH>is%1$=|x0z@ok5EIBsn8&C8D|*U2uc40$2n
zSC%uNC6E6e{j+>8eQZ0i>3yDGKq%_uWFX-{eZJ`4`8smm*NIPzhOWb=?&_-QmvsMA
z0k!pY*Nk*jTvXKR$^zHKDem#l>z<yT<{M0KtBzW&?~TEZzJy}Vn7Zma&se2tO5x3K
zVmI^_X75|w%)KG+s4fiFg`gi+gV$Jcx4hwmlfz<xtn6ca)|(7@7iiP*h9sG}%=7k9
zaWkdqMM3)IDkv7^gOeY+9W(aR3WeIfs`8aFBui}TOyqh^jX`!&xb$2It2Pb?!rRNz
z8fagBe$7T_w9F2FCIi*WJtMy3R1NM=6_KM;OiOh9t#f^3Z`s)s^^D&9T((ImKe$Nr
z^Zgquz0>(-+N5)9hAc~m)KQ-fq#;3<MU^{0I$5o(EZjEv)M0#)YWEZ>^1m%%?>|u_
zRgM0?)nn1SfM%1i7mN!^4)<7A1N%KX)aSR}3H-UgH&3mR;{|u842&3Ew((Ud<nP9w
zeyYKJ<r|Eg9=2`q_?MLX^agU=X?us<<an_*H7OyYG5l<3a++KV#f*)vV|U;5O$o+2
zEEMmmc#2T9oBUR^qq$B9`@kQKw0-sJt_LnK(EpfMs=ndlyIuhp2cc9URnnEK+Eb&%
z88Z|h2Ucn3#LdT@sB=;^iU){&*39Vw5g+nU?J0H9ny1~`W~bd(Mj0Unh`F8}x3dmU
z<i%6XUt$4hMC_PDqQ~V$k5mxjijnc14=MtJ0yh`F8qL%HNVqfZeKNycUa2&MIjEl4
z$~*9OKbCIqwtbj0v&5pMs3=kr&YNqi&>);M@{o{_c%kh_{2``3MSlJ>q3``dhgC|J
zTLnzG{4><B|4JNViL0z^#2E&KkmWo*v#tU`kBpymwt$M%CZ2wNUq%*X;`t)NXv^DM
zRnR(0J>%j*NU5rv+{GyUX4xFf3ju`=jj+utKLlI4JK5fX!<M4tXu<J%&~RRGoZMZ@
z1mu5T5bXK?3x|D!E?p-{&y_$(SSS{GIHGGy0ErY81<|&j()uQMc`2$AT?KY??@CqO
zI@+6Ii+jNMe!-a}bm#Q%0^Om3cUJ7u^TvCD<ik7L=G`^j-84)-;^z-@Y5MoPCtgB)
zrGmE!9}mP^xAI@%t|z`2z2bW&bzxPtH1?8s-sfcHrk&d+wEH%`yZ_@g^z}scAIt7s
TJ5j|11iVy{nu?Y3<}d#P08gaH

diff --git a/doc/load-balancing.md b/doc/load-balancing.md
index dfaa7a7f33..03c9bd2cba 100644
--- a/doc/load-balancing.md
+++ b/doc/load-balancing.md
@@ -44,30 +44,31 @@ list of servers to the client.
 ### External Load Balancing Service
 
 The client load balancing code is kept simple and portable, implementing
-well-known algorithms (ie, Round Robin) for server selection.
-Complex load balancing algorithms are instead provided by the load balancer. The
-client relies on the load balancer to provide _load balancing configuration_ and
-_the list of servers_ to which the client should send requests. The balancer
-updates the server list as needed to balance the load as well as handle server
+well-known algorithms (e.g., Round Robin) for server selection.
+Complex load balancing algorithms are instead provided by the load
+balancer. The client relies on the load balancer to provide _load
+balancing configuration_ and _the list of servers_ to which the client
+should send requests. The balancer updates the server list as needed
+to balance the load as well as handle server unavailability or health
+issues. The load balancer will make any necessary complex decisions and
+inform the client. The load balancer may communicate with the backend
+servers to collect load and health information.
+
+# Requirements
+
+### Simple API and client
+
+The gRPC client load balancing code must be simple and portable. The
+client should only contain simple algorithms (e.g., Round Robin) for
+server selection.  For complex algorithms, the client should rely on
+a load balancer to provide load balancing configuration and the list of
+servers to which the client should send requests. The balancer will update
+the server list as needed to balance the load as well as handle server
 unavailability or health issues. The load balancer will make any necessary
-complex decisions and inform the client. The load balancer may communicate with
-the backend servers to collect load and health information.
+complex decisions and inform the client. The load balancer may communicate
+with the backend servers to collect load and health information.
 
-
-## Requirements
-
-#### Simple API and client
-
-The gRPC client load balancing code must be simple and portable. The client
-should only contain simple algorithms (ie Round Robin) for server selection. For
-complex algorithms, the client should rely on a load balancer to provide load
-balancing configuration and the list of servers to which the client should send
-requests. The balancer will update the server list as needed to balance the load
-as well as handle server unavailability or health issues. The load balancer will
-make any necessary complex decisions and inform the client. The load balancer
-may communicate with the backend servers to collect load and health information.
-
-#### Security
+### Security
 
 The load balancer may be separate from the actual server backends and a
 compromise of the load balancer should only lead to a compromise of the
@@ -75,43 +76,60 @@ loadbalancing functionality. In other words, a compromised load balancer should
 not be able to cause a client to trust a (potentially malicious) backend server
 any more than in a comparable situation without loadbalancing.
 
-# Proposed Architecture
+# Architecture
+
+## Overview
+
+The primary mechanism for load-balancing in gRPC is external
+load-balancing, where an external load balancer provides simple clients
+with an up-to-date list of servers.
+
+The gRPC client does support an API for built-in load balancing policies.
+However, there are only a small number of these (one of which is the
+`grpclb` policy, which implements external load balancing), and users
+are discouraged from trying to extend gRPC by adding more.  Instead, new
+load balancing policies should be implemented in external load balancers.
+
+## Load Balancing Policies
 
-The gRPC load balancing implements the external load balancing server approach:
-an external load balancer provides simple clients with an up-to-date list of
-servers.
+Load-balancing policies fit into the gRPC client workflow in between
+name resolution and the connection to the server.  Here's how it all
+works:
 
 ![image](images/load_balancing_design.png)
 
-1. On startup, the gRPC client issues a name resolution request for the service.
-   The name will resolve to one or more IP addresses to gRPC servers, a hint on
-   whether the IP address(es) point to a load balancer or not, and also return a
-   client config.
-2. The gRPC client connects to a gRPC Server.
-   1. If the name resolution has hinted that the endpoint is a load balancer,
-      the client's gRPC LB policy will attempt to open a stream to the load
-      balancer service. The server may respond in only one of the following
-      ways.
-      1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client
-         call will fail.
-      2. "I am a Load Balancer and here is the server list." (Goto Step 4.)
-      3. "Please contact Load Balancer X" (See Step 3.) The client will close
-         this connection and cancel the stream.
-      4. If the server fails to respond, the client will wait for some timeout
-         and then re-resolve the name (process to Step 1 above).
-   2. If the name resolution has not hinted that the endpoint is a load
-      balancer, the client connects directly to the service it wants to talk to.
-3. The gRPC client's gRPC LB policy opens a separate connection to the Load
-   Balancer. If this fails, it will go back to step 1 and try another address.
-   1. During channel initialization to the Load Balancer, the client will
-      attempt to open a stream to the Load Balancer service.
-   2. The Load Balancer will return a server list to the gRPC client. If the
-      server list is empty, the call will wait until a non-empty one is
-      received. Optional: The Load Balancer will also open channels to the gRPC
-      servers if load reporting is needed.
-4. The gRPC client will send RPCs to the gRPC servers contained in the server
-   list from the Load Balancer.
-5. Optional: The gRPC servers may periodically report load to the Load Balancer.
+1. On startup, the gRPC client issues a [name resolution](naming.md) request
+   for the server name.  The name will resolve to one or more IP addresses,
+   each of which will indicate whether it is a server address or
+   a load balancer address, and a [service config](service_config.md)
+   that indicates which client-side load-balancing policy to use (e.g.,
+   `round_robin` or `grpclb`).
+2. The client instantiates the load balancing policy, which is then
+   responsible for deciding which requests will be sent to which
+   addresses.
+   - Note: If all addresses returned by the resolver are balancer
+     addresses, then the client will use the `grpclb` policy, regardless
+     of what load-balancing policy was requested by the service config.
+     Otherwise, the client will use the load-balancing policy requested
+     by the service config.  If no load-balancing policy is requested
+     by the service config, then the client will default to a policy
+     that picks the first available server address.
+3. In the case of the `grpclb` policy, it opens a stream to one of the
+   balancer addresses returned by the resolver. It asks the balancer for
+   the server addresses to use for the server name originally requested by
+   the client (i.e., the same one originally passed to the name resolver).
+   - Note: Currently, the `grpclb` policy ignores any non-balancer
+     addresses returned by the resolver. However, in the future, it may
+     be changed to use these addresses as a fallback in case no balancers
+     can be contacted.
+4. The gRPC servers to which the load balancer is directing the client
+   may report load to the load balancers, if that information is needed
+   by the load balancer's configuration.
+5. The load balancer returns a server list to the gRPC client. If the
+   server list is empty, the call will block until a non-empty one is
+   received.
+6. The gRPC client will send RPCs to the gRPC servers contained in
+   the server list from the Load Balancer.
 
 ## Client
 
diff --git a/doc/naming.md b/doc/naming.md
index d0c892e8d9..5d603061f8 100644
--- a/doc/naming.md
+++ b/doc/naming.md
@@ -1,30 +1,59 @@
-#gRPC Naming and Discovery Support
+# gRPC Name Resolution
 
 ## Overview
 
-gRPC supports DNS as the default name-system. A number of alternative name-systems are used in various deployments. We propose an API that is general enough to support a range of name-systems and the corresponding syntax for names. The gRPC client library in various languages will provide a plugin mechanism so resolvers for different name-systems can be plugged in.
+gRPC supports DNS as the default name-system. A number of alternative
+name-systems are used in various deployments. We support an API that is
+general enough to support a range of name-systems and the corresponding
+syntax for names. The gRPC client library in various languages will
+provide a plugin mechanism so resolvers for different name-systems can
+be plugged in.
 
-## Detailed Proposal
+## Detailed Design
 
- A fully qualified, self contained name used for gRPC channel construction uses the syntax:
+### Name Syntax
+
+A fully qualified, self contained name used for gRPC channel construction
+uses the syntax:
 
 ```
 scheme://authority/endpoint_name
 ```
 
-Here, scheme indicates the name-system to be used. Example schemes to be supported include: 
+Here, `scheme` indicates the name-system to be used. Example schemes to
+be supported include:
 
 * `dns`
 
 * `etcd`
 
-Authority indicates some scheme-specific bootstrap information, e.g., for DNS, the authority may include the IP[:port] of the DNS server to use. Often, a DNS name may used as the authority, since the ability to resolve DNS names is already built into all gRPC client libraries.
+The `authority` indicates some scheme-specific bootstrap information, e.g.,
+for DNS, the authority may include the IP[:port] of the DNS server to
+use. Often, a DNS name may be used as the authority, since the ability to
+resolve DNS names is already built into all gRPC client libraries.
+
+Finally, the `endpoint_name` indicates a concrete name to be looked up
+in a given name-system identified by the scheme and the authority. The
+syntax of the endpoint name is dictated by the scheme in use.
 
-Finally, the  endpoint_name indicates a concrete name to be looked up in a given name-system identified by the scheme and the authority. The syntax of endpoint name is dictated by the scheme in use.
+### Resolver Plugins
 
-### Plugins
+The gRPC client library will switch on the scheme to pick the right
+resolver plugin and pass it the fully qualified name string.
 
-The gRPC client library will switch on the scheme to pick the right resolver plugin and pass it the fully qualified name string.
+Resolvers should be able to contact the authority and get a resolution
+that they return back to the gRPC client library. The returned contents
+include:
 
-Resolvers should be able to contact the authority and get a resolution that they return back to the gRPC client library. The returned contents include a list of IP:port, an optional config and optional auth config data to be used for channel authentication. The plugin API allows the resolvers to continuously watch an endpoint_name and return updated resolutions as needed. 
+- A list of resolved addresses, each of which has three attributes:
+  - The address itself, in IP:port form.
+  - A boolean indicating whether the address is a backend address (i.e.,
+    the address to use to contact the server directly) or a balancer
+    address (for cases where [external load balancing](load-balancing.md)
+    is in use).
+  - The name of the balancer, if the address is a balancer address.
+    This will be used to perform peer authorization.
+- A [service config](service-config.md).
 
+The plugin API allows the resolvers to continuously watch an endpoint
+and return updated resolutions as needed.
diff --git a/doc/service_config.md b/doc/service_config.md
new file mode 100644
index 0000000000..6093fc3445
--- /dev/null
+++ b/doc/service_config.md
@@ -0,0 +1,201 @@
+Service Config in gRPC
+======================
+
+# Objective
+
+The service config is a mechanism that allows service owners to publish
+parameters to be automatically used by all clients of their service.
+
+# Format
+
+The service config is a JSON string of the following form:
+
+```
+{
+  # Load balancing policy name.
+  # Supported values are 'round_robin' and 'grpclb'.
+  # Optional; if unset, the default behavior is pick the first available
+  # backend.
+  # Note that if the resolver returns only balancer addresses and no
+  # backend addresses, gRPC will always use the 'grpclb' policy,
+  # regardless of what this field is set to.
+  'loadBalancingPolicy': string,
+
+  # Per-method configuration.  Optional.
+  'methodConfig': [
+    {
+      # The names of the methods to which this method config applies. There
+      # must be at least one name. Each name entry must be unique across the
+      # entire service config. If the 'method' field is empty, then this
+      # method config specifies the defaults for all methods for the specified
+      # service.
+      #
+      # For example, let's say that the service config contains the following
+      # method config entries:
+      #
+      # 'methodConfig': [
+      #   { 'name': [ { 'service': 'MyService' } ] ... },
+      #   { 'name': [ { 'service': 'MyService', 'method': 'Foo' } ] ... }
+      # ]
+      #
+      # For a request for MyService/Foo, we will use the second entry, because
+      # it exactly matches the service and method name.
+      # For a request for MyService/Bar, we will use the first entry, because
+      # it provides the default for all methods of MyService.
+      'name': [
+        {
+          # RPC service name.  Required.
+          # If using gRPC with protobuf as the IDL, then this will be of
+          # the form "pkg.service_name", where "pkg" is the package name
+          # defined in the proto file.
+          'service': string,
+
+          # RPC method name.  Optional (see above).
+          'method': string,
+        }
+      ],
+
+      # Whether RPCs sent to this method should wait until the connection is
+      # ready by default. If false, the RPC will abort immediately if there
+      # is a transient failure connecting to the server. Otherwise, gRPC will
+      # attempt to connect until the deadline is exceeded.
+      #
+      # The value specified via the gRPC client API will override the value
+      # set here. However, note that setting the value in the client API will
+      # also affect transient errors encountered during name resolution,
+      # which cannot be caught by the value here, since the service config
+      # is obtained by the gRPC client via name resolution.
+      'waitForReady': bool,
+
+      # The default timeout in seconds for RPCs sent to this method. This can
+      # be overridden in code. If no reply is received in the specified amount
+      # of time, the request is aborted and a deadline-exceeded error status
+      # is returned to the caller.
+      #
+      # The actual deadline used will be the minimum of the value specified
+      # here and the value set by the application via the gRPC client API.
+      # If either one is not set, then the other will be used.
+      # If neither is set, then the request has no deadline.
+      #
+      # The format of the value is that of the 'Duration' type defined here:
+      # https://developers.google.com/protocol-buffers/docs/proto3#json
+      'timeout': string,
+
+      # The maximum allowed payload size for an individual request or object
+      # in a stream (client->server) in bytes. The size which is measured is
+      # the serialized, uncompressed payload in bytes. This applies both
+      # to streaming and non-streaming requests.
+      #
+      # The actual value used is the minimum of the value specified here and
+      # the value set by the application via the gRPC client API.
+      # If either one is not set, then the other will be used.
+      # If neither is set, then the built-in default is used.
+      #
+      # If a client attempts to send an object larger than this value, it
+      # will not be sent and the client will see an error.
+      # Note that 0 is a valid value, meaning that the request message must
+      # be empty.
+      #
+      # The format of the value is that of the 'uint64' type defined here:
+      # https://developers.google.com/protocol-buffers/docs/proto3#json
+      'maxRequestMessageBytes': string,
+
+      # The maximum allowed payload size for an individual response or object
+      # in a stream (server->client) in bytes. The size which is measured is
+      # the serialized, uncompressed payload in bytes. This applies both
+      # to streaming and non-streaming requests.
+      #
+      # The actual value used is the minimum of the value specified here and
+      # the value set by the application via the gRPC client API.
+      # If either one is not set, then the other will be used.
+      # If neither is set, then the built-in default is used.
+      #
+      # If a server attempts to send an object larger than this value, it
+      # will not be sent, and the client will see an error.
+      # Note that 0 is a valid value, meaning that the response message must
+      # be empty.
+      #
+      # The format of the value is that of the 'uint64' type defined here:
+      # https://developers.google.com/protocol-buffers/docs/proto3#json
+      'maxResponseMessageBytes': string
+    }
+  ]
+}
+```
+
+# Architecture
+
+A service config is associated with a server name.  The [name
+resolver](naming.md) plugin, when asked to resolve a particular server
+name, will return both the resolved addresses and the service config.
+
+TODO(roth): Design how the service config will be encoded in DNS.
+
+
+
+
+The gRPC load balancing implements the external load balancing server approach:
+an external load balancer provides simple clients with an up-to-date list of
+servers.
+
+![image](images/load_balancing_design.png)
+
+1. On startup, the gRPC client issues a name resolution request for the service.
+   The name will resolve to one or more IP addresses to gRPC servers, a hint on
+   whether the IP address(es) point to a load balancer or not, and also return a
+   client config.
+2. The gRPC client connects to a gRPC Server.
+   1. If the name resolution has hinted that the endpoint is a load balancer,
+      the client's gRPC LB policy will attempt to open a stream to the load
+      balancer service. The server may respond in only one of the following
+      ways.
+      1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client
+         call will fail.
+      2. "I am a Load Balancer and here is the server list." (Goto Step 4.)
+      3. "Please contact Load Balancer X" (See Step 3.) The client will close
+         this connection and cancel the stream.
+      4. If the server fails to respond, the client will wait for some timeout
+         and then re-resolve the name (process to Step 1 above).
+   2. If the name resolution has not hinted that the endpoint is a load
+      balancer, the client connects directly to the service it wants to talk to.
+3. The gRPC client's gRPC LB policy opens a separate connection to the Load
+   Balancer. If this fails, it will go back to step 1 and try another address.
+   1. During channel initialization to the Load Balancer, the client will
+      attempt to open a stream to the Load Balancer service.
+   2. The Load Balancer will return a server list to the gRPC client. If the
+      server list is empty, the call will wait until a non-empty one is
+      received. Optional: The Load Balancer will also open channels to the gRPC
+      servers if load reporting is needed.
+4. The gRPC client will send RPCs to the gRPC servers contained in the server
+   list from the Load Balancer.
+5. Optional: The gRPC servers may periodically report load to the Load Balancer.
+
+## Client
+
+When establishing a gRPC _stream_ to the balancer, the client will send an initial
+request to the load balancer (via a regular gRPC message). The load balancer
+will respond with client config (including, for example, settings for flow
+control, RPC deadlines, etc.) or a redirect to another load balancer. If the
+balancer did not redirect the client, it will then send a list of servers to the
+client. The client will contain simple load balancing logic for choosing the
+next server when it needs to send a request.
+
+## Load Balancer
+
+The Load Balancer is responsible for providing the client with a list of servers
+and client RPC parameters. The balancer chooses when to update the list of
+servers and can decide whether to provide a complete list, a subset, or a
+specific list of “picked” servers in a particular order. The balancer can
+optionally provide an expiration interval after which the server list should no
+longer be trusted and should be updated by the balancer.
+
+The load balancer may open reporting streams to each server contained in the
+server list. These streams are primarily used for load reporting. For example,
+Weighted Round Robin requires that the servers report utilization to the load
+balancer in order to compute the next list of servers.
+
+## Server
+
+The gRPC Server is responsible for answering RPC requests and providing
+responses to the client. The server will also report load to the load balancer
+if a reporting stream was opened for this purpose.
-- 
GitLab


From 8fda5511cb8dea5cb7fcd163253893f3d89357a1 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 08:05:55 -0800
Subject: [PATCH 137/344] Finish docs.

---
 doc/load-balancing.md | 44 ++++--------------------
 doc/service_config.md | 78 +++++++------------------------------------
 2 files changed, 19 insertions(+), 103 deletions(-)

diff --git a/doc/load-balancing.md b/doc/load-balancing.md
index 03c9bd2cba..4ed938c990 100644
--- a/doc/load-balancing.md
+++ b/doc/load-balancing.md
@@ -11,7 +11,7 @@ instruct the client how to send load to multiple backend servers.
 Prior to any gRPC specifics, we explore some usual ways to approach load
 balancing.
 
-### Proxy Model
+## Proxy Model
 
 Using a proxy provides a solid trustable client that can report load to the load
 balancing system. Proxies typically require more resources to operate since they
@@ -21,7 +21,7 @@ latency to the RPCs.
 The proxy model was deemed inefficient when considering request heavy services
 like storage.
 
-### Balancing-aware Client
+## Balancing-aware Client
 
 This thicker client places more of the load balancing logic in the client. For
 example, the client could contain many load balancing policies (Round Robin,
@@ -41,7 +41,7 @@ It would also significantly complicate the client's code: the new design hides
 the load balancing complexity of multiple layers and presents it as a simple
 list of servers to the client.
 
-### External Load Balancing Service
+## External Load Balancing Service
 
 The client load balancing code is kept simple and portable, implementing
 well-known algorithms (e.g., Round Robin) for server selection.
@@ -56,7 +56,7 @@ servers to collect load and health information.
 
 # Requirements
 
-### Simple API and client
+## Simple API and client
 
 The gRPC client load balancing code must be simple and portable. The
 client should only contain simple algorithms (e.g., Round Robin) for
@@ -68,7 +68,7 @@ unavailability or health issues. The load balancer will make any necessary
 complex decisions and inform the client. The load balancer may communicate
 with the backend servers to collect load and health information.
 
-### Security
+## Security
 
 The load balancer may be separate from the actual server backends and a
 compromise of the load balancer should only lead to a compromise of the
@@ -90,13 +90,13 @@ However, there are only a small number of these (one of which is the
 are discouraged from trying to extend gRPC by adding more.  Instead, new
 load balancing policies should be implemented in external load balancers.
 
-## Load Balancing Policies
+## Workflow
 
 Load-balancing policies fit into the gRPC client workflow in between
 name resolution and the connection to the server.  Here's how it all
 works:
 
-![image](images/load_balancing_design.png)
+![image](images/load-balancing.svg)
 
 1. On startup, the gRPC client issues a [name resolution](naming.md) request
    for the server name.  The name will resolve to one or more IP addresses,
@@ -130,33 +130,3 @@ works:
    received.
 6. The gRPC client will send RPCs to the gRPC servers contained in
    the server list from the Load Balancer.
-
-## Client
-
-When establishing a gRPC _stream_ to the balancer, the client will send an initial
-request to the load balancer (via a regular gRPC message). The load balancer
-will respond with client config (including, for example, settings for flow
-control, RPC deadlines, etc.) or a redirect to another load balancer. If the
-balancer did not redirect the client, it will then send a list of servers to the
-client. The client will contain simple load balancing logic for choosing the
-next server when it needs to send a request.
-
-## Load Balancer
-
-The Load Balancer is responsible for providing the client with a list of servers
-and client RPC parameters. The balancer chooses when to update the list of
-servers and can decide whether to provide a complete list, a subset, or a
-specific list of “picked” servers in a particular order. The balancer can
-optionally provide an expiration interval after which the server list should no
-longer be trusted and should be updated by the balancer.
-
-The load balancer may open reporting streams to each server contained in the
-server list. These streams are primarily used for load reporting. For example,
-Weighted Round Robin requires that the servers report utilization to the load
-balancer in order to compute the next list of servers.
-
-## Server
-
-The gRPC Server is responsible for answering RPC requests and providing
-responses to the client. The server will also report load to the load balancer
-if a reporting stream was opened for this purpose.
diff --git a/doc/service_config.md b/doc/service_config.md
index 6093fc3445..7318b69f21 100644
--- a/doc/service_config.md
+++ b/doc/service_config.md
@@ -123,6 +123,9 @@ The service config is a JSON string of the following form:
 }
 ```
 
+Note that new per-method parameters may be added in the future as new
+functionality is introduced.
+
 # Architecture
 
 A service config is associated with a server name.  The [name
@@ -131,71 +134,14 @@ name, will return both the resolved addresses and the service config.
 
 TODO(roth): Design how the service config will be encoded in DNS.
 
+# APIs
 
+The service config is used in the following APIs:
 
-
-The gRPC load balancing implements the external load balancing server approach:
-an external load balancer provides simple clients with an up-to-date list of
-servers.
-
-![image](images/load_balancing_design.png)
-
-1. On startup, the gRPC client issues a name resolution request for the service.
-   The name will resolve to one or more IP addresses to gRPC servers, a hint on
-   whether the IP address(es) point to a load balancer or not, and also return a
-   client config.
-2. The gRPC client connects to a gRPC Server.
-   1. If the name resolution has hinted that the endpoint is a load balancer,
-      the client's gRPC LB policy will attempt to open a stream to the load
-      balancer service. The server may respond in only one of the following
-      ways.
-      1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client
-         call will fail.
-      2. "I am a Load Balancer and here is the server list." (Goto Step 4.)
-      3. "Please contact Load Balancer X" (See Step 3.) The client will close
-         this connection and cancel the stream.
-      4. If the server fails to respond, the client will wait for some timeout
-         and then re-resolve the name (process to Step 1 above).
-   2. If the name resolution has not hinted that the endpoint is a load
-      balancer, the client connects directly to the service it wants to talk to.
-3. The gRPC client's gRPC LB policy opens a separate connection to the Load
-   Balancer. If this fails, it will go back to step 1 and try another address.
-   1. During channel initialization to the Load Balancer, the client will
-      attempt to open a stream to the Load Balancer service.
-   2. The Load Balancer will return a server list to the gRPC client. If the
-      server list is empty, the call will wait until a non-empty one is
-      received. Optional: The Load Balancer will also open channels to the gRPC
-      servers if load reporting is needed.
-4. The gRPC client will send RPCs to the gRPC servers contained in the server
-   list from the Load Balancer.
-5. Optional: The gRPC servers may periodically report load to the Load Balancer.
-
-## Client
-
-When establishing a gRPC _stream_ to the balancer, the client will send an initial
-request to the load balancer (via a regular gRPC message). The load balancer
-will respond with client config (including, for example, settings for flow
-control, RPC deadlines, etc.) or a redirect to another load balancer. If the
-balancer did not redirect the client, it will then send a list of servers to the
-client. The client will contain simple load balancing logic for choosing the
-next server when it needs to send a request.
-
-## Load Balancer
-
-The Load Balancer is responsible for providing the client with a list of servers
-and client RPC parameters. The balancer chooses when to update the list of
-servers and can decide whether to provide a complete list, a subset, or a
-specific list of “picked” servers in a particular order. The balancer can
-optionally provide an expiration interval after which the server list should no
-longer be trusted and should be updated by the balancer.
-
-The load balancer may open reporting streams to each server contained in the
-server list. These streams are primarily used for load reporting. For example,
-Weighted Round Robin requires that the servers report utilization to the load
-balancer in order to compute the next list of servers.
-
-## Server
-
-The gRPC Server is responsible for answering RPC requests and providing
-responses to the client. The server will also report load to the load balancer
-if a reporting stream was opened for this purpose.
+- In the resolver API, used by resolver plugins to return the service
+  config to the gRPC client.
+- In the gRPC client API, where users can query the channel to obtain
+  the service config associated with the channel (for debugging
+  purposes).
+- In the gRPC client API, where users can set the service config
+  explicitly.  This is intended for use in unit tests.
-- 
GitLab


From b3f811c7397e06d5c80317bdbda900aed914cf4a Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 08:10:11 -0800
Subject: [PATCH 138/344] Add image in PNG format.

---
 doc/images/load-balancing.png | Bin 0 -> 27733 bytes
 doc/load-balancing.md         |   2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 doc/images/load-balancing.png

diff --git a/doc/images/load-balancing.png b/doc/images/load-balancing.png
new file mode 100644
index 0000000000000000000000000000000000000000..18b68bfdad83d15b33f37eeeb98f582feb8ee0c0
GIT binary patch
literal 27733
zcmeFZg;!M3_cwfJXb@>pDFFecrBjd)gOu))?q<kQKm?>zK<Q9==*}Sor4i`{=@?|_
zA)Y(>{e9Q_yzlc5ylXvox$tuCxhM8MXYYMJ`*Vp<S5+b<zD*1O0O`{w3NHWv2MGYs
zAwqnx#MI|j6#zKWKUH|7<vX?AO!kppH*n3+p;vFB{YH&rC{IdTVsx1mE1h_v6GR@L
z+X7NS@fiQq7YS7$*MqxOWt!22#z&~&5(;*8Sc}}#FSm`*`*^3qA_p$#`Bp?jk4Gtm
z=26o<%tz^GF^oz-H1}}}bmuoQDfOBS+OyIlvznt9r>SU3!CB*Am+_s3`Lm094P0<s
z|M&X868Qgx1YFrks0>pkTrK=5C6~4pEZi(E<|_PW{9#=c+`a$v&+x02TAkY<i_4_d
z?xE0|2mlyWl35*T9#><pVJjcqef&VQyrt9nrxrNnp_M+*Wk%C&XXR~Ki*Bmv<O#}T
zA|TW6$wAMEzgW4j5CK?8mf2%w;;F@nx<v?ui8%m&RwhswcD((zEBpj2HQB(k9D|#O
zgenj~-Q?i6yN#B=d;O<X?4wWAm9|g-?k*5FQQpZIO*jq#3vJn+@k}R9I3`1ZO!|B?
zd6|A})u9_A3c@xWQef%dtASxuUpx{t8=r0qB@7!RW8ciQERM9VbR@q{3Jg6;d|b^D
z=V6DnH1L>;hvgR(Ub+AvA!n+UQXI$(4h8`D*&Njz-&%uR%J{R&WnhbP-`|Sh$-4yr
zQ&Ib>M~a~{U>SJH(h3R|u3YeD-pBs-498LsfQ#Hgp$PwuP5rhO>6wCpwk-g!;ZI}7
zR=G!$l7?*$ygY?HvZt;w2-*?@@UgPH*?Tl#p{)LJ)srGyd;tC<Coh77HJuYXua5~<
z5j(kH?*{0QhA41gU_(5GBiR;ug5X5pKg#cylM3MgT5n+yha5Hh$wmh~p0%V-4iEc@
z0XC)UQC8qX<nLhRq@UM-p}T<*-|*PgzNvEX2R<eq6HlBdoA$mjdVi>+A?LG~YQ2}W
z2yC0x**Ms6%3Gw{c_>iilQ>FgdZtB?b^ih|lOk~sVuApfL@^4&F2n#*0e6pr1HZDS
zH!w&5O=k)9ZN$vi2BwoA;USuu{AX?aDGjMcn`*eyzK>zTv%8wwqGlhYdAGw9EpQ?b
z9&6c7PMqXOj~RCdum^(KdhB#%Nrvylod!e9vY~ZPz94*hui@dknhr=D)n_D^_czx*
zuu0>XT{~R;@iG75F7DnEa!oLG?_C=5I?;lv8!qG;*u;>ZMKb6=u8C1_4z3$<FtQQb
zh%&?Fdw)?O(X(qhsV?dMfthA9es6vHcr=B+PUF`iyzqK$4eB)0fkEPhjS_}4_bJC_
zL!UdY+!9HOyH|?NlZSKumq$AR=OP5~xyP+|)1a0BTz;VHI_!~;k|nIEVr2Let#=s_
zWCoQu`2YfG8fg~cb8n7Ye$1kOz0RrM-oh~YH{hV&Fz!%kxqEeS>rbIalFhi(SPQ95
z4Ql#M5*wgUO%TuV-*%~NDAQNlj8+s}bD(-5La-NPjaG>w%y1=v*W)I9_HFeW^f4m!
zs;p4o+UXiTEw4-B>N#35(G@PfgPPj;W|VF=JML}ZW-SERlP3n86y{9BuHLNTGYwF@
zKID8<IzUmE#iAFUEl6UpQ^5Ku<)Ya^M{A4<Ns@DZz8t+<`R%iZseug>p&4K{gAWX`
z6C!Yc9GM<6QIlj=+zZYj%2%t043X{HpQCagNo<ax<v-Ro4jO16Os2&rEFew1x6z-D
zZTcP>CW#+Uitoe#_*iLy+6})~=sUwCd;_|pre9Sf3mgmkD&Kf-?9#ITcomX}d^m}8
z7fc~X#y&ojUW~OKXf~N<fkS|QYPC+JCLCweSQba_yE6J@@O}OQhzxo(-;dF<ea<}Y
zL6SImJDTk2097k7&iw2bz-0F!$)qya?H#a%o;E@i0Jt8;m=V*Z>m(wg*suM{gfTko
z$>66@K!>@+QgvqFhrV@-<Zg#ojg_2-ZkqtRZHA*dFbyjqb99I|bY_I!1jvy9a2^Mh
zJ>`$D`RT9bF_j*foPlo_ZfM<m7q^U0K%1UxtJ(Nw^a=x?i<zOf@;?6H0O5|X>Jz4@
zuKl<zBD0i`6JMc+YWmq%@aef3BI1P$qZokvq!|<qb~U~IJUkIluavs}@$IxE1i~GQ
z=x1%RrG$#@ciL^^qS9@P?GNmZVXP-;`V4Otk61}nuFh(tVN1MS+}$3vhHzY+*{M~i
z2_5-WG~q(?+@Ipb3T&(*3*gB5$BB9>YV|hGuH$AAJ?h;^Tfv<@lbAM$*LP0vmv(@5
zv#D*ebC?~AY3A=Ma4PV5b(>F5Zgkq$d>XT;omuLG@sZF^f0#RZoGmCV?7geMYIS5j
zt*N+e>?{rT@VASoN$N29ZEjKThbp)Lzm+;2SPp8AM`7_B@%$l)>ixkZ1+CWa)S!`d
z#sL<>sR7OqxsZgx!gIY9fGN7mUE|Ls^uNy<h_#h;7TL62bWDo&gY!nX0pQ&<02B_~
z0Tl__Z*WQdy}-%+yTPitumh{+e^0R;fLD*43|RDkt`0WW!3f%le+vv*M+yKZ%y{7M
z*hP=kG<b_0>-sHxJM8_xMU1@x7sI~`oS-_xW6)!P7j}uue8JwS-#Ej*fGzlY{XeUN
zPZ^GeK)ryQ3%t6V002q$*M}^N0Dr{-4%dwikR9Zo=yEE3vaNA#D-Mw<2~HE+Ozvx%
zU8UO{5_WIF*RhkA?T%OCH3=9&FU2-3hus|08Sz@h$BX@W2sV!0IIwqBn!xka^KE}o
zOFcuC@mttduq&BgTjmR)*)_<_t?$*{-_!E=ESg8g&o=C_BLho|pr4HV-_5|zSRR{#
zedF@K0d|Rg26^|Z@I|8h_Ox$~ecWh>c*0<7XKLg*Y4wM|<kI~bolOJpy2IZV<bm4!
zjHi8$rypX?^)z$0-aLXiV6r<0)aEao|JE~@7(W`C#g64B^d{t8W(PTv(5#pimtV2$
z|5bPmI}hxj-T__wxctzY^4NLz+`-<k!XM!B-@*O>z?}~M_xI_)Dxkprw+gaeHy;6(
zgl5>e;Q##rtmEB#9mWi&z>a|&sV9u<Dl-c%1IRmU8KK1AF8v;1*Vw<dC_MiTmKj`Z
znc2`24oR1HWI;|r=fN$NnY#j4Wox<5B7`M(<2EV<7`Co1!byHE|D0!}MOIQ7z5%+(
zkqnj^7F%FIrpJVBFSa5)iwle-h!+xC-QD~u^~Pi>cLgYIwJDL_GcfPPca_ToN&TE*
z>-1;qQ9mugmTn*gDW~bGOU>y2zOR&h>}!!iIsJa(NB%i1meA}SiykPdg&!nllVj1k
zUSEOBg`UZRvV$E<R1<g0QP0N4S}#F*ERgO8X%Z`!k6@4o1+oys&vVDuE1>b8D!@SD
z5b8TMdBxsx(r(u_v`|R0AagP!TyNg3YaHa<(06s#MM}6(K!cQz;PIJO#I|rGC|&+4
z{|3zbJ8Ki&Kj{Gg!mO+hdXj}PiK8P<<A7iNo^KYqJlX7BZW|wroWIC@zBCwg(sSa{
za#$f4nwB_%Q48FQ^fWZ+#?8Czp(}D)N2`lf9ASP4C*^HDJV$PyNXqlsMF6}8T}K7W
zKOeSUggJz4UCn8FjMR*{8w6dUjA)H^Q&LKwN)Oi<)$jyDiUS-k`XzVcyG`hWcSdw$
z{nbjn=!rLUB&}Ns0tu#a_v<ozZB@?#X{vjvSN|@hy<hxX<*X5i|Ev>0c7p)t0}Yb$
zWt5Ab2|u;OT{v6SL3&eH?W`DUP@Ce~m(s&=Q&kkA4xN2c@qFN^hx5hCUB<)o8s-s<
zs1bU`?OV;=!j-i2%hbvx!xEWb&%lUg9YV7mwce9<uM^9_jmrwmucLFzkq&4xA791P
z!ueWy0%K9k<gq~O?h%R7^kyz>E!uhd_{drsNj#{NVnq_WA$EZtKf=(CwbXLi$Z*WI
z#5~&BjPj-`p={aBWo*5q5d@bmxLdfj0-Q}Pri<JMu}TKb1@7J#yfS4LUQin}$bFH`
zYK1bsq2H75j0O;Va4S^v@y}r^6@{nypBF}KYM6*Dn>o}<6XWZIVsjHmYN}HCgrWvi
z7)KmwY$N1XE;rHRGk$GiY6UwZO~0n{7%H2JR)<F&V3khB49i}8LC%~H5rs8GstA|0
z;PoxhFYN}H2QJ<^fT5wi%%%7bI>hnu#nJPT@%?)?({j^E@Udgt9qVpB4TRICloK6x
zla7r*eN8OFa|~{`3t@NbV{jW*MS7EN8nVL=4WN8Ip>j4!@v;dg{i`I;4-^M9H%ZKh
z<V^1|O?U^MwMY$2@|&3A_IS{*{ATRk;*1yl48|>)lx;y1)rcI+K4&$|hosS_&Xzkz
zcvZN$1G>|~eD2<cWB3x?aX{k9*q_NYYs#`3>FU<R_;B&YK!@j&4?z)+v1Q;BVHdb$
zcYCMm-I@}6vcSLA1IRr8*g%-bCs3I+q^MZ-+v(#%<@sD3FhFeV#L<|loYm7p`0;xJ
zt)O9>ey+MHPfEWRPa%}&562>}Mq!zC#Aw|21T(T7O%rn`wRTOY_MCfj;vH>_jmL*W
zgN$AWI*Er7c4?L-6x>9HI~`3w#vZQj2*($xuWpwo6HHD`ggT7nyaPpKDQ%4VT)dUo
zfA`pt0&64k4g@{%fOQH;DrwjNFDojSSXY0pM7h_n#Gwe+RcoPHn5$4ZEeWT1d_UD1
zouKkjq(P0yHbRZa9;3`?K=YY6O>OKK@2UnEVPEYPBqI}QC)?Ai`KT^xRO9uhQ(V)Y
zEEZiSG1JZpq{ND4TD6r5sXrZsHFjVut_c+bSDSH{LY%wJO4vb|8y8*~ZegTWwdL)*
z=(wH_+u=6P<Hkr3*H!Yql)0|3Ps>A^b<)c($2(pR`R!lcATnb}s>vfD*@td1hsfBJ
zOC4z7)DO{6A-^(uvck)GOQ6ODEpPvIM!1kjY$ii(V4@Oyi-c-G=icSA&04h<@Z79d
zlP)<&*StTd9AS-D7Gs>%tC1U*pzVFVIy|(vkk7#wW>b0E5u{hqLI$(<IxqZ5Ps}jx
zp4gfqN>+Aclkk<bRQ6Mb(sq=^l_2b$6YQUpVTJcP$ONrPF3Z5S441Dik7{FE^2RZ!
z)>fhJ6IwE<IK~gnW96HNrU-*k1k{%d^edU&xMg!6hN1<sS_?gk)r}&=TA>vy-_J(2
zlpg~rpFTc02+O6(B<|Or=@WXA{Nj7AUPZPp<vZ`b%ZL5b_G>j(7g0;<jVZEPD|W4M
zNqmkM1@Vp#=cORU&-&w2<erkTRIHh4-kH2~#Q6CxWJp5mFt}wgY%h<cn}jZrwDUn-
z`>3gd#D#qqOl@hb%vr){J?1ppMTUMJlVuv=65OHk2jSDq9du~u96cVm(Uu!?=rKPV
zw|kY)>+-a={A4$&8+CG$^7Hs&Wh}OdOPYO0vy^FSUv_%>T=Z(472LCXA5%hK9yJ~K
z4O=B8tlpdtaN;Sv&n41&b~dhwO9B85@_-Fm+36NlCb32$@&myOsES43YPM4tAVQW;
zBuiw%6~xBp`CV{kTMEg(er{P+@TN+Q$b{<X^5F_z&GDhEtdp4saS=nGWC;O|ci)-O
zni-lH!?-O4;jTQC|5oKGB~juxtpxaF0Aqioe7X)!vS|nCZPujnZoCPeMd-#-eWFa)
zc+_&zYwB@v>-E7Usf+S)meY}OFf0HY*w~mD_}8&eOn-N~JVRaDpSKs;YbI@!)|i*B
z83{@Tou@F-*UB_s{n<e=anMf>2dV9tWTaOfMSvTR6`n$i%-BGw#i9&*lUT6<f&^4A
ztLa8bO6|Ky39F>|xEG365z-gJYPnMJ24kGGTUW*TBi;usM`<)&elmt>`t?=GYPu#W
zM9yJ2(?@jTwb^p|Q!#QWmA&^<4aJ-He?6NiB&}E+pse4=<@%)uH3;^)oE&m()}eb6
zw?$tyyDh%ywLXJD9DYW*4W@_0$UEii6d`_DXE{+<E2iM?z3voYuPJ<a;bvt)N10-1
z1)-N<gbA^!9@g{iDg)u6nSmlF-)EPly8KXGx=k;Cu{z8d!CoCsN~8Rp79TjDg?RnJ
zqwRmPv&h%#F=K<m%v}7b9}HCGEJov&UG|X7#2k&(R61#~K#azMG?T$y2?iP9ItByY
z*fs%Tvuh3^KusG)O^VENQpz;euiLxq6~tEwuS_8qH>Y#HYu+%WCD9Ds;T095)Vtw9
zH0=kSP$+w7xVM=UvwQVkoc3!XEekga(FD3(b2)LYpvv|kxtdC-Ui<XrAhAPrv~o8i
zWv!oScZrjOIAXarc21O{RD|~xP!oh+raVsZKK_Oiee_L-Xko`C!18>T&gGr1iI4I5
zr0L~~5UtO8b*akyv2@zL`)(a(*Rx)2#!cxw$ES()vd7rxYp#)AGsmlwMMLL^tCJSY
zYs^m!-3^{+Nh5zS=_4$V;+g5g)`RDN0@15qF?M(P^e{i&rrjR;c90fajBT0F8kxYF
zGJ;mPmfN;U)l{6~`*-?@%@|sb;-wkWq6Rd(F_$SWjN^&+(|p&i;l@77`Za|;Z-Sw*
z9u2Om?H;490)RQ{NQL-z<L<GV8VlZLky>s?FI5gabkKToHaC>L9G@8_VBVt$)q6eO
z)a-|#H*F4DF1`MnG4Du&FIXqtbiRYGhtF9A*YC#y*H4l7W4)|NffZ?+=4E?9lJP`4
zakOg@!v)GXYgzLy95GK{@}za+rKyzqFIq!pI9ot9f+QWCdeRWZ7c(f0**-~}tXzIR
zAjwDL-$LHJRamry9u&7ZIJvujSJl*gSn<!OpiS=9dUeg$ohR$37{A{~)5~@?X$j8q
zm?8J6m^nU5WFW0koU@_#GF#G@>7fS7WyLji=7Pg{*Tc~b2~lG|JHJ#vmxUfK%`BJR
z%kkPKwxGq+>g+g!$CzJN9_hzT2bI?DaGAqM-7jl=BM<qKO`Z>*j^dGYIk95mWV>^$
zXibB}|06*=JlE#7Mi>7X39E8xQu<060QCuIai1g6e3Uz*-<)`?B_{xeb^CX31da$$
zrcp)&Jtzh>%A(t{P(4npnZ6EtGGR~088EsoafrLOU;W%ZVemsM<&FSD<(xmtW=^EU
z$@7x3$>6bt@lIiYb+1QyJNY{2amvqwZ$F65U~(!G$$6SAzZ5KVfZn^G*k<~oINKav
zzev|<=5WbZD96o&J!T`Xo+&D+v#9E+OdNNJ7?BA;r+9#&TDlfh@qWXzd(TqOSVYu-
z=dKt=Jy`x>%VqMK?vifrshp09Wpmz9*#(GgNr+HQ?;A`Xp|*=gNr&C^48IG~pFR8y
z!$wV>WT0^_j>6q5$Hzy^z6_ovf;gJj7d<>(bwd@s@OT2OeU?i~=-6`U0C#e7fqEh=
z#dI%QKWDL%eIl|@UNqTqS~+Eu3c0^N(0Y-)ARm&%9q^~FrrzoY>2hLxl334gTD4ce
zZgtQ|O^cX5gj+2KH(h2YZrdk`mz3BnqH|jW6!1v}Gm<j4<$KdwvcaqFKrY=FL)F(B
zOX}JDYCtbKg;Y_;xBOu*iOmt7Yku1A#cFi?!Y}tJYj5!gtw520wKP&9voO`IYTQ5(
zdc!rlZmvHimU~I@c?R>{FY~nIz*&BbdU2zzy^IJHdRZb{jc|GJ_6xGTc@B}(30Vs!
zR4C|U@|bQoCVZ5K>amQun^%{}<+9;dZegH$+Mfb7=Srnof_M=yIEN;@M+&+BqE-%=
zKJx6FEJ*zr%Z+l@@b%3{j!_euwa%w@;>@_3N~P~afoFpok@RQEbJN8@BAf&qB3t;r
zUB4h0O=b76zrcOo&fi!Z>hV45HYIYtX)S%mLWgpf-QYsqMi4=V*PaBL&M+xa&KLcH
zh;VXy4_L!<9o(V}@KE^oycv#9J3>d^q5T7LN#K$x&C?jrh*w7R)zO@T%Hhx*zEZC3
zT#V{>x{E8}kjR?Sk2qAxnoRB$)e7xVem!&C_a@ToX&o1;J{_nLsXOc9>VlOA7QulM
zzrTCi<QFXm7d+=Raqqr57!_Sj(IR2fd$pxIqeZK!9B_F|wUvB^6<%3lKUKt8pMsNZ
z{dUkMky%<^@o?lg<-8wa$*|=PZ#))=!A9pLhIms<zpgYDarYupUwQwsgA@;~-BTBy
z#I<8pEbH^%B54PE*?-Aq!X|=F)M(>gnY^K`KK3vwQ6r{=uPO?+jM#c3n5K<bJFG-h
zQHu!A^%wl+t}x{M7;ChB!O8Zulm_UA35#;V<xO6qfs}E*Y;{;$)^Zv7wl!`U3?4Ow
z#B~*+pCtQ{NT8>U$dT3H43>%ZgRhY4e)nGY<yM*^dz4hGw}TMrd!vAL(Bw#CR=6-3
zVznnN^5RXgZCb{5(*xsN+W~V!cFE&XWi-CSrEx!`81^20ly@3Q=GfShlKY65baOnR
zSf<3zEOXWk!X2NdZXy$`ZJ`A#)u7VOWHYMl6=j86l?IO&d2l^Sac#aJ6{T^O&zh!0
zN-zfVnq!o|HGdp;82z%f0&q1Mp7ytl>t8uYw&;~+0wvE{@2i-m76UpE&ahdLWE`v>
zU`3PkW<=%@_FUHz4nv=rtr9K7x$3N}=eN<DX<PC3Ktxauw&K0QHFi;;dN5KcTgB*s
znyeMZX;X)y_e2ZQ*Nm}K{U8w037$Y@f=*sdGR*sE#hH4KG@)N-2dtDDr3SSW2V3uY
zJKZv!*_2{xK;iv4SWETlYPm6g&?MNo+pTNLIPco;5yH~21g+a@(n`yRI^mVxT{rQ+
zVz5(OYvLS&b+ft^*ad5;Om$jeeX`+cn}L#ejl_)|HRgUlwQg<d%k3zu2(z@1T&tfV
zcT>Frh{un(w8yEC$>~qG@?Ddfy6m|kmK?urJ;p7YQrx<4)b#n;C<8fi2m;yGwH7fi
zl$yYH1A?J)u>PE)`w4g7A;c23#l}R6vnwu>Idtl46ty#*3hzpGSr^JWh?~Y)7s+n<
zR!hU2FQm+1F*||iIS}C<%cVTOl!u@Nw%Xt*HeEV94D+xu1&A)<y6O@xa4;rQwJv0P
zyck^9B3!_puAMmMb!K210U#DLGAL8$?yWx4Q{&uJXbw4FsL<c=zaYs-B6fhiT7isV
zMg}fL?dZOHIQI5-6dyl48t4Tft%YIxA<C%z^B$a{`#}{@y>FS3O-Vh7QGuS3Q3ofb
z(iG_%M0yP2omI;1y3-}11Z6H;N^=Rst`RCu@=%>M8;f7cYXz27EG81I+YcNJ`GWfo
zbGmcXw;jLx<~vnP*X(RP3Yl|R4IoF3(jqTsngmh^#ue<qtbxb=v(Bet&rhBT+51nz
z;7m=6Z!{hi79=^A7<0W$;D9>?S%lF#V9r`U!{A;<l*tCV(*mzHqij~@>~A?4lHpRP
zJEBQ3u=?me97j}vv{(9(?4z{|>Blt9&zP>Mx$l}{Avb8<$0N~sKYdQ2m7Ubc3#9?f
z?X&HnahJEH4d*kSw<1Q1>k@36K^W-|7Buq0D;v=4?Hys*Uk`HcU)k8#FE0wmv1dZW
z0=veLV*W+{x#KB8cWa*C6OoGMqXM|D;-I}#BQl36upRxT=qEPW>CJ`q5StMhILUk9
z7HwAc)1<C>CD!V_Rx{Bs6|--hQqxhkZ{6>*mv%CJEiSq9A|B9rQrn)w=Et_nlPc~o
zm3zc7%&F=B@;Jxx&$MxO;rJxfz+Q==w6khp<oMjWmbTjL@62Rjx3;Yy+>0FMH!0&O
z12Zo65(>f(nvYGAS3BQy=16@t9BaL2tU5O(bLzvVQkzFVJ>*SCgA^b#<v}MK@`=gM
zB(M9=?$D0WAkT`%LrOCeFn45`$0zw+VWFcBt&X9r@M$hM&5Pn8Gng=sjZQ*Z!f~Ox
zY3E(&O#@bV0_Jw|<0t8(_iRjNq#!e#f5x5(LbgdZD?WFYH}!o;!_b0|=ul3`s|u0@
zhtgEWdGF<Sf^%0#v?VIdMU=rkA*1f>Iv478L`E3pV48tqua6mYR#LT86i5LlO;{s)
zOQ0LqpQ0<a8qn-2G)UD~%=_CrYdU?2vx8+*Ae*`12+AsAb48Qgx=y}1P|;PY!1Hr^
z$&9+?m|<5lm@|!i@!q@?A1~C`on5VVN+;bm%qUzghXOqEtHU6UCK@zvdi><sf)cJ8
zP_?EKXD$2IY|aT8TT$}O9H_EpjtBP8EE?#^VQGGZ9oLJMD8sO)DP^NqiePT%#g^XT
zrBzbu2i_b@gszvtoGGI6%BMsgI4%QfpemdvUs6qJs^k<{;91pBy|6T)i<p`fTFduJ
z0x7LgfOFd9uV?YS;R8Bde*+&{)@Dw)w(PTRvGej4H<Zj_8<#tYG7pn)5GM=GZSF^f
zD{~+Y`MS6I8F>D#cCz}0Aaa($!hBZqxBQ-R=2s?U(p;vl-5PM<z;#6tfvDQG9U5d1
zV-bjfNW<7FM_5LwJPso@R1)q7>#mLUoqD!Y?-r*zz~&5jg0SLP$+3wt(_hRhej@y*
zaFC5RuyXM34K_k_XoY*YAsd`0bxNv?*)0XcW~h)sa}_Zv^RaSB6~f-<sY&5Rt0)jt
z!GasJcj4u`6*ov0f*QcI3e@*S_I<7wY)^7tpTbmZ3*9}_zYCW-a^aS_$5p4UFot(J
ziBLDB1J@&F&>8+Zx6jge4!&la{1^DvA^r=fFO2!YdDd#?nvkmy9cR}@DI{fOJc&jL
z?c8=ah^%RRsxhI}{wjj<_HOk3AA}r4zd>}|$PMCHkI;uWSa4ELamN?jkH4$TLomS?
znLslPMnqFJiSd~w9PkTuTbTQW)&A-!7?=$8xC{^n)0{*?6LSCIlh?qQbon1J0zjmg
zHB}KY4<wHforp*UyG^FniV99SE@eHMj|uV)r}dQ4iIPQo<|NV1TEM*f#c6@M@Q1R?
zsk~Cvwae<ki?ZJ=5XY>cnqb4n2?*^`gYH7~;o$QthoFUfHtA+XP=vbee^UcFgg3B;
z>oru5J)UkK*@NMt;QpYiJ;JaN9PzxL!m+pDc2)Zauad+Nu6W0#Y6^(aOUen#QbmvR
z)fFb2q*D-8`szVEZ9~~9;E(XQ78bY_7!kAz0kJniGui(jt*&8sWlbp}2#q5_n8gZ@
zwpe9o{s7xYc`j73RLxYPTtf9bq6$9~O`arSCnfVq7*v<}hXF6wyFmY?Eb%t0-}O4X
z`ysv7Us;TE&lg;ruakHo_!h6)5-R^II&4xz9ft3(4?Hh^ws2p`n`P_S6VNizeB`7o
z(B>!dt5(za!~Ne$V^b#lH}l~@;*Z{<p@r=Ondnb)Z>vk1z6B9hH1+J4=;)spN>j63
z4h8bvyC`S*r*JHy2XYo5Gw}N;ZI+_~GLzwh24ba}Y)#6Jo~vl1#li}Im95XAP42-(
z3*WFH$p2(u09n>|2Ms{teO+BxC6&G|R71Q`LO1NiI9Gu7*F77Wfx`Cxy%RIe;3r&c
z@N#=PY&Hm+e$k61{Lgy-o5uN1>gDkD|3sW%ckBO62mMd3=WoWQK@mV@HA4O;A@nHx
zZ*#RI3%4TDzWkrcTRLO@zp1EcyuF#u>my)_ioN@NXD)Vbu3iMQ<1+`@T770V23IM;
z_ZfY+oT?O&p0ju0hSRjP#@_mz-u!){#<V<}4i^;SSOdU#4V#y8HPqi3pzC0_EULE}
zrY(PVAdHZa^8wRX*zAeP(MyE)+U%Cd#|a-Q41r78>2haK{Dcjq<Ysd)cllNF#G0*W
zCtqN>Qw>`ojUzEpn`Q(<to>;*0p)bcL`i4O@Hp{g>V!eVZIJ7sw;rVa7m+UP0ui6b
z)v0wu0H(Hi%c6y<V{%34WR85)eGAB}?(-l^y?q$xocn`#7&XcQ(q+ut`y%btZ1bw+
z0lt<ESb<nunRjxDAg=3R)Le1hXtkNie9o?@vxoKP4AwUg3C`ESCU=4khwMfAwZET>
zyc-7qKguvh9;ZJdKf>F;TZMX;mC7ERF%Q(*%#FCD5?@{z4@g|r9Pxk0wM`)$*s3-C
z@)>04Xg(2gbQ$sf5rTb1hwRH$s|1U;wif#LS;mg%7GD9HTyf5#NgddsX}e0^@X4dX
ze8%u(Jk`Ye{D=wwDHyYkTJJ2bgX|p|Gvilq>6@cXwHPRlBPJTtoa%KYUO1`<zy~51
zm|#~KvV<A0_JhcVz;q(Q%0uA~5s;7XbN7f(Lo7p=ac)u^I_}<icq*f4jzR?_(`H(-
zOblLV2VGqcbtSLvy$wnTl$y8b-N;rz_OnJlX2Uk%dnN3>ccYb#;^|`lNYl<q#zixx
zC>tIkBq-ah;Ci$uDd#H{l{4k3F;edca(H6Xd3nFy0y0DIT{+#oEo0o%F?>S4hUYxV
z0Quv<GI<q^LE9FukM{K)Dcy91R)J9d#LCJHYp4U+HuYK4>t1YfI@9OV7XGW%EaOGe
z>&LLy!tU9JOgZQDi)nM-YXtZUA<j%9Jd_#_fSsK9cGYI?P^SKKYX~4q$GnCQ^dO<4
z3!}(mS5NDhU8&>xhzURK^a~3;7|tHv@Pt$c2kZW8NYB3E&~v#unZmFL%}i<_Q(mSa
zoH9jG6F^e4zVbto2B4c11Lv;fH7-uGnVei(rzxjt9&qpja&_qZ+%~{e6p&q;_&725
z7PbbMZQ8Axr^;NNq}y_L`(%4O{y=aIP7ZRM7|koG+I(L_G9#sK3-A8H148$-Mrap(
zK?a!nZz3JB11zm;s&D@W+2s@)+@{fq@-``)+?ggSdrHfx_mmR?<T7e2N~cde!`6eh
zzYCwu^m4!hkJCC_a&Mr*0O8_~ih=0L#JxiZ@R30K5kod8_iqPmH8Qu0>ZJ5Qj*eI%
z%-#YY0oHuVn3L<iY<?S%#nbDI6$X^wv#H8XQ7e%cG+lVF0!1S2CAN<CY;xHU^7iPT
zw4<xM<3dVBCy^k5;8oa`ZF1b#Yv(}bQxUPno080vF>SUSk!I4HY2mp%pZj%5;N&Ip
z!3y8(K^j~(le2Wa)_RN_t&fDcve+Gfy8P~Kl(^IJoyyk!wVZm1*m|`2oGK7nwt2fR
z+WtCJdV55^B}7OXkoC!OMbc<EZGJKSJh&wBm%Z0qyUngfIAV<@@=dGsZkkV+i!%BN
zlv`1Z(EVeYA*n}H(1d>(63XJg@o?^hV#_moHNN`Nyh)z#aLVLIX+|Jc+yU9YwPbxP
z!m^4b+)MZKMdRk$?%W2L!My?iv)|5a&wt5Q=B|sK<qT-OD(Myw^>rQ(=mxOL1PKe*
zb2#&+n_n$;+1jrWqB^CJ(La+WAU;yW5hndB(En7j7vL+GpF_IZ5yccJL-lN(hnQV}
z=Ja0t|MW6SjpWElPV#Vm8dKm1ozPokyrItUKSQ9g($FFa;U%%6LH?)Hzw`$=FdhL}
z9vxDkg;j4W<I#Z0eTV#OZ)l`A+Fp|$AqUi^9`5=kJa2yeoD^V|dU{4_cx&{hX5^>U
z#6zbWrp#ai2Le4ivzw%=BH9a|FgfmhI5Wz0F6b%W=R(yZPav{hVP&}nlDk2*WDWC)
zc6i<S1Sv{V{_jh#gRlA})H?%Kb3ayuo=y{#<Qe;;V(sT{f&vxoxpr*WJmDY6UCt)n
zOU7Q4Qc4KczZ02Q|4M6HVNWXg3oG|Kdy|`V_xN(20_5$a0{uJP!GT{Ed|rBJp-(us
zVb@J5u!H05ZGM#8zGgjim%%DmR6X~-Fd*m4a*x1Q*FrMqoP1q6f<bjVU-G(QI=`AY
z_67QpSy@{Kl?PwR-LJ#R)9=wy(M8xZE}V+@UQ@ITJI<9XZ;C3#D$b80k{<$SnG%xK
z?})a`Y8A<Yg#f_tc<$}xyF=kR=U^=a=TLw4(o3mKa7s4AE-!0dv_@_*5OPb7IL)iM
zX_Oa#2*A=8hY+?4l@B;=Vo)ri<kQQOW+7WTPK*oI>RGq7y|h<!+z-JSPR@I_TC|#=
zjupylhEbOpt3l62d`oGd(w(~4ZfBpEYN3g3;nmfl-L>rYQjVobxO*(3w$ZcmLA+Mr
zuIR3?EzV3>#nEBz*x0QMs^yU%VJiT}9v%DGC=6qVzAl$o2YHV#R|rV7hIWhn#`lk!
z$#jx{`clJ!d>TEpTIT$C?ZAe@gZMDnQwNXrYY66g4Z(O2$o#2{?lj-V*R~3ra+!;2
zj$nwipNn|B#<J@TahzXaM>WoT18xA!Mg(8g)n}Q&H~e1ftKR)Q?kfKyR=2x$!XL3A
zb#w<lXcpnGPTm*}+PJ@4V;z>**!I5jrz~D<>*oz|zo!5R%<K1k)S3W+Ea8X{*bX2(
zCQ+`1_gDZ&oW@%mq^A65GkVf-4pfU5t~3;`e`xooBc0xjZSZF_1AtI0uLy4GN1GY~
zo`~H-#3nzeUX%A&&uX&=eH63u2>4i5G}~yB)tMZ(xj(>#ytrQW^E?&6{0=)Lc*&!=
zmJ#PNL1how_Q+1v28SgxtpRb6?D}`J5AomrzWuH%S1kL4>ZH$ONz~iIH;x@5OL&}5
zZn6l*Fmg4oGeGL;K5Oipxr=ONDEljbIGFJde(PCAsyz_u%15+FGY7NOOJ{x!0iN~!
zwB>F(l(h&HdipF_fo5F_e^$7X1Oj@2-3QF6s_{OjO_EE7Nf)=@L<<_zQfS_T0w2@s
zRr|iDh^DRHl=;5Mt|PXWrYH!=#u6<a%-tzRU(QR!m@g}j<5>~_aC`o6b}S9*PUycZ
zJcx7+iB+<;uY;y~mg_%-nR4ng#E==)k7P~Vq~1xx^q|e>rEbTPB)}jVqSfrvh|w^S
z_qYR}_DwqtnN^`stN=0_L;piH`be+h=J}n@ll$vaa-@^Bu~y1+gPmGYmTr2WL5c8h
z%nQgy=rcxx)%Xjw1MqQOIrLH|G{)a_v$mrknUeo)h&(Lq;RY#h&Ex7lE!)(~w;<RY
zmHTvRrKC-h;#)b8c_#Na_65cEUE&z0m|x31DC-(dmlsIl^?XJC_k;n!DFvj<(;|4X
zv7|BPzsE!H22|^Ro`c+FNgNHH7v?vxF%d<(F*6)xAo$+kbBx`oQjknge<2T+407*f
z2_3!q0&(FR;_Ar*qrw}_ppxOlgo`EQNZP&zmTCcpk>{v7zKg%d*tqajboKq1njw0g
zJeh1_&&J_%BqqE3wUdJ#C2+4E?3xvf*s+Eqy)t?ZF!K*3sB;RTceY@tPZ#wcN5|yf
z_IL%Abs;v#o=8Bc4?X(GRWAwhL?2XNgVq`9t>Ty4qdOw{K|`1sDp$9LyC?Y&-QgQ_
zHNCvnx|i&kHmS?^&eZFQ>Q6Es6J700W9#1XNup@Ly_PDMw)G>v3?HSYg9}q}%M_Or
zWbj+Q#?>*;TRc|{$Jek(@4~f@tgv4fWsFgT{fdAOQ(y#x>-ec-G7j+UUa0>wVE*bP
zqifCB*Dl~le64G|b^r39iOpyf--EWr+_U~TXv0PG)i$5cGE#DRZJ_R+vCix9#K1!w
zwXZ1SfYaxiZQO2%!zv~$Aa+vhDpQCdCm>wlee9vPe1QkAAYM$TMD8!7dyQ39$yHvp
zC=^Y#6^f+f_v^T|_;i#U1oD)Qqi&tq1?<9TbC-0lrrmvlPqvQIutzU5dSa@y$AVaL
zV<wNBuLQKtI;8avtsSQMca8txi87cC?$R|nE<89a?3am53S4(6;FvH~HUByFrai^!
z>}#C5NO?5&z$6RElS-fH%Ypld4s>QWv_6hr!`=IHqSAU4T{UZRI@TSM(HoUA`({kP
zX=&N+q!I+0np*&oSN8^8z5PX7ok_uye`Yvy=Pk&!<;mYIvGMsWpp7$Qk@LNKyXdhD
zDa42hiGw<E-1DI6sBrp@Q*5DQaGB~c7|U1h9<(Vw*1!yANtdMlyah+IuCnOGSxD3T
zx*$i!f^k9M!OiG?e}tUA2e_DQv&hF>dIp;Z)3?1KO-u2!c7{#oCDm<%+6&K2%r1g=
z5XbK#ty(3j_5(nI*XFQB?!Cm%kv3Ri`H{@ReH1N0m!I_%7`WNQ=pCqF;ftpN1$Zdi
zgIAj`!!V5vNnjEJM$;a!_?7RWWe+Qt0f_lj@enNyc`C*0J}^i(H6_Q?w+p5RV~LWP
z-OgP~GqJ0GI`M5O;dgrar&md}Y89y8;J|;7ECwG2>GmD)`#r4%lU#;rO5YuKO;*sG
z0i_M6C7ut>s9KXNo@5Phe*AiTX5wwrkP2?0KwCPI>Ud(KNz5wGSkT>yYGWr;#cC{7
zrumheq*^^w-$g_}IQq?sDN<E*6X+hI_cL&o#+8TJ(Ty4aZ7N!fY$sbZP$(^L{L0A0
zyfrRCs&Ta~p=@mbtSHWAg?LL4&BDb!g<JVquE5Ej4P274K9y~akZVf56+p6i)|My$
zP_d<8wo+hWv5zgk-EWiwKz0<$DZLqu4i<KXH76?Rj?mhvE;v4^3R8CAyvvg_WRtR{
zyJep;=`~mL$A6<jB=CK%jzFvcRzQs|P2JhawAd(2qBE)G;H&U4m=z^k9Y~|g@ZYTu
zV;s)EktLjC_>XS+>Di~BUsDg1zz9-6K@<E;Wbh$oyF~%F+dAXySKcM;aC7uZil3i+
z?XATMNih9C_#u<doN-|@Tk0%i`13ah0C@aV0TpBlgl});Wn6aWrTcB79`47-o*z!n
z9o5K3-QYQE34MU2KH&h=Ib{XaLO9Ty679LR#jlH6WSZIl{uqUc0pHcnHt7fscxB?-
z#pRJ)m46gDI8;me=PIw2Gl+S5?qVuAhZ}Rsp(4PL<=u8KH;^^~e(o~Y86(UUkals5
z9*}ggR3H?>dhG93R$3`?k7V8uP;TXbUSjBhP{z@NW9dy785QV|@ij8CK^WL0KBb|s
zkP!9uGIriw#h+B>FyrjsP_Y?7XB(3gie(_20mzbv897IE5!<{|pazxGp_K{Q+O_4r
zn=BsEn1QF^<b3!rIlD0qsS>)rs<6GQe98E1TkG)`XCg#W(^X2u!bK81fAlPmj=c3s
z%>sSy56&Jdig!$|C@W+%@aBbd+|=(gOPT)R(e+2mLE}CYNE-8(FJD@-sMFr9k)o*G
z`q0WH-@9=E7t<C)XRse3Ud}4Hj~VVJN~ccL{63s|IT`jND37D`sx0P2I_(d4k{sZ0
zITJTqZT<V5ctA=yLHbFhr{q~wrXtv_P|t_mZj`MBiQRQv{*U;$8poBB7}8Y??|sU~
zo^BO|{9I-UM)I^qxh*!iD!x-k<BB;9oA-yE0C89#vZ?OJmUPyk)*k0+fX>3j<PS{n
zEy@;?w+CkHbNr)FG0snwC)*wa(OADgbz^Mm%_WO1)(b@o^pmz*4^t=Pg672x&Y6{p
z!r2wQ36a7JIPEn}FAA7Z5Gql<eE9jCG!nkJxTyF_{dY*j&X8XOf)J6%|GQK5O;eRB
zp^N=*v9!HeN9JFu+h>cvT3t~t*NRPUL!>a9VSg4}&cEf)9#5p74ET_Jqcu5OIzao2
zZp(p=5PQZNkPX@SEF}MR_&CoVgPwK3btQ0RoHXWT68-qxU#u!!E`3E`+sj&4uV+s8
z$-V_mRgb<)1683CrCWn>R-b_hN=@Np^V5gGi<;0z^fOF%3y+Q9R|;g(U?c0vWCd9u
z&&7GyD<3RO2X+Q5>n-7P-OlIB6zA+c>KucWQXr`mmb6aG_uDy{L@8c(z%10wzug-4
z)iVEX(7m$H%QuyTUVldD@<;x&l|)R_a>@eisZ_>ZDC%vf%c`$;{owJ9x0^pn7BEa#
zBbh*=(g|DbES=0%*mx&4HaMhiJ&3`)K)J;OL8zolk)Rbrrr5tOSNe0);3WSRUa4_f
zvedBdY{2;XLr?n2rr*M*4-=iyKU?rN+-XfOf1a%PAfo354@TU2d9J>rx&!$dJv>{-
z=ls+fE{1~G&b^$c#(o|L<6$EOd{0Z=I)-#s_~y^GvvPdyLVD%l2K#Ij>aC4VxVgBB
zCQ}k?<2=<{n+eNUX%QZ!PF{xFx0C1dX~zsvW+wMMSW?4(8#^Du8um5?LrWK%kl}%)
zo};*Bp)2Q?wRst>8{;hx&Ms$}F8u<=^haJi;>;>o&S=~t-EarJfIg=?8h4LoyqPml
zZAo)$_Pjy3;O3}*3*p$G^$U*yX_=s5($>^nrEL9PJG#pU_WI3yZbeSdK23{nc<_ks
z#SG@6Ha@w)I>LYM*kL5dB8-DuDO=Xkear*q!jf`>vFbx8h5%d@EQZfN09v<6XTqBv
z^0<s&OaAIkCJ-=kTvw;tsuZD3JJxuY!qdTM0(CuN0LtvJbo_-XYucExbRR~rKSsj*
zfSa#E?jt(1STa3l7bQV^U3z6+H(yUjAFnJly)(mw5>A;}8njU0*4t}Yv{IR_N7cJu
z^#&9|rOESyvn@MG&YBexL#pci?X%uwcu==ZkeKR(^|U%v7xlcUWa>P}6SGf_F)_d3
zd&E8LEH`=N(4Bw0BM90n<nLk4Md{%QY9$BIN0vOQM{*cnJp{jk`5<?=K1pu7_Jb#R
z%*Mo48YZ*l`_RM9!v8DP6h;v5tIk@)Z=H<Bq~*q<XceQ|5bjsDS#8$)F^>m6a8lUy
zayg1=QTKM{!=k`^@@vhdiTT9O3i+M+eDLaEG`o#r){eZ1DT6=A53#5D^WsU3RIh>3
zh=kQ~qwlxwZl^)qGNvAt>!3Mx(4!ue+dSy-<}QTMX8Lc$=0j(rz;li6MF2s+hQ5%O
z%1U$V{^LT6ihZ{aSE9C?cUJNm>Rr}GDUkamyE<a!E6dM**BJOp@VPy)<?4iq35Gix
z64KQ6IAl0eBD2VCBc8#659^!qE^Sbk?XjAV?3lZgjKqVr_}7TcDrsW3RiztysuSP|
zdHTIiJ#FMO(F$2R9qvI<1A|f{5?#efhKmDdeN8j$@cXavfFT2|`28x3#s>ml5tW~Z
z{A8{umc=hZ1i1nsHJaq_n;K&{eC*P1I<gzp&z0Z*sBiuYhKER9JN}f?Zrj}cRg$JB
zRdZBaw7ZrTx9qb*VPd@Nr~{E{nCzBxgf4>XK@n72gMkc;fDY3;D?*Fh!&kCKz1cb8
z33NuDL7W3$y{h;wm;`#!Skqk<zOqZ860&3`M1b}58WbCa41Cp~?fkOisY#I5Lse1O
zw7u_s%*CYZF=Ov{ho}!UrQ$ncIxAbx)*CEml8CJ4v~#_^Msp<Z2Y}GNitIDb9<;;a
z&qDGYKAX8EDM-`03X_T{my9S~MKSq$1ff}kZN%D;8`oXK?)(4~#0SI)y#UrDV(u`J
zL#~0}QNp?ReOF=9#uM)G9JQ9>6<)Y2OHJz55zmPR1gh(cCT5;48s36%mm+X;rD}SL
z687Ff!-`+(5KXx|RYE6-^{hPLPK95=j?fY|-w^K62&br3fy6a~H5>7M?4bx`vQ!Z$
z2H(T8c&>2w$)NdZ9r3A(V@@an{hl#NUF+L2eO9g&S#L;TfRVP8>X>0}L5KtmCpTXe
z)w?1uDHw}MR^NbR^COxs91?5J1WZ!OiV`pEaLYP#V>(15jA(NAzvXlmsl0lb@M(pn
zrm(kV0i*$<JA0@c6B5{@c*uNMpeL_5F1Zm}2q(R_HJ6*!bE4&lo>7V2>G|_=tzU*g
zm2;ZTt~JC$phC=+aAv}UaPGjF;lzvjJn##RSe;wD*1w-}f2vs<hVqrjxjjc4W|7;4
z2{b~r{bzqY&gnMvHs2yK3bXW?=m6!EYO^1+d2(I=*FyFXo9IKhXny$3`oB?<PX!rL
zj4#8u!9}CFLcx`4fZi{RON4z+0rST&-yN~@<(iF8%5^COQ=&wc^Q_nd#wRgO-^yuH
zSBf?`@P_=%No=Vknks@P=V@UWmG<+Ma+OQxc$=}6<#cbT+jCp#B)THv-s#_p+7C-o
z8f!ciDf+q69>B6{H=BC-=bc&G$K3;HR^I`PF3I~GFS9lx`+i>}EF{zk4;DG~j(y0}
zF1@JtVf(^nQk_n$_IV+JR=?N4xva*Van<qAE?B(PqI&h#m^a(o%8Zm|r{&|H8}U^}
z_c-)0JRQ_eKt1O#WsYSm<!7)z0z9Zf=zmL3Q$)k=iYSIEB;mtEwd?f~Szqej@O6*v
zaWGg#Yu>A*n(u(6YtW`QkH8Q~I{nL%ir)~NV6w{nHmHcg*STU6D?w#PY$D<8ufQ{X
z*2AsrKO;HJuO+!XwLkq>nQ-=)n_NCDywPZ+2Meqf<J)_&vh3Zku9fpz{j|LhNTc6M
zcf98@Nvx@|)R<}lS^USISBD8r+=}RG5~Hqxz^(P^N3)eghNuyWOG;s%_H&8c(Ian~
z>L?=!_T@eog>og+5L@ZoJeqn>+)1?9QYk<JhOl5{3h${Ly?BzQ?8w#+0jOTyP~mqo
zI$ZQp-QIDBx}+}jQYcp%sct<E6E2eTxP^8@$Bj?I%EGCCrn2tq-tFD?7VqB2_1US;
zCAdvPaqtf?N%+cFsO@ens|jXb7*iy^6V(f6SsC5);Aa|-Xw7maKcy_=HS+hd;1F1A
z$WdbS?o$m74*sTw^PglQ06kEWPL$tu*RE|0m?{1qCCubxD@~JL5irxay27KY{T@w6
zNE9%xvvm-cIUQD-wCrE}?sV*5-{5C!Zq$+fQiU`>3`|$3;%_G0^IGzZ4pmN<B~@-^
zr3gS0HLGYBJf8Wop0URH+~L_*M3z-*l41J1%08~{eXYi@cAu&`?Qin+|KOr$v2v-R
zBiDxRUQlRfnlC-M;~d!)xn02GW`%!2X|Gzw@PkM#J*jfeK1{MVXEOS<aMv99LbQ3P
z1fGQPoLrkod$u^urugr}Dd1Uj?pv{qpm+Fo*KNJyI#jN)|9GFjN;Fpe#eSG1@5RR_
zpCnwq;?9g^Wo5MtRYd4b(&kGw_0kj?jB_#e(Z>g~#1%Ek?_{5kIg`w%o6$*6g|*ZE
z6<X#mTR?z18fN+?XR1mG{1k3oDA_O|qcNSDvbjc6(pxd<I__$$aBqr*t*j>b)4GGm
z%#r#A3*&vG-9aj+vzZlcJ|;#+>$wwv_;jq}Jug+uKWTntblmlkk<DX~Y6W*~ff9?m
zhtMifx;k%hBtiX#M`A;^hN02D-6i_+8sQJIjr0A?MRr~~hjko2;92Os_r$I5#xZPf
z>K&sthPODHMU5V!Vzjo+KDjjT-joDn^KQNEYA20VP<F#5G`mOJOKCW>{Vd|9Axh3k
z-egA40*rz?D^_)Px|TF~$dMhNy`^^LKC?v<d|%<Y(UQ1alx-sIeO8oHzAkXBw{rCS
z1=!*QrFPi@m`}~(zzda%3*l9UrJx5&1}Gfpxbp<c<p;JJ729>8q3Sbk*{y1eKU6b!
z`cs1Sc5<z%98GwIev_D@{APwiRLZAj>G-){zBL8b?~Tlm4GJYg$&u<JGeUB()4B>C
zSbNTM^nH%#-dST*Q*AenQ$vW3ee>Q<`;rdmB0%xu@>9QkeT%nKFTK;t<l(M44M2=o
zj^zHjSX1(IUk3(9wP1D`#*KYuP3Hs9{iT^!DM9&VLUcXb`+lPNakPu`A3FNY11J|s
zz~y|%pa07HC({Em{*bHqc(X%aS_?YbiIS!rJlxMmZv2JPuESMM)Vt5s^=cV;>mqyo
zUy4J06G^O0BKRGq<=>cx@&N$ym-(m`87r7gqmg@#t}Wzr7Z{rVNLaAL%cQIQ!6$r7
z!~A}4x7S=(e+g%0Q#_iT-z$!oH(J3GPwR0uV@iVxqu1Kg`FPE}Ev-2mB5;auXGKlk
z?dY!65u;}x09gvk9N0*;7_;H;AJRjM9SO(BUog=lE&e^ri9ce;aNZi1JehbQ_j&qk
z&%DO}t)K#UNC!TKUv|bQTB2=vzdQy1RDiR9ujzu^hjF_*d?+UirPNOnlm>$<qKqD+
zuWK8ch7&qEI-;lzBo*^=Hm0vDSuzi!i+D?n(ht~=(^C7240c)?6ZW$`w0%@h{JtSn
zLHvje?1OPDJGomIM=tE{K<-lz{vqvKDd!=tP)wicppi5VQ*ep02mg-C^$0!MXX&Co
z4~8XIC|js&p&<B4(J`!NGL!rEehko%{PNDj%u`q6Kdce?I6=0KCP4`F(yl8GMz|0t
zhFsw8yY(s*c$g&Arl5@-`$Gj#I`=BkxXb3LQ{hw&6fNL5R;=~4NN|iEYswP*4KLlb
zI-e{ec=J5`VtggimxVvZO=TnvlI(obHZ<9EcNd-=A&Mv%s?gC=9#I%}Uul;Pl|2DR
z^^ra@LpBctJARPle*JOBzd2WZm|A4gbwbMR_r6bfLTnMtgXTyX^2M#sd)#VTdYZE0
z$8nho^Y5&1N@|rt_8-SnN?hP@u<VvcM%NdYI`PrOx7pggOl5`Aye;f$!(!O`7=4@y
zSuRs`9Qjd@5cG{HAD<Uw0@TSR$LJQHdrDWojypqG!3E&XT8ba00aASg?s^M-@;<F5
z5Y!y)Jd>(Q-*=t$E8<~F>MdmBj<HYJ^9p2Cb9`E9G2X9xo}bd8m$l;W(IQX7X!w<Q
zTF75G)Fro$hHMWU)UzHI(M-vmO9EM-_SVV*=e0@L>DWp{s`4Y&%H@HMMxIgu!73V>
z_fs^{{ShWNDR=gL4y744-*Zl?a|iqYQ^df%2M*cg_hYE1lwQ$+jX>6ZFu0ArkHu3M
zYM}q~adqE5#yH|-JLhwsv=~*2TKAP6LphQH${LQC-)-|-g^qk2AL|>$TpqU5g6SR>
z+p~A^wvLfG{S=z?5NMs<U9;j%X8~YN3yiXv<6`~4hqXD6iJVLou>}cP{W?3`3f>At
z`Og;&2CNDmHRI>qdhzIiG&28xwey`(O*dP=K{O~5K|rNQ02M(|KxtA!M^wbbhbA4A
zDov?EAb^N8X`-kg{h<jYNDD0#L1_Y^MruGhfrK7N2;4uO^WJ;zde{5m+>dvie9Nr=
z?Ad$Io;@>r@A>VNBc%5EK9ZsK!U4d=|6Z(HAIs-PJhzUxBc~cj{`E#1*=x5dkFWTr
z_}cUwL7<UjY+-J>)$|!LH{I^5%Xin^f}Q!e6`=C<veC$B&Bz<@OYai)^Fud4s*KHk
z=}U++Z<p4ehp%hAoo(-oNP7aTX@xZY)fpo}SVr4PSvWdog^X04t*3U?T;@<8kM;<-
zq6Gwe5w0|uAJI>3@F3h(kFyF)p4VDauuASyMN$rs2$9cD?H$o6yz9TK6%u`45So+E
zGu5euwI(08%SCI1{n>Pb&mP7xf=eSu6gZ_>WsOwOb>4o$?VLB#e!*tHnfg{SQTUXr
z$742T1l#;}o?obT8>+OHPrh(hyL71U_xm&T+24y_OdeJ&fb?TE;NzP&^E_LA_I_3;
zznLlfJ~QnjNpnl2ys%u5K1X)@-nOl~dWll(@?5NJwzSjd((PjuR#vNTqW}+In!mJE
z_OT&E%)Q6MIK?Ecc|V$JV>RwJo9Jov?q_pKg{-gNfV=fXeAo<m-8p5HM()i*_!v4H
z@zh=2t=z>MoY{ND)s#&6VBYukH%gx4aK)a{Vpa@_$`+A1VW772^j^ZWg5}u2dP@f$
zkKa3WoL5X(;>e`hgQJa+EtT&lrGQLF2R)C|tV`aw+xf(y+eW}-@FRji!bj##Vxs}%
za(dwQu!!4Ix~K)Jc-;j)7ilOO3`gy6q#v}ms%(GNj8k53Gp?wwY|be6O~4uv)E1<v
zlQZSgC#J4PLY6Y`v_H@!>>*^ftvz7G<$-wPDWJ>`^d%e|(Rxv1B||#2ZPD-jGu&!_
z#%v_l2?46R(>&AbZ7XBo$anhcxsHIAXi!^9vZH#~1&|D-CO0GHJ9gY;@4Qv6EZ|o1
zRXADmQXPNsK6E)|8ho_C!_ngV7(_zH4WoA^QPg&PQ-iaqwj$QU&*A~)8yF{fd~%|0
z!e{o?&Gdl^EpE_#qaFXSo+12AfTKbCGOotsU`JNNj;@r6=E!knIGXi4Tlr!MP@{O|
znS)5B!OKhY8v^7J#f-(mw<Kr76PlkgzkT~~{?Ne5>Y4e`PT=DS5fLgM;%aX*f3xMN
z>Yts?Wp19?D#iPA3O{%w#_gThIWMr#IG}!fGAcXX*0>Al>M`!3w_E~KPAGvC>u*Zs
z>Y$q6Uwm`Rxz`<fxRyZ~x(SYm2WDvwdZ7(R;N%-!L8hhp8X#jH`M|*fgqWvC@k%>#
zvTwR5?nl%)bcVv^xD*x0pJ{wPBeIaq>(6Cu;+NCeI=<xL8s~T9iAA>>B8@oSon7en
z*9WC0b0c^DBULS8aiiMYN3$P{$@0~Th1wXmBh@W?W$rw*8ao?f7&-A9MX`DL3<nsj
zfnZoFS$Fx4*0El+mT(5^jqXCklCra~B)ZO(<&4{ih+YUtA|V1HR)&noLd<Deifwe`
z75z*4nlpbUYI`0vQ`gjUBIqQ(TJs2y@8tso91o9z2ms~xC#+eU4S43;El9J|(Dg!M
zhd#e)kKcHuQ)8a;J-<oC_&B9An@Ve=J%cyBZ%rYu&WA*^{=F8Q1-s_eutCGACh!PP
z+e|qV=I%nP0J2`^Iv~<<jp*YP_k!nBnJ3LZuDv}kT&pZ8NH`JgU4F?+?aog`O9&8G
zQt>6s3V+b4e~p-n&0PHEQ$=JzWLOLj0ge1acqc$@-_&_uB)O<19e)|K-cb`UHqEPE
zt5j~ezF*f;d1v8^P<*cc!$EUX?vXI9!j{4obY~}Q!K%;?Dx>VI-|dks#ON9eUIm=R
z0%}|PiSRRBr`Yb_-`;(wDhPVnUwKRY`RyDtQ3;v6D{1^<(ZRR)SnYh+-DV6gmL9zq
zt;?%^xO;jjaN<}l%!Roqv6}e+p;ov0zJA`!XEN@vc_yfVira*Y7HCDwas)ViqqMna
zW?$8sds>W|iClh1)E!XI=?%<uxbV`e_`;zV_h;5f6TRXhi-)^})qQOzif$a$YE<$u
z@JzaDZZP=4Nl)x#l=3reJa<PxV}skqoY!S{Y$0AVb~^IP_bg{<P4#)APPGw02$bAt
zcy}WGS0o~{KpFEPWzMc(-E-}Yp2FdMW21$Fn5<D*LGNDopVSohhDB$6HDQW1#HAmN
zGJ~w20qS<V<fFN!U#ExGF>&Td2>QnGi><VYcTZovLf@@odFzdJ2BK9Pe+}euZq6t-
z`mbgo{KIY*{`JC<cYYU^#R6lsgF>N}EzButT7W&H(;bt7JG2WBgS^0+kvAcMB}<RV
zwB8b~?V7#zI`?Fhp@Kqr+N)A6Chb6uMmrrsNv9z3x5g*N*oJ^P7{L<8>K^sOo;ANk
z#*gND`%veb&~**B4X{K?mP8MAFhl2?fkKqqz3AfP4LNvQ&F(Wjwzlbt(XgQ0i5s(2
z4_@yxq|cM@SDrH-$5GQ<T+eNV=O|?UjC#b=u>oQ}iVv7>wMZYf+79(jBkKRz5+`gd
zAG3^G&)Pojtl71dZEWvseeVPvJ0Fr!?J@t5Bgf$vUkr?+qpZvD*6FZIwc#*lLlI?%
zPoL2E<Zl~<>Z`wB%{Oa3w7CY8G97Cy)!$F~^6k|h!sKR;@;&vHo1*?tL|@JuF21@Z
zXgnb<FF9>5kL$=hBCNFBg4S9^b+#HxWaqls;MpySVw?^4xE92xLuwVWjcX8dj8BNU
z{+R`hcCzj|Cl>bdhoAp^?+h^IxF#9-Hhg1XEwvtpy?*hHZd@)$$Hs3(GvHOQLqgn1
zh)}|dQZ<mfBq^l!vGef$vqrtl3ZNugq(*YZli{SB66T&fU05*V=mYr732S}()%qqJ
zMyf(qKk%7baOopU@i0dqs?VEG(cOpkq-+>bYC~|W`YRq2Xz%sCt8wSx66L`No=wRy
zqIRkZkG8U-sqnd#64~l*y2sIy^<m$9RgOWBh}P~#As7EPZLmjlB+u(0zNBl&rmb-4
zC$rF@t9H1{eTrz_*B;s?&N+KxIHLdr@6HHUhn4f64BaQ(KNu!Nrs_^!mG2GPrfh)M
zhvdcXA2WP{;zng$qT3AEs+4e58>I$$Caj9I9-g-3<HM<x>}SX4BU?=6gz);_ewMQ#
z-q0`CyQPu8W`$0L5A_RKrdfU{tm^U$X0bS(HXINp6*d#5E{TyAA|@H@)$x87m8T;X
zGQ?*p6?>T35FRL42mJaY!rwa#aY_ijXOLoU!E$&RQp2nPiGVIY`Y3U~0fXBf!3#B~
z)fBE8Hm4c*Jr55LpXWY4ob`FkH9#DpUTTBa$vQ9jUaP>6r|0CjZ=k1XpViq*oyEN%
z3(JYmD-d9!A?-Jr?^hhN2!=j|igPp`xDTj3uP)lza>3Bf{y9p9m#ktWQESmovxJb4
z5P$t@m!62R#r66xk774|0I?sF6h%jO#|Hm(@)yZM){V3C$1J~4+pAx)CKiKna$YO7
z9CoV8yKy)b*?ySN$nsob_v@SPd7m;_R--M?3{&Kv#nID`IZ2B<0oXjjP|o_{rmc?m
z;;j&gZbeejPM@x145nu3%R%;6q(SE~=$4~Gk3rfw<3T&$-Vwa!jtyQlx^B^QtT{_h
zt_yMDC7eF>F)0sS9;{}iIHU2IP=3LjFXKYsUG{g}hHG)&TC3}k5mpYZ5lMh4F9=Vi
zu+<$53bF<K=1RY#y~?7p8u9{2m)74>Nh-tfcBkYt?PmKYt0*hiMHGZ)gnyM<=-R&B
zCz*69@b{hk9=m9R0!mfe@vS@&wr-{$kyD5?22uM{bqGIq!&fT~;2;I^zq6AZxE5`-
zr#%@68T0Lr0zooEYOdx{O%lX0l8icQ4wd`;O!ptLxwnr|P7R*M9lRT337Y(pi^(tn
ziXu7|Zf}bjm32zgF1Lq6{T<V1cjO+ktL#krlIu3Qi8yi%sq%h`+{(1Y&}BBS1>cp*
zm`H&t;DYXhnmTE9YtXTQzU-h%FOzUTM}r1p1OoMramkAG6|}te?m;dU<i$Ebm-joT
z<5c&97A;@&z^DO%`+K`^DuTb40x)ka#PMX>b$fYu%@sR-mi^SJAL)BDqNGzTn1+3t
zn>!cy=w@wYvd288>UY#mtP(kbOZa@yX0~7q*NyY@S{85i)7d5#k!r-042x$?$DFK?
zJ5%A)*t*&4YsJ`!k&}T@C>9WYdcnz|Zne_5g|a)T^YuKEQUh6Q=2tnby4?<Mg)`>n
ze*=5kbLMp&IhEe`^TniZ5HK{S5Kqbdrm~aJ`Wq4#cy)h<3;sPt6)OVupW~%L@l;b=
zXO%rtIWyxFusB(mX;Z4J@}gfayAU%E1Sk{K<`=DK)hORUYERAjd2b6To($sq_Wj>^
zs?iMxs{5DsC5Z=}JN(26u7i2iJ&8c}1tbqZ3B<!@%?4iZ<@xUoarNOgn@S)Mn3?B?
zbucQtm-??={vR5EQEn5nDSwDsO9kHmIJDV>W&HaMH0bNYsRUT(31y-Q{NF@D|9%6&
z2Tvd%?jh0OCeS~n4gU8V00rG{U<Lug+5AJP|C^{<f2GG@@{1`~%<+*G21ZYnSWjn}
z9@<?(Q|8edOClI}+^$m4{`BPj=6)@dR`G(Yi;nI|le><~Ts)9vSLF;kz!PNy#^CPb
zryD#bz1KD*s-(tW?@!e146bp(50GGH1Px_85N@kGu`{>B)v$YikBIVkJm&AO>Ygf3
zY`D5|&W}E}H;c&)9HIUE87=XEPBN}v(}4(5(;D`i_8ONeo)ZTNBU>M~t#Elg3rNIv
zJwVP2?$?S`<qq0Fswz*T60zOR<Qk=YJVq57L<!n+eHJv5M9v;^@FF7Hx8#4Yt8Opu
zu!P6S2aMHVor305gZ8WT%?9QdeSwIVwUBj9=2O*7e!86}`aI5tE<ZeVuv7f7x4<r-
zUvJp0+hl5QH|QY!HVcunkWa?hI-@Cgq8}s-zeV46mq*!q9q<LztxddNv>L6f?6d}T
zj8Tf%3wmtn;}Cfwr|SF|fRt5(W^9$$(VkQiO|0HKfhd@47TqOx+VU~UI^`8fMO9Zb
zdhfOj561T=alh%{jb#1Iu|*%Zn%PP(rBaexokAcyozaxOA5qVeLq;x%*N`=-%C+?(
zH@D(DhI*UDYB6^7)N$VdY$+Afs!E;hRmly9FQrg%fm``JMygL|nlNOiq1H>2D`^f5
zTs5M7e+)`3@krG|L0M$~@+6G%3rcGf?d$Pw#!@f6md(dQlxLpzad{PIHwD4i-?`D&
z746ciNEMJDK_t>aSQF@-C1`#{huH}!HKQ6(s_yHUDuCQq7I@_>a4?lvXX+1UrWEOz
zyd2c>hQU{1?gIC*Tv4U*!KY66(4g-gg66j}>*ya&STnjLFe*9qIX#0qdn#yD4l<8s
z?;`-)8&u>h*KRGWcVRCmdu+m<Q*_`%Zx*EqfIy)kxf<8KFLon4%z@Yb_YFq+SNubL
zKY@SOTp0}>1y5OxR7(2_KyH=4skDOMa*XGsnOn}qpZlq7!#AUQo`76JGj&q-_kBeN
z=0+;FGXn=l<G}JJaD~v2C8`oEzqcY;U`Ot1Fe4nke{%~=*%rDR#9-`%?jjUJk{;f&
z>s7Gm^)(#9Y^V^_tl0C`zo~g&8^-q`h`k<uQ-5#W54=kva50addMOtIG0A~&DnG;R
z9ODOpq<IsTzlE8-z;q4B0wodrx6`23i_ni$I{HaPxVbhXYocC|5tHYMYpm(!$DMO3
zl1e}(5Yq>?x4zX>+{Y0ChjJ+ViSc-^=KkQpajCwPGVu4BHSvHiK%UaQFzM_0hTCAu
z<z(;v!LEnQOs;v3sx?=JYMDrLyww~_Me?2CGkklr-3WhR>713YUrE@CD6kk%nd>Ue
zBR_obsG_A#rEK-##!*{pqO0ghY~mg4>^tTz>kJy>0ihOsvC}=y+#uBN{r!)!ec>*X
zBrASEJC(7n#;t!*ni3-?{h4i3b$Wv>C-RF{4T37v>pxl2r*ceNV}~^mgYM;@vu<lJ
zKV>BCtYiSyVU!E!ESK2Ji@QX)uelh~PcmZh)Gq|;=4wAWy)CEBmacg*@D3q#Xt08i
zfBgLwWmD3wrP+Ai60D>hdB=WxK)NB(t+T=1;X9TVe}KP3S+txvIJFp1O69FRXA)7t
zu-v6q#Qz$)F-#fnlOLCNQ+*m*#DjevUN>H8{?P2u{CU`9U>x`^{I?kI>^>pHZ)5o@
zCelZKDc|F}FSms2+rJL)rAjTn9_uJ^g}m@)Q%uXs>puH5m%jo$!T0Rr&ZZ^+W%X44
z(@^i)(@{Q`&W-m1Vxuv{mdZ%TnTt1j&^S>hvS33!Kd?mD1vJYh?7_^l=U<VMOIR+?
z#SAnH@e2VqHt3*--zD4zFhw-tD`H!M4_2RENb9Z(scI?c)`vcgoX8SmwU}14EH3mk
z7M4i;0B#>TdpWqmg3+Ci$v+sjHuHOD0)J2R@&DzJnXBmT3Mb{qwU@G!%iXpAc2w<B
zd67kVUq;y_1e4`!w)eu*Vpu2Z@H75L9?_|kM4y#8?W?j+YOp5VB~VtUlo6}mP=2~V
z2~qgKa>i<-=3Ieln-_clcZZ?-*s{Sa6NynN3)Gz~93LDyD{DueC|UHJ9vP!$Z)aCt
zr>$fVnSe)uj<nZTn34o;b$V%bsNC%qf0@HyeWtvxt25}HEAw4for4r7wW5^5S>X|g
z)FwCT=Gpa9r;O~BuiJ~!HsiJxpTTv0E4G#w_=RlK14cDL#OT~7_{j+m=t^YJ!WG>1
z%1Jxtjdp_~dnrUcDv#6#Ew^oE?vj3grV)Uky=>~;Wy^w>i{GTDYNex*y3%->oLa@K
z+57N3=OG&Q)6rrrO}V0nffr|P47o?b#MS})u0g>8Gr`Vn3ofytq$TRo!7x)r#aCEB
zDIqfi7Kj-MgbVLyIyXYS>;WW^<4MZtXL&PJX3mwDB7wv>6$W$c-LfN@)Yn^F?DALG
zxZj$^eXN0KLPVr*(qkf@ldLj*IwqojW~Zz?L8TjwF2Mrl^7wbzeHnPS7{O&r7j0Tp
zU&;co2T2t)1%vZzn8MO70Wb!f^>SS=!AvzF4!A<O_@B}c@LmYA@K{N@LxHQ=g2#+r
z=i|_GNKQe{l(|oGP0j!=+S^=)Eo`1|M=LF_OT%1K|F2)Wqe9Ii0a<>rY~YSz$~7+)
zFUX^W&%n!8sFj5?pJTX241=U>%Ne@gh#Nfe3tXj$63C7nt#eUy3u?p=6O_Ler~vO?
zk3AF9Xn}eS2V2mGb{!iozs-KRXGcu5bA^6kS0fhs5c_3$Iy|xAe`z22g{eW)(@}Y4
z6NYq1kF-T%4Z#+ZV06OT>eZ6X2jzTJ71l~f_oYn7m7`AVO=lvfh|#5|FPycTiZ+9d
z4Iz{2ts9&&Io!;KSV<-oE{DFZ+*Qh2zNPMn(3VDq$j?2FFLg&$OxR1#G_{?Ay6hT-
zshtZmA9<eQFjVU_XDVlPllwt2Q)PObSmx9``$&zpJ^L}f_FBMHaHtPk_g~jz{Dtv+
z0cJEcM<rqQ5)((LWoLt{eSL4FmaU_8@xINVqxZEfTId#&D$6Yj_6PK@VNLOq(UsoO
zKfhVHnkAkQ*~EEFY^;0OW`i{{ym9yT=JZY^%`+w4<*=vtZ3ma15yo#lef*2jqFfd;
z7G1>t=(v}q0DD6!_v;l^d}+a8)K8kz#jw`@nr^q>en4eJ!flUW+5C#8vh>b=N2c`U
zO1>*Eb2y&BVtQUbv1?9<epL>>fRZ(>b$U9Pm4a$pj;w^7kNToZdhKR2xZli_a^ZHX
zvAgQ=N%FGqSvTJGvBQna4?SpA`mJI(<nORu!bzBcSPuH2u1*6|zU9}u`FPHvZ!HC6
z6x2;(mpcxiCm98f<m%|Zs6G(t7&1)n7!7Bn2?ZnJAhQAeiwcc3_Sfr(%71rpH?jJq
zX%@(vWEMGN^Y5ghj7x2P4ATp>iu4Q}sb8~@31M>1M85{nZKc0e+`o%5ejCX-Yd$=v
zWc;Z&UkPP`<qSe@D1EFrpLRRi`fkbHg}e7@6Zrs+iywjnX>t8@XquJ{Q7-wW#V4%!
zt9GWGP{<v9H1`SXlemE!rVmOay_RwKuZ1gnP6|MTc$g9eZuc3NGd<e5?pJo2r|Z-u
z@9{zYh|#YzFqsW(Vwd}=Gwr47rKr$#sQ<3M763VfTF9YQSXDhZlD80&{wi#Rg=q{I
z2xs@vBqUp4W6m~}vZRirrDydOfhy@G=&r0QLCeCP4^L~2#-@*OBv-Z{E!p}IpFi}~
zmZI(Fn#pox$$kA==iZo&>QP0n<t0znpl#1THI(?Frr_BNv?*iGXGWQo092$;{~F6j
z05E|wx+aozTYwXDSx8n$?2DTdGxzwirf`;=@0Tz&XM6@f7OXR@ESmDR3Cs$>Z(Y9e
zxWDY9PKV&5g}qJG_Re*KpGT#SR4LI@{T`PRlEI(5j6y2!kxenc5W;07IP>&!MFHax
z`FX;*dn6|X0r-N=TksD#1lF@WKcYy!D{Avmw>^x>g`Mp3RJK#Ri2AGxC4OJ(VsI^%
zGAyHlDrT`L^I4IXhP)kT*`v>B0S_Qa;bcQp#iGCE<BgW9T1uB*7Vp0bQ!`V)J?^l#
zk3Oh~Y3m%l4j|0Ny)!nqrw%MPhb_}NaWu#Pt}pfwR|4cJ$hIS|2)QYHE8ejzix;Sj
z3StG<?!vV|X6jc{qVCEE7GqW=kgVwGLV3}wbmxMVU%QJ=<&gLafuP2z@OMi=so{`h
zMu7x?N5lU}E2QLE!%hSM<wn>Y0sW+!3J2Gg5!)|qFRRC)^<iFpYEl?huU^!$deQ;H
z@dEQ*h(<BHvxUHi?Luc_)WNHDsHQ&dQH5EgjYa=b10Tq2N;yc06RqejzLbL!J?-XM
zG!j|@V8yXx_YOvDv&YIq#MrV;46JDQEnD7k|1E7?Uz^7pVLYc-te2rkmRfw!T<pr%
zc`<^|yuQw|f45(1=`HNbQPkY!MojfaforyFF=hM5tIFQ?aapcOpShm`9QJwm>s*uG
z9;V$LW|VBIoUuOzCMYnRx)#tawCG2pj{vzSscJHDD`M+fYd-t0SZ$Jt$cM{~(vd-C
z5<6ACquBLf=S@>j!6|35m4q*7Ea$ZQ?-7s;*3hZMC1d<SF#kJA$o-YYl^e3ZA*Hh4
z7y-FX6V6%ujd=-aC!F<mC$s}%A7Gc=Q-09<Ha2%Y3H3aoyAWVAvfvLY(U-}xM(Gw!
z)nM!7luyqFjuvA)=cEa20X<`SmQNo!-*aY5;qK{vU#-{qiLIh*^8h(!en0oM4^EUS
z%k`?BJ=X?h<|a_-JGhjMd_x7wuUQut{AkD&G5CY|r#O;{5Nxi`;UOvx+JEUqY6Ml0
zQJ02NOyBM0JUL9SA0{bP3kd2p@)golh!fH@m)DAKm5m)G!^;@sr7Q2E*T2RZ!i*`4
z%ZzFyyIws(+{ns5?MId@1?FSXtn{R}*P)jr=VpX-u-~e^S#6nGPZ%Q$)o&qn$sif#
zyh8OLiiWc1-*%La?t^ST<+umF_4cJfar3(ma(G|Vk5z;^Sy*8$n3YL=>6zVf69-Fv
zws9C+Oe#Op*>zrK+{|Z4C5!AW>r>6FCcWAY)4?WADtN!37+lWbopi1yZ8G-Vb?#sr
z(zE}rv>2Y=A13|$99x3U<HF>fqO5Qjd9XB|lx2o&%QC0hk6n2nJ5wg%fNWv~I;&Kh
zVJ5~35@*qSdS~O%=4jiv(K3SRxCxS2Gf*n8`!H?xji`t(NV)1XC0}3XWy((F<-8vO
zL#MBHf#TXNbW%+n2#SQEC@i@c95A$hb$I&5urrIk^NJZ}WCojx8x@ZiuV$VMOJU04
zRU^M!Zclrw1Zd=*bnw`f;Y1if*%AECUX48SpgnE*%At4}GRz)%w(xCRc)I{78R!<T
zB!X=FuWmxV_qOBzPq#yYhu!dO{~+^^0S^C*bp-=t|EB>#)%vBP$a`eapAW}|yZ`0G
z!y$n2-;FV4@FJ3#fG@-Ul{5BXeGe9ZwiEad&wm8!3T}e`^Z%9VL?uvHa39-0$N(~6
z@N9cKyQJx8tAdIViGNB5P+z?|aex{Y_cowpUHCKP;kSJpdqzu%eaG8U-@*<D0^*AQ
l`Ta)&|Ixtz_Zlz@0xevd!dqTvbvu;xuJ!{hw1)M|{{_vCQN;iN

literal 0
HcmV?d00001

diff --git a/doc/load-balancing.md b/doc/load-balancing.md
index 4ed938c990..c5e59331c2 100644
--- a/doc/load-balancing.md
+++ b/doc/load-balancing.md
@@ -96,7 +96,7 @@ Load-balancing policies fit into the gRPC client workflow in between
 name resolution and the connection to the server.  Here's how it all
 works:
 
-![image](images/load-balancing.svg)
+![image](images/load-balancing.png)
 
 1. On startup, the gRPC client issues a [name resolution](naming.md) request
    for the server name.  The name will resolve to one or more IP addresses,
-- 
GitLab


From 892e917a09d46e70703dda5edcb30a5b807f8f60 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 08:12:39 -0800
Subject: [PATCH 139/344] Fix link.

---
 doc/naming.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/naming.md b/doc/naming.md
index 5d603061f8..588f611f16 100644
--- a/doc/naming.md
+++ b/doc/naming.md
@@ -53,7 +53,7 @@ include:
     is in use).
   - The name of the balancer, if the address is a balancer address.
     This will be used to perform peer authorization.
-- A [service config](service-config.md).
+- A [service config](service_config.md).
 
 The plugin API allows the resolvers to continuously watch an endpoint
 and return updated resolutions as needed.
-- 
GitLab


From 473ff83facfadc823523d3f833924c661432a943 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 08:21:12 -0800
Subject: [PATCH 140/344] Fix filter_end2end_test.

---
 test/cpp/end2end/filter_end2end_test.cc | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index ab6ed46de5..28bd6baab8 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -114,20 +114,17 @@ int GetCallCounterValue() {
 
 class ChannelDataImpl : public ChannelData {
  public:
-  ChannelDataImpl(const grpc_channel_args& args, const char* peer)
-      : ChannelData(args, peer) {
+  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) {
     IncrementConnectionCounter();
+    return GRPC_ERROR_NONE;
   }
 };
 
 class CallDataImpl : public CallData {
  public:
-  explicit CallDataImpl(const ChannelDataImpl& channel_data)
-      : CallData(channel_data) {}
-
   void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                               TransportStreamOp* op) override {
-    // Incrementing the counter could be done from the ctor, but we want
+    // Incrementing the counter could be done from Init(), but we want
     // to test that the individual methods are actually called correctly.
     if (op->recv_initial_metadata() != nullptr) IncrementCallCounter();
     grpc_call_next_op(exec_ctx, elem, op->op());
-- 
GitLab


From 0c3e8dbc68d9a1796dd75e241a2902ee3ea8fbfd Mon Sep 17 00:00:00 2001
From: thinkerou <thinkerou@gmail.com>
Date: Thu, 15 Dec 2016 00:27:03 +0800
Subject: [PATCH 141/344] fix code style

---
 src/php/lib/Grpc/AbstractCall.php        | 11 +++--
 src/php/lib/Grpc/BaseStub.php            | 54 +++++++++++++++---------
 src/php/lib/Grpc/BidiStreamingCall.php   | 15 ++++---
 src/php/lib/Grpc/ClientStreamingCall.php | 11 ++---
 src/php/lib/Grpc/ServerStreamingCall.php | 15 ++++---
 src/php/lib/Grpc/UnaryCall.php           | 11 ++---
 6 files changed, 68 insertions(+), 49 deletions(-)

diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php
index c4d56790f7..9f0b02b8bb 100644
--- a/src/php/lib/Grpc/AbstractCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -62,7 +62,7 @@ abstract class AbstractCall
         Channel $channel,
         $method,
         $deserialize,
-        $options = []
+        array $options = []
     ) {
         if (array_key_exists('timeout', $options) &&
             is_numeric($timeout = $options['timeout'])
@@ -89,7 +89,7 @@ abstract class AbstractCall
     }
 
     /**
-     * @return mixed The metadata sent by the server.
+     * @return mixed The metadata sent by the server
      */
     public function getMetadata()
     {
@@ -97,7 +97,7 @@ abstract class AbstractCall
     }
 
     /**
-     * @return mixed The trailing metadata sent by the server.
+     * @return mixed The trailing metadata sent by the server
      */
     public function getTrailingMetadata()
     {
@@ -105,7 +105,7 @@ abstract class AbstractCall
     }
 
     /**
-     * @return string The URI of the endpoint.
+     * @return string The URI of the endpoint
      */
     public function getPeer()
     {
@@ -167,8 +167,7 @@ abstract class AbstractCall
     /**
      * Set the CallCredentials for the underlying Call.
      *
-     * @param CallCredentials $call_credentials The CallCredentials
-     *                                          object
+     * @param CallCredentials $call_credentials The CallCredentials object
      */
     public function setCallCredentials($call_credentials)
     {
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index d0baeae955..aec60af094 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -48,14 +48,14 @@ class BaseStub
     private $update_metadata;
 
     /**
-     * @param $hostname string
-     * @param $opts array
+     * @param string  $hostname
+     * @param array   $opts
      *  - 'update_metadata': (optional) a callback function which takes in a
      * metadata array, and returns an updated metadata array
      *  - 'grpc.primary_user_agent': (optional) a user-agent string
-     * @param $channel Channel An already created Channel object
+     * @param Channel $channel An already created Channel object (optional)
      */
-    public function __construct($hostname, $opts, $channel = null)
+    public function __construct($hostname, $opts, Channel $channel = null)
     {
         $ssl_roots = file_get_contents(
             dirname(__FILE__).'/../../../../etc/roots.pem');
@@ -98,7 +98,7 @@ class BaseStub
     }
 
     /**
-     * @return string The URI of the endpoint.
+     * @return string The URI of the endpoint
      */
     public function getTarget()
     {
@@ -106,7 +106,7 @@ class BaseStub
     }
 
     /**
-     * @param $try_to_connect bool
+     * @param bool $try_to_connect (optional)
      *
      * @return int The grpc connectivity state
      */
@@ -145,6 +145,12 @@ class BaseStub
         return $this->_checkConnectivityState($new_state);
     }
 
+    /**
+     * @param $new_state Connect state
+     *
+     * @return bool true if state is CHANNEL_READY
+     * @throw Exception if state is CHANNEL_FATAL_FAILURE
+     */
     private function _checkConnectivityState($new_state)
     {
         if ($new_state == \Grpc\CHANNEL_READY) {
@@ -167,6 +173,10 @@ class BaseStub
 
     /**
      * constructs the auth uri for the jwt.
+     *
+     * @param string $method The method string
+     *
+     * @return string The URL string
      */
     private function _get_jwt_aud_uri($method)
     {
@@ -191,7 +201,7 @@ class BaseStub
      *
      * @param array $metadata The metadata map
      *
-     * @return $metadata Validated and key-normalized metadata map
+     * @return array $metadata Validated and key-normalized metadata map
      * @throw InvalidArgumentException if key contains invalid characters
      */
     private function _validate_and_normalize_metadata($metadata)
@@ -220,14 +230,16 @@ class BaseStub
      * @param mixed    $argument    The argument to the method
      * @param callable $deserialize A function that deserializes the response
      * @param array    $metadata    A metadata map to send to the server
+     *                              (optional)
+     * @param array    $options     An array of options (optional)
      *
      * @return SimpleSurfaceActiveCall The active call object
      */
     public function _simpleRequest($method,
                                    $argument,
                                    $deserialize,
-                                   $metadata = [],
-                                   $options = [])
+                                   array $metadata = [],
+                                   array $options = [])
     {
         $call = new UnaryCall($this->channel,
                               $method,
@@ -251,17 +263,17 @@ class BaseStub
      * output.
      *
      * @param string   $method      The name of the method to call
-     * @param array    $arguments   An array or Traversable of arguments to stream to the
-     *                              server
      * @param callable $deserialize A function that deserializes the response
      * @param array    $metadata    A metadata map to send to the server
+     *                              (optional)
+     * @param array    $options     An array of options (optional)
      *
      * @return ClientStreamingSurfaceActiveCall The active call object
      */
     public function _clientStreamRequest($method,
                                          callable $deserialize,
-                                         $metadata = [],
-                                         $options = [])
+                                         array $metadata = [],
+                                         array $options = [])
     {
         $call = new ClientStreamingCall($this->channel,
                                         $method,
@@ -281,21 +293,23 @@ class BaseStub
     }
 
     /**
-     * Call a remote method that takes a single argument and returns a stream of
-     * responses.
+     * Call a remote method that takes a single argument and returns a stream
+     * of responses.
      *
      * @param string   $method      The name of the method to call
      * @param mixed    $argument    The argument to the method
      * @param callable $deserialize A function that deserializes the responses
      * @param array    $metadata    A metadata map to send to the server
+     *                              (optional)
+     * @param array    $options     An array of options (optional)
      *
      * @return ServerStreamingSurfaceActiveCall The active call object
      */
     public function _serverStreamRequest($method,
                                          $argument,
                                          callable $deserialize,
-                                         $metadata = [],
-                                         $options = [])
+                                         array $metadata = [],
+                                         array $options = [])
     {
         $call = new ServerStreamingCall($this->channel,
                                         $method,
@@ -320,13 +334,15 @@ class BaseStub
      * @param string   $method      The name of the method to call
      * @param callable $deserialize A function that deserializes the responses
      * @param array    $metadata    A metadata map to send to the server
+     *                              (optional)
+     * @param array    $options     An array of options (optional)
      *
      * @return BidiStreamingSurfaceActiveCall The active call object
      */
     public function _bidiRequest($method,
                                  callable $deserialize,
-                                 $metadata = [],
-                                 $options = [])
+                                 array $metadata = [],
+                                 array $options = [])
     {
         $call = new BidiStreamingCall($this->channel,
                                       $method,
diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php
index f0e1e811de..b03bbd204f 100644
--- a/src/php/lib/Grpc/BidiStreamingCall.php
+++ b/src/php/lib/Grpc/BidiStreamingCall.php
@@ -35,8 +35,8 @@
 namespace Grpc;
 
 /**
- * Represents an active call that allows for sending and recieving messages in
- * streams in any order.
+ * Represents an active call that allows for sending and recieving messages
+ * in streams in any order.
  */
 class BidiStreamingCall extends AbstractCall
 {
@@ -44,6 +44,7 @@ class BidiStreamingCall extends AbstractCall
      * Start the call.
      *
      * @param array $metadata Metadata to send with the call, if applicable
+     *                        (optional)
      */
     public function start(array $metadata = [])
     {
@@ -76,10 +77,10 @@ class BidiStreamingCall extends AbstractCall
      * writesDone is called.
      *
      * @param ByteBuffer $data    The data to write
-     * @param array      $options an array of options, possible keys:
-     *                            'flags' => a number
+     * @param array      $options An array of options, possible keys:
+     *                            'flags' => a number (optional)
      */
-    public function write($data, $options = [])
+    public function write($data, array $options = [])
     {
         $message_array = ['message' => $this->serializeMessage($data)];
         if (array_key_exists('flags', $options)) {
@@ -103,8 +104,8 @@ class BidiStreamingCall extends AbstractCall
     /**
      * Wait for the server to send the status, and return it.
      *
-     * @return \stdClass The status object, with integer $code, string $details,
-     *                   and array $metadata members
+     * @return \stdClass The status object, with integer $code, string
+     *                   $details, and array $metadata members
      */
     public function getStatus()
     {
diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php
index 20db809ea3..c542f08872 100644
--- a/src/php/lib/Grpc/ClientStreamingCall.php
+++ b/src/php/lib/Grpc/ClientStreamingCall.php
@@ -35,8 +35,8 @@
 namespace Grpc;
 
 /**
- * Represents an active call that sends a stream of messages and then gets a
- * single response.
+ * Represents an active call that sends a stream of messages and then gets
+ * a single response.
  */
 class ClientStreamingCall extends AbstractCall
 {
@@ -44,8 +44,9 @@ class ClientStreamingCall extends AbstractCall
      * Start the call.
      *
      * @param array $metadata Metadata to send with the call, if applicable
+     *                        (optional)
      */
-    public function start($metadata = [])
+    public function start(array $metadata = [])
     {
         $this->call->startBatch([
             OP_SEND_INITIAL_METADATA => $metadata,
@@ -57,8 +58,8 @@ class ClientStreamingCall extends AbstractCall
      * wait is called.
      *
      * @param ByteBuffer $data    The data to write
-     * @param array      $options an array of options, possible keys:
-     *                            'flags' => a number
+     * @param array      $options An array of options, possible keys:
+     *                            'flags' => a number (optional)
      */
     public function write($data, array $options = [])
     {
diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php
index 5aeeafa94a..406512bf57 100644
--- a/src/php/lib/Grpc/ServerStreamingCall.php
+++ b/src/php/lib/Grpc/ServerStreamingCall.php
@@ -35,8 +35,8 @@
 namespace Grpc;
 
 /**
- * Represents an active call that sends a single message and then gets a stream
- * of responses.
+ * Represents an active call that sends a single message and then gets a
+ * stream of responses.
  */
 class ServerStreamingCall extends AbstractCall
 {
@@ -45,10 +45,11 @@ class ServerStreamingCall extends AbstractCall
      *
      * @param mixed $data     The data to send
      * @param array $metadata Metadata to send with the call, if applicable
-     * @param array $options  an array of options, possible keys:
-     *                        'flags' => a number
+     *                        (optional)
+     * @param array $options  An array of options, possible keys:
+     *                        'flags' => a number (optional)
      */
-    public function start($data, $metadata = [], $options = [])
+    public function start($data, array $metadata = [], array $options = [])
     {
         $message_array = ['message' => $this->serializeMessage($data)];
         if (array_key_exists('flags', $options)) {
@@ -82,8 +83,8 @@ class ServerStreamingCall extends AbstractCall
     /**
      * Wait for the server to send the status, and return it.
      *
-     * @return \stdClass The status object, with integer $code, string $details,
-     *                   and array $metadata members
+     * @return \stdClass The status object, with integer $code, string
+     *                   $details, and array $metadata members
      */
     public function getStatus()
     {
diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php
index e8eb6487a8..3c1cb158ea 100644
--- a/src/php/lib/Grpc/UnaryCall.php
+++ b/src/php/lib/Grpc/UnaryCall.php
@@ -35,8 +35,8 @@
 namespace Grpc;
 
 /**
- * Represents an active call that sends a single message and then gets a single
- * response.
+ * Represents an active call that sends a single message and then gets a
+ * single response.
  */
 class UnaryCall extends AbstractCall
 {
@@ -45,10 +45,11 @@ class UnaryCall extends AbstractCall
      *
      * @param mixed $data     The data to send
      * @param array $metadata Metadata to send with the call, if applicable
-     * @param array $options  an array of options, possible keys:
-     *                        'flags' => a number
+     *                        (optional)
+     * @param array $options  An array of options, possible keys:
+     *                        'flags' => a number (optional)
      */
-    public function start($data, $metadata = [], $options = [])
+    public function start($data, array $metadata = [], array $options = [])
     {
         $message_array = ['message' => $this->serializeMessage($data)];
         if (isset($options['flags'])) {
-- 
GitLab


From 3ad655099e41ae598e3041f18f3f28c106a60d3e Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 14 Dec 2016 18:28:07 +0100
Subject: [PATCH 142/344] fix building protoc artifacts on linux

---
 tools/dockerfile/grpc_artifact_protoc/Dockerfile | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/dockerfile/grpc_artifact_protoc/Dockerfile b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
index 1bbc6e021b..2904a8fa51 100644
--- a/tools/dockerfile/grpc_artifact_protoc/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
@@ -59,5 +59,11 @@ RUN yum install -y devtoolset-1.1 \
                    devtoolset-1.1-libstdc++-devel \
                    devtoolset-1.1-libstdc++-devel.i686 || true
 
+# Update Git to version >1.7 to allow cloning submodules with --reference arg.
+RUN yum remove -y git
+RUN yum install -y epel-release
+RUN yum install -y https://centos6.iuscommunity.org/ius-release.rpm
+RUN yum install -y git2u
+
 # Start in devtoolset environment that uses GCC 4.7
 CMD ["scl", "enable", "devtoolset-1.1", "bash"]
-- 
GitLab


From f1cdf59b7f5871c7e9523c5119dd100184521cd9 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 13 Dec 2016 13:26:47 -0800
Subject: [PATCH 143/344] Patch overlooked strings from Python un-namespacing

---
 src/python/grpcio_health_checking/MANIFEST.in           | 2 +-
 tools/distrib/python/grpcio_tools/MANIFEST.in           | 2 +-
 tools/distrib/python/grpcio_tools/grpc_tools/command.py | 2 +-
 tools/distrib/python/grpcio_tools/grpc_tools/protoc.py  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 7407f646d1..5255e4c403 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,4 +1,4 @@
 include grpc_version.py
 include health_commands.py
-graft grpc
+graft grpc_health
 global-exclude *.pyc
diff --git a/tools/distrib/python/grpcio_tools/MANIFEST.in b/tools/distrib/python/grpcio_tools/MANIFEST.in
index 7712834d64..11ce367747 100644
--- a/tools/distrib/python/grpcio_tools/MANIFEST.in
+++ b/tools/distrib/python/grpcio_tools/MANIFEST.in
@@ -2,6 +2,6 @@ include grpc_version.py
 include protoc_deps.py
 include protoc_lib_deps.py
 include README.rst
-graft grpc
+graft grpc_tools
 graft grpc_root
 graft third_party
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
index 43ec8c2a4c..31b3331a66 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
@@ -49,7 +49,7 @@ def build_package_protos(package_root):
 
   for proto_file in proto_files:
     command = [
-        'grpc.tools.protoc',
+        'grpc_tools.protoc',
         '--proto_path={}'.format(inclusion_root),
         '--proto_path={}'.format(well_known_protos_include),
         '--python_out={}'.format(inclusion_root),
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
index 7d5892dc4b..63fddb2f06 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
@@ -45,5 +45,5 @@ def main(command_arguments):
   return _protoc_compiler.run_main(command_arguments)
 
 if __name__ == '__main__':
-  proto_include = pkg_resources.resource_filename('grpc.tools', '_proto')
+  proto_include = pkg_resources.resource_filename('grpc_tools', '_proto')
   sys.exit(main(sys.argv + ['-I{}'.format(proto_include)]))
-- 
GitLab


From 94b82355cb07c5a8db4c0f797a1760b2addb451c Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 13 Dec 2016 13:26:47 -0800
Subject: [PATCH 144/344] Patch overlooked strings from Python un-namespacing

---
 src/python/grpcio_health_checking/MANIFEST.in           | 2 +-
 tools/distrib/python/grpcio_tools/MANIFEST.in           | 2 +-
 tools/distrib/python/grpcio_tools/grpc_tools/command.py | 2 +-
 tools/distrib/python/grpcio_tools/grpc_tools/protoc.py  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 7407f646d1..5255e4c403 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,4 +1,4 @@
 include grpc_version.py
 include health_commands.py
-graft grpc
+graft grpc_health
 global-exclude *.pyc
diff --git a/tools/distrib/python/grpcio_tools/MANIFEST.in b/tools/distrib/python/grpcio_tools/MANIFEST.in
index 7712834d64..11ce367747 100644
--- a/tools/distrib/python/grpcio_tools/MANIFEST.in
+++ b/tools/distrib/python/grpcio_tools/MANIFEST.in
@@ -2,6 +2,6 @@ include grpc_version.py
 include protoc_deps.py
 include protoc_lib_deps.py
 include README.rst
-graft grpc
+graft grpc_tools
 graft grpc_root
 graft third_party
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
index befb1284da..e490940e7f 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
@@ -45,7 +45,7 @@ def build_package_protos(package_root):
 
   for proto_file in proto_files:
     command = [
-        'grpc.tools.protoc',
+        'grpc_tools.protoc',
         '--proto_path={}'.format(inclusion_root),
         '--python_out={}'.format(inclusion_root),
         '--grpc_python_out={}'.format(inclusion_root),
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
index 7d5892dc4b..63fddb2f06 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
@@ -45,5 +45,5 @@ def main(command_arguments):
   return _protoc_compiler.run_main(command_arguments)
 
 if __name__ == '__main__':
-  proto_include = pkg_resources.resource_filename('grpc.tools', '_proto')
+  proto_include = pkg_resources.resource_filename('grpc_tools', '_proto')
   sys.exit(main(sys.argv + ['-I{}'.format(proto_include)]))
-- 
GitLab


From 9fb054a5377b97feb0ef6bf0d128a2c675e210d2 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 13 Dec 2016 13:32:17 -0800
Subject: [PATCH 145/344] Upversion Python

---
 build.yaml                                        | 2 +-
 src/python/grpcio/grpc_version.py                 | 2 +-
 src/python/grpcio_health_checking/grpc_version.py | 2 +-
 src/python/grpcio_tests/grpc_version.py           | 2 +-
 tools/distrib/python/grpcio_tools/grpc_version.py | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/build.yaml b/build.yaml
index 79bb8c9471..be77738002 100644
--- a/build.yaml
+++ b/build.yaml
@@ -7,7 +7,7 @@ settings:
   '#3': Use "-preN" suffixes to identify pre-release versions
   '#4': Per-language overrides are possible with (eg) ruby_version tag here
   '#5': See the expand_version.py for all the quirks here
-  python_version: 1.0.3
+  python_version: 1.0.4
   version: 1.0.1
 filegroups:
 - name: census
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 775ece397b..1c0183ee47 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION='1.0.3'
+VERSION='1.0.4'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 17ef5873f1..60e94ffcfa 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION='1.0.3'
+VERSION='1.0.4'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index c6226160b8..bdc1c36b70 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION='1.0.3'
+VERSION='1.0.4'
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index a96d2ef8b2..547a4b5ae2 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION='1.0.3'
+VERSION='1.0.4'
-- 
GitLab


From f8439141a0727d8ccb7b3ce61c368aa2fdb4ca68 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 12:36:39 -0800
Subject: [PATCH 146/344] clang-format

---
 src/core/ext/client_channel/client_channel_factory.c  | 8 ++++----
 src/core/ext/client_channel/http_connect_handshaker.c | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/core/ext/client_channel/client_channel_factory.c b/src/core/ext/client_channel/client_channel_factory.c
index 01eee02979..4eb35dfcf7 100644
--- a/src/core/ext/client_channel/client_channel_factory.c
+++ b/src/core/ext/client_channel/client_channel_factory.c
@@ -56,12 +56,12 @@ grpc_channel* grpc_client_channel_factory_create_channel(
                                                 args);
 }
 
-static void *factory_arg_copy(void *factory) {
+static void* factory_arg_copy(void* factory) {
   grpc_client_channel_factory_ref(factory);
   return factory;
 }
 
-static void factory_arg_destroy(void *factory) {
+static void factory_arg_destroy(void* factory) {
   // TODO(roth): Remove local exec_ctx when
   // https://github.com/grpc/grpc/pull/8705 is merged.
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -69,7 +69,7 @@ static void factory_arg_destroy(void *factory) {
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static int factory_arg_cmp(void *factory1, void *factory2) {
+static int factory_arg_cmp(void* factory1, void* factory2) {
   if (factory1 < factory2) return -1;
   if (factory1 > factory2) return 1;
   return 0;
@@ -79,7 +79,7 @@ static const grpc_arg_pointer_vtable factory_arg_vtable = {
     factory_arg_copy, factory_arg_destroy, factory_arg_cmp};
 
 grpc_arg grpc_client_channel_factory_create_channel_arg(
-    grpc_client_channel_factory *factory) {
+    grpc_client_channel_factory* factory) {
   grpc_arg arg;
   arg.type = GRPC_ARG_POINTER;
   arg.key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index cf10dfb3e9..76c78ee853 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -269,7 +269,7 @@ static void http_connect_handshaker_do_handshake(
   const grpc_arg* arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
-  char *canonical_uri =
+  char* canonical_uri =
       grpc_resolver_factory_add_default_prefix_if_needed(arg->value.string);
   grpc_uri* uri = grpc_uri_parse(canonical_uri, 1);
   char* server_name = uri->path;
-- 
GitLab


From 13f35746426b9dcca3d751b3f7f298859ae18936 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 14 Dec 2016 12:39:03 -0800
Subject: [PATCH 147/344] clang-format

---
 src/cpp/common/channel_filter.h         | 6 ++----
 test/cpp/common/channel_filter_test.cc  | 8 ++++----
 test/cpp/end2end/filter_end2end_test.cc | 2 +-
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index f4652cee77..c9f50df732 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -216,8 +216,7 @@ class TransportStreamOp {
 /// Represents channel data.
 class ChannelData {
  public:
-  virtual ~ChannelData() {
-  }
+  virtual ~ChannelData() {}
 
   /// Initializes the call data.
   virtual grpc_error *Init(grpc_exec_ctx *exec_ctx,
@@ -309,8 +308,7 @@ class ChannelFilter final {
   static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
                                      grpc_call_element_args *args) {
-    ChannelDataType *channel_data =
-        (ChannelDataType *)elem->channel_data;
+    ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data;
     // Construct the object in the already-allocated memory.
     CallDataType *call_data = new (elem->call_data) CallDataType();
     return call_data->Init(exec_ctx, channel_data, args);
diff --git a/test/cpp/common/channel_filter_test.cc b/test/cpp/common/channel_filter_test.cc
index 0859cc024b..32246a4b76 100644
--- a/test/cpp/common/channel_filter_test.cc
+++ b/test/cpp/common/channel_filter_test.cc
@@ -43,8 +43,8 @@ class MyChannelData : public ChannelData {
  public:
   MyChannelData() {}
 
-  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args)
-      override {
+  grpc_error* Init(grpc_exec_ctx* exec_ctx,
+                   grpc_channel_element_args* args) override {
     (void)args->channel_args;  // Make sure field is available.
     return GRPC_ERROR_NONE;
   }
@@ -54,8 +54,8 @@ class MyCallData : public CallData {
  public:
   MyCallData() {}
 
-  grpc_error *Init(grpc_exec_ctx *exec_ctx, ChannelData *channel_data,
-                   grpc_call_element_args *args) override {
+  grpc_error* Init(grpc_exec_ctx* exec_ctx, ChannelData* channel_data,
+                   grpc_call_element_args* args) override {
     (void)args->path;  // Make sure field is available.
     return GRPC_ERROR_NONE;
   }
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index 28bd6baab8..bd384f68b4 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -114,7 +114,7 @@ int GetCallCounterValue() {
 
 class ChannelDataImpl : public ChannelData {
  public:
-  grpc_error *Init(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) {
+  grpc_error* Init(grpc_exec_ctx* exec_ctx, grpc_channel_element_args* args) {
     IncrementConnectionCounter();
     return GRPC_ERROR_NONE;
   }
-- 
GitLab


From a84cdb8c81253f48fcf7f913ec71d0c7b8e1241e Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Mon, 29 Aug 2016 16:28:53 -0700
Subject: [PATCH 148/344] Add parse, tobinary, totext commands

---
 test/cpp/util/grpc_tool.cc      | 140 +++++++++++++++++++++++++++++---
 test/cpp/util/grpc_tool_test.cc |  50 ++++++++++++
 2 files changed, 179 insertions(+), 11 deletions(-)

diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc
index a3da5682dc..b9900ca1b7 100644
--- a/test/cpp/util/grpc_tool.cc
+++ b/test/cpp/util/grpc_tool.cc
@@ -86,11 +86,12 @@ class GrpcTool {
   // callback);
   // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback
   // callback);
-  // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback
-  // callback);
-  // bool ToText(int argc, const char** argv, GrpcToolOutputCallback callback);
-  // bool ToBinary(int argc, const char** argv, GrpcToolOutputCallback
-  // callback);
+  bool ParseMessage(int argc, const char** argv, const CliCredentials& cred,
+                    GrpcToolOutputCallback callback);
+  bool ToText(int argc, const char** argv, const CliCredentials& cred,
+              GrpcToolOutputCallback callback);
+  bool ToBinary(int argc, const char** argv, const CliCredentials& cred,
+                GrpcToolOutputCallback callback);
 
   void SetPrintCommandMode(int exit_status) {
     print_command_usage_ = true;
@@ -173,9 +174,9 @@ const Command ops[] = {
     {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3},
     {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3},
     {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2},
-    // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
-    // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
-    // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
+    {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
+    {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
+    {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
 };
 
 void Usage(const grpc::string& msg) {
@@ -185,9 +186,9 @@ void Usage(const grpc::string& msg) {
       "  grpc_cli ls ...         ; List services\n"
       "  grpc_cli call ...       ; Call method\n"
       "  grpc_cli type ...       ; Print type\n"
-      // "  grpc_cli parse ...      ; Parse message\n"
-      // "  grpc_cli totext ...     ; Convert binary message to text\n"
-      // "  grpc_cli tobinary ...   ; Convert text message to binary\n"
+      "  grpc_cli parse ...      ; Parse message\n"
+      "  grpc_cli totext ...     ; Convert binary message to text\n"
+      "  grpc_cli tobinary ...   ; Convert text message to binary\n"
       "  grpc_cli help ...       ; Print this message, or per-command usage\n"
       "\n",
       msg.c_str());
@@ -496,5 +497,122 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
   return callback(output_ss.str());
 }
 
+bool GrpcTool::ParseMessage(int argc, const char** argv,
+                            const CliCredentials& cred,
+                            GrpcToolOutputCallback callback) {
+  CommandUsage(
+      "Parse message\n"
+      "  grpc_cli parse <address> <type> [<message>]\n"
+      "    <address>                ; host:port\n"
+      "    <type>                   ; Protocol buffer type name\n"
+      "    <message>                ; Text protobuffer (overrides --infile)\n"
+      "    --protofiles             ; Comma separated proto files used as a"
+      " fallback when parsing request/response\n"
+      "    --proto_path             ; The search path of proto files, valid"
+      " only when --protofiles is given\n"
+      "    --infile                 ; Input filename (defaults to stdin)\n"
+      "    --outfile                ; Output filename (defaults to stdout)\n"
+      "    --binary_input           ; Input in binary format\n"
+      "    --binary_output          ; Output in binary format\n" +
+      cred.GetCredentialUsage());
+
+  std::stringstream output_ss;
+  grpc::string message_text;
+  grpc::string server_address(argv[0]);
+  grpc::string type_name(argv[1]);
+  std::unique_ptr<grpc::testing::ProtoFileParser> parser;
+  grpc::string serialized_request_proto;
+
+  if (argc == 3) {
+    message_text = argv[2];
+    if (!FLAGS_infile.empty()) {
+      fprintf(stderr, "warning: message given in argv, ignoring --infile.\n");
+    }
+  } else {
+    std::stringstream input_stream;
+    if (FLAGS_infile.empty()) {
+      if (isatty(STDIN_FILENO)) {
+        fprintf(stderr, "reading request message from stdin...\n");
+      }
+      input_stream << std::cin.rdbuf();
+    } else {
+      std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary);
+      input_stream << input_file.rdbuf();
+      input_file.close();
+    }
+    message_text = input_stream.str();
+  }
+
+  if (!FLAGS_binary_input || !FLAGS_binary_output) {
+    std::shared_ptr<grpc::Channel> channel =
+        grpc::CreateChannel(server_address, cred.GetCredentials());
+    parser.reset(
+        new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr,
+                                           FLAGS_proto_path, FLAGS_protofiles));
+    if (parser->HasError()) {
+      return false;
+    }
+  }
+
+  if (FLAGS_binary_input) {
+    serialized_request_proto = message_text;
+  } else {
+    serialized_request_proto =
+        parser->GetSerializedProtoFromMessageType(type_name, message_text);
+    if (parser->HasError()) {
+      return false;
+    }
+  }
+
+  if (FLAGS_binary_output) {
+    output_ss << serialized_request_proto;
+  } else {
+    grpc::string output_text = parser->GetTextFormatFromMessageType(
+        type_name, serialized_request_proto);
+    if (parser->HasError()) {
+      return false;
+    }
+    output_ss << output_text << std::endl;
+  }
+
+  return callback(output_ss.str());
+}
+
+bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred,
+                      GrpcToolOutputCallback callback) {
+  CommandUsage(
+      "Convert binary message to text\n"
+      "  grpc_cli totext <protofiles> <type>\n"
+      "    <protofiles>             ; Comma separated list of proto files\n"
+      "    <type>                   ; Protocol buffer type name\n"
+      "    --proto_path             ; The search path of proto files\n"
+      "    --infile                 ; Input filename (defaults to stdin)\n"
+      "    --outfile                ; Output filename (defaults to stdout)\n");
+
+  FLAGS_protofiles = argv[0];
+  FLAGS_remotedb = false;
+  FLAGS_binary_input = true;
+  FLAGS_binary_output = false;
+  return ParseMessage(argc, argv, cred, callback);
+}
+
+bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred,
+                        GrpcToolOutputCallback callback) {
+  CommandUsage(
+      "Convert text message to binary\n"
+      "  grpc_cli tobinary <protofiles> <type> [<message>]\n"
+      "    <protofiles>             ; Comma separated list of proto files\n"
+      "    <type>                   ; Protocol buffer type name\n"
+      "    --proto_path             ; The search path of proto files\n"
+      "    --infile                 ; Input filename (defaults to stdin)\n"
+      "    --outfile                ; Output filename (defaults to stdout)\n");
+
+  FLAGS_protofiles = argv[0];
+  FLAGS_remotedb = false;
+  FLAGS_binary_input = false;
+  FLAGS_binary_output = true;
+  return ParseMessage(argc, argv, cred, callback);
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
index 1ff8172306..33ce611a60 100644
--- a/test/cpp/util/grpc_tool_test.cc
+++ b/test/cpp/util/grpc_tool_test.cc
@@ -86,9 +86,18 @@ using grpc::testing::EchoResponse;
   "  rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
   "{}\n"
 
+#define ECHO_RESPONSE_MESSAGE \
+  "message: \"echo\"\n"       \
+  "param {\n"                 \
+  "  host: \"localhost\"\n"   \
+  "  peer: \"peer\"\n"        \
+  "}\n\n"
+
 namespace grpc {
 namespace testing {
 
+DECLARE_bool(binary_input);
+DECLARE_bool(binary_output);
 DECLARE_bool(l);
 
 namespace {
@@ -338,6 +347,47 @@ TEST_F(GrpcToolTest, CallCommand) {
   ShutdownServer();
 }
 
+TEST_F(GrpcToolTest, ParseCommand) {
+  // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
+  // ECHO_RESPONSE_MESSAGE"
+  std::stringstream output_stream;
+  std::stringstream binary_output_stream;
+
+  const grpc::string server_address = SetUpServer();
+  const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
+                        "grpc.testing.EchoResponse", ECHO_RESPONSE_MESSAGE};
+
+  FLAGS_binary_input = false;
+  FLAGS_binary_output = false;
+  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+                                   std::bind(PrintStream, &output_stream,
+                                             std::placeholders::_1)));
+  // Expected output: ECHO_RESPONSE_MESSAGE
+  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
+
+  // Parse text message to binary message and then parse it back to text message
+  output_stream.str(grpc::string());
+  output_stream.clear();
+  FLAGS_binary_output = true;
+  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+                                   std::bind(PrintStream, &output_stream,
+                                             std::placeholders::_1)));
+  grpc::string binary_data = output_stream.str();
+  output_stream.str(grpc::string());
+  output_stream.clear();
+  argv[4] = binary_data.c_str();
+  FLAGS_binary_input = true;
+  FLAGS_binary_output = false;
+  EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(),
+                                   std::bind(PrintStream, &output_stream,
+                                             std::placeholders::_1)));
+
+  // Expected output: ECHO_RESPONSE_MESSAGE
+  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
+
+  ShutdownServer();
+}
+
 TEST_F(GrpcToolTest, TooFewArguments) {
   // Test input "grpc_cli call Echo"
   std::stringstream output_stream;
-- 
GitLab


From 5e43db8d8f1036904ca1343f4499a20f7188e7c4 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Wed, 14 Dec 2016 18:23:25 -0800
Subject: [PATCH 149/344] Fix Python setup-time diagnostic

---
 setup.py | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/setup.py b/setup.py
index 559a75f674..ab217433a3 100644
--- a/setup.py
+++ b/setup.py
@@ -218,15 +218,18 @@ SETUP_REQUIRES = INSTALL_REQUIRES + (
     'six>=1.10',
   ) if ENABLE_DOCUMENTATION_BUILD else ()
 
-if BUILD_WITH_CYTHON:
-  sys.stderr.write(
-    "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, "
-    "but do not have Cython installed. We won't stop you from using "
-    "other commands, but the extension files will fail to build.\n")
-elif need_cython:
-  sys.stderr.write(
-      'We could not find Cython. Setup may take 10-20 minutes.\n')
-  SETUP_REQUIRES += ('cython>=0.23',)
+try:
+  import Cython
+except ImportError:
+  if BUILD_WITH_CYTHON:
+    sys.stderr.write(
+      "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, "
+      "but do not have Cython installed. We won't stop you from using "
+      "other commands, but the extension files will fail to build.\n")
+  elif need_cython:
+    sys.stderr.write(
+        'We could not find Cython. Setup may take 10-20 minutes.\n')
+    SETUP_REQUIRES += ('cython>=0.23',)
 
 COMMAND_CLASS = {
     'doc': commands.SphinxDocumentation,
-- 
GitLab


From 4682bf392860f3b77351cf7221d04b20a656c68a Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Wed, 14 Dec 2016 18:42:03 -0800
Subject: [PATCH 150/344] Diagnose  AttrErr as too-old setuptools

---
 src/python/grpcio/support.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/python/grpcio/support.py b/src/python/grpcio/support.py
index f363f5fdc5..b226e690fd 100644
--- a/src/python/grpcio/support.py
+++ b/src/python/grpcio/support.py
@@ -100,9 +100,15 @@ def diagnose_compile_error(build_ext, error):
             .format(source)
           )
 
+def diagnose_attribute_error(build_ext, error):
+  if any('_needs_stub' in arg for arg in error.args):
+    raise commands.CommandError(
+        "We expect a missing `_needs_stub` attribute from older versions of "
+        "setuptools. Consider upgrading setuptools.")
 
 _ERROR_DIAGNOSES = {
-    errors.CompileError: diagnose_compile_error
+    errors.CompileError: diagnose_compile_error,
+    AttributeError: diagnose_attribute_error
 }
 
 def diagnose_build_ext_error(build_ext, error, formatted):
-- 
GitLab


From 61b8c8920698b949872480540912ba2bf022c9df Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Wed, 7 Dec 2016 15:28:35 -0800
Subject: [PATCH 151/344] Add check on return value from start_client_batch

---
 src/python/grpcio/grpc/_channel.py            |  46 ++++-
 src/python/grpcio_tests/tests/tests.json      |   1 +
 .../tests/unit/_invalid_metadata_test.py      | 179 ++++++++++++++++++
 3 files changed, 220 insertions(+), 6 deletions(-)
 create mode 100644 src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py

diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 3ac735a4ec..1298cfbb6f 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -99,6 +99,22 @@ def _wait_once_until(condition, until):
     else:
       condition.wait(timeout=remaining)
 
+_INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
+    'Internal gRPC call error %d. ' +
+    'Please report to https://github.com/grpc/grpc/issues')
+
+def _check_call_error(call_error, metadata):
+  if call_error == cygrpc.CallError.invalid_metadata:
+    raise ValueError('metadata was invalid: %s' % metadata)
+  elif call_error != cygrpc.CallError.ok:
+    raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+
+def _call_error_set_RPCstate(state, call_error, metadata):
+  if call_error == cygrpc.CallError.invalid_metadata:
+    _abort(state, grpc.StatusCode.INTERNAL, 'metadata was invalid: %s' % metadata)
+  else:
+    _abort(state, grpc.StatusCode.INTERNAL, 
+        _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
 
 class _RPCState(object):
 
@@ -472,7 +488,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
           None, 0, completion_queue, self._method, None, deadline_timespec)
       if credentials is not None:
         call.set_credentials(credentials._credentials)
-      call.start_client_batch(cygrpc.Operations(operations), None)
+      call_error = call.start_client_batch(cygrpc.Operations(operations), None)
+      _check_call_error(call_error, metadata)
       _handle_event(completion_queue.poll(), state, self._response_deserializer)
       return state, deadline
 
@@ -496,7 +513,11 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
         call.set_credentials(credentials._credentials)
       event_handler = _event_handler(state, call, self._response_deserializer)
       with state.condition:
-        call.start_client_batch(cygrpc.Operations(operations), event_handler)
+        call_error = call.start_client_batch(cygrpc.Operations(operations),
+            event_handler)
+        if call_error != cygrpc.CallError.ok:
+          _call_error_set_RPCstate(state, call_error, metadata)
+          return _Rendezvous(state, None, None, deadline)
         drive_call()
       return _Rendezvous(state, call, self._response_deserializer, deadline)
 
@@ -536,7 +557,11 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
             cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
             cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
         )
-        call.start_client_batch(cygrpc.Operations(operations), event_handler)
+        call_error = call.start_client_batch(cygrpc.Operations(operations),
+            event_handler)
+        if call_error != cygrpc.CallError.ok:
+          _call_error_set_RPCstate(state, call_error, metadata)
+          return _Rendezvous(state, None, None, deadline)
         drive_call()
       return _Rendezvous(state, call, self._response_deserializer, deadline)
 
@@ -571,7 +596,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
           cygrpc.operation_receive_message(_EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
-      call.start_client_batch(cygrpc.Operations(operations), None)
+      call_error = call.start_client_batch(cygrpc.Operations(operations), None)
+      _check_call_error(call_error, metadata)
       _consume_request_iterator(
           request_iterator, state, call, self._request_serializer)
     while True:
@@ -615,7 +641,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
           cygrpc.operation_receive_message(_EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
-      call.start_client_batch(cygrpc.Operations(operations), event_handler)
+      call_error = call.start_client_batch(cygrpc.Operations(operations),
+          event_handler)
+      if call_error != cygrpc.CallError.ok:
+        _call_error_set_RPCstate(state, call_error, metadata)
+        return _Rendezvous(state, None, None, deadline)
       drive_call()
       _consume_request_iterator(
           request_iterator, state, call, self._request_serializer)
@@ -652,7 +682,11 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
               _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
-      call.start_client_batch(cygrpc.Operations(operations), event_handler)
+      call_error = call.start_client_batch(cygrpc.Operations(operations),
+          event_handler)
+      if call_error != cygrpc.CallError.ok:
+        _call_error_set_RPCstate(state, call_error, metadata)
+        return _Rendezvous(state, None, None, deadline)
       drive_call()
       _consume_request_iterator(
           request_iterator, state, call, self._request_serializer)
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index d0cf2b5779..0eea66da40 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -25,6 +25,7 @@
   "_implementations_test.CallCredentialsTest",
   "_implementations_test.ChannelCredentialsTest",
   "_insecure_interop_test.InsecureInteropTest",
+  "_invalid_metadata_test.InvalidMetadataTest"
   "_logging_pool_test.LoggingPoolTest",
   "_metadata_code_details_test.MetadataCodeDetailsTest",
   "_metadata_test.MetadataTest",
diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
new file mode 100644
index 0000000000..0411c58900
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -0,0 +1,179 @@
+# Copyright 2016, 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 of RPCs made against gRPC Python's application-layer API."""
+
+import unittest
+
+import grpc
+
+from tests.unit.framework.common import test_constants
+
+_SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
+_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
+_SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
+_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
+
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
+
+
+def _unary_unary_multi_callable(channel):
+  return channel.unary_unary(_UNARY_UNARY)
+
+
+def _unary_stream_multi_callable(channel):
+  return channel.unary_stream(
+      _UNARY_STREAM,
+      request_serializer=_SERIALIZE_REQUEST,
+      response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_unary_multi_callable(channel):
+  return channel.stream_unary(
+      _STREAM_UNARY,
+      request_serializer=_SERIALIZE_REQUEST,
+      response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_stream_multi_callable(channel):
+  return channel.stream_stream(_STREAM_STREAM)
+
+
+class InvalidMetadataTest(unittest.TestCase):
+
+  def setUp(self):
+    self._channel = grpc.insecure_channel('localhost:8080')
+    self._unary_unary = _unary_unary_multi_callable(self._channel)
+    self._unary_stream = _unary_stream_multi_callable(self._channel)
+    self._stream_unary = _stream_unary_multi_callable(self._channel)
+    self._stream_stream = _stream_stream_multi_callable(self._channel)
+
+  def testUnaryRequestBlockingUnaryResponse(self):
+    request = b'\x07\x08'
+    metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    with self.assertRaises(ValueError) as exception_context:
+      self._unary_unary(request, metadata=metadata)
+    self.assertEqual(
+        expected_error_details, exception_context.exception.message)
+
+  def testUnaryRequestBlockingUnaryResponseWithCall(self):
+    request = b'\x07\x08'
+    metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponseWithCall'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    with self.assertRaises(ValueError) as exception_context:
+      self._unary_unary.with_call(request, metadata=metadata)
+    self.assertEqual(
+        expected_error_details, exception_context.exception.message)
+
+  def testUnaryRequestFutureUnaryResponse(self):
+    request = b'\x07\x08'
+    metadata = (('InVaLiD', 'UnaryRequestFutureUnaryResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    response_future = self._unary_unary.future(request, metadata=metadata)
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertEqual(
+        exception_context.exception.details(), expected_error_details)
+    self.assertEqual(
+        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
+    self.assertEqual(response_future.details(), expected_error_details)
+    self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+
+  def testUnaryRequestStreamResponse(self):
+    request = b'\x37\x58'
+    metadata = (('InVaLiD', 'UnaryRequestStreamResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    response_iterator = self._unary_stream(request, metadata=metadata)
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      next(response_iterator)
+    self.assertEqual(
+        exception_context.exception.details(), expected_error_details)
+    self.assertEqual(
+        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
+    self.assertEqual(response_iterator.details(), expected_error_details)
+    self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+
+  def testStreamRequestBlockingUnaryResponse(self):
+    request_iterator = (b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    with self.assertRaises(ValueError) as exception_context:
+      self._stream_unary(request_iterator, metadata=metadata)
+    self.assertEqual(
+        expected_error_details, exception_context.exception.message)
+
+  def testStreamRequestBlockingUnaryResponseWithCall(self):
+    request_iterator = (
+        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponseWithCall'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self.assertRaises(ValueError) as exception_context:
+      multi_callable.with_call(request_iterator, metadata=metadata)
+    self.assertEqual(
+        expected_error_details, exception_context.exception.message)
+
+  def testStreamRequestFutureUnaryResponse(self):
+    request_iterator = (
+        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    metadata = (('InVaLiD', 'StreamRequestFutureUnaryResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    response_future = self._stream_unary.future(
+        request_iterator, metadata=metadata)
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertEqual(
+        exception_context.exception.details(), expected_error_details)
+    self.assertEqual(
+        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
+    self.assertEqual(response_future.details(), expected_error_details)
+    self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+
+  def testStreamRequestStreamResponse(self):
+    request_iterator = (
+        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    metadata = (('InVaLiD', 'StreamRequestStreamResponse'),)
+    expected_error_details = "metadata was invalid: %s" % metadata
+    response_iterator = self._stream_stream(request_iterator, metadata=metadata)
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      next(response_iterator)
+    self.assertEqual(
+        exception_context.exception.details(), expected_error_details)
+    self.assertEqual(
+        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
+    self.assertEqual(response_iterator.details(), expected_error_details)
+    self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
-- 
GitLab


From 15521de93fc0a9feb2e1a555d249d8fd070ec9ab Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Thu, 17 Nov 2016 20:39:27 -0800
Subject: [PATCH 152/344] Request a pollset_set in grpc_resolve_address

---
 .../ext/resolver/dns/native/dns_resolver.c    |  1 +
 src/core/lib/http/httpcli.c                   |  1 +
 src/core/lib/iomgr/resolve_address.h          |  2 +
 src/core/lib/iomgr/resolve_address_posix.c    |  9 ++-
 src/core/lib/iomgr/resolve_address_uv.c       |  9 ++-
 test/core/end2end/fuzzers/api_fuzzer.c        |  4 +-
 test/core/iomgr/resolve_address_test.c        | 74 ++++++++++++++++---
 7 files changed, 82 insertions(+), 18 deletions(-)

diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index a7392e14ad..688c4fa845 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -218,6 +218,7 @@ static void dns_start_resolving_locked(grpc_exec_ctx *exec_ctx,
   r->resolving = true;
   r->addresses = NULL;
   grpc_resolve_address(exec_ctx, r->name_to_resolve, r->default_port,
+                       r->base.pollset_set,
                        grpc_closure_create(dns_on_resolved, r), &r->addresses);
 }
 
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index fdb8abaa2d..1035f31109 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -278,6 +278,7 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
   grpc_polling_entity_add_to_pollset_set(exec_ctx, req->pollent,
                                          req->context->pollset_set);
   grpc_resolve_address(exec_ctx, request->host, req->handshaker->default_port,
+                       req->context->pollset_set,
                        grpc_closure_create(on_resolved, req), &req->addresses);
 }
 
diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h
index 275924448a..e03d16fa4e 100644
--- a/src/core/lib/iomgr/resolve_address.h
+++ b/src/core/lib/iomgr/resolve_address.h
@@ -36,6 +36,7 @@
 
 #include <stddef.h>
 #include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/pollset_set.h"
 
 #define GRPC_MAX_SOCKADDR_SIZE 128
 
@@ -54,6 +55,7 @@ typedef struct {
 /* TODO(ctiller): add a timeout here */
 extern void (*grpc_resolve_address)(grpc_exec_ctx *exec_ctx, const char *addr,
                                     const char *default_port,
+                                    grpc_pollset_set *interested_parties,
                                     grpc_closure *on_done,
                                     grpc_resolved_addresses **addresses);
 /* Destroy resolved addresses */
diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c
index de791b2b67..821932e562 100644
--- a/src/core/lib/iomgr/resolve_address_posix.c
+++ b/src/core/lib/iomgr/resolve_address_posix.c
@@ -181,6 +181,7 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
 
 static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  const char *default_port,
+                                 grpc_pollset_set *interested_parties,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addrs) {
   request *r = gpr_malloc(sizeof(request));
@@ -192,9 +193,9 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
   grpc_executor_push(&r->request_closure, GRPC_ERROR_NONE);
 }
 
-void (*grpc_resolve_address)(grpc_exec_ctx *exec_ctx, const char *name,
-                             const char *default_port, grpc_closure *on_done,
-                             grpc_resolved_addresses **addrs) =
-    resolve_address_impl;
+void (*grpc_resolve_address)(
+    grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
+    grpc_pollset_set *interested_parties, grpc_closure *on_done,
+    grpc_resolved_addresses **addrs) = resolve_address_impl;
 
 #endif
diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c
index b8295acfa1..3269c4f09f 100644
--- a/src/core/lib/iomgr/resolve_address_uv.c
+++ b/src/core/lib/iomgr/resolve_address_uv.c
@@ -181,6 +181,7 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
 
 static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  const char *default_port,
+                                 grpc_pollset_set *interested_parties,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addrs) {
   uv_getaddrinfo_t *req;
@@ -223,9 +224,9 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
   }
 }
 
-void (*grpc_resolve_address)(grpc_exec_ctx *exec_ctx, const char *name,
-                             const char *default_port, grpc_closure *on_done,
-                             grpc_resolved_addresses **addrs) =
-    resolve_address_impl;
+void (*grpc_resolve_address)(
+    grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
+    grpc_pollset_set *interested_parties, grpc_closure *on_done,
+    grpc_resolved_addresses **addrs) = resolve_address_impl;
 
 #endif /* GRPC_UV */
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 19ac6ced14..746134c85b 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -361,7 +361,9 @@ static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
 }
 
 void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
-                        const char *default_port, grpc_closure *on_done,
+                        const char *default_port,
+                        grpc_pollset_set *interested_parties,
+                        grpc_closure *on_done,
                         grpc_resolved_addresses **addresses) {
   addr_req *r = gpr_malloc(sizeof(*r));
   r->addr = gpr_strdup(addr);
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 2dd0d88b3f..2f533137d8 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -34,6 +34,7 @@
 #include "src/core/lib/iomgr/resolve_address.h"
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr.h"
@@ -46,16 +47,64 @@ static gpr_timespec test_deadline(void) {
 typedef struct args_struct {
   gpr_event ev;
   grpc_resolved_addresses *addrs;
+  gpr_atm done_atm;
+  gpr_mu *mu;
+  grpc_pollset *pollset;
+  grpc_pollset_set *pollset_set;
 } args_struct;
 
 void args_init(args_struct *args) {
   gpr_event_init(&args->ev);
+  grpc_pollset_init(args->pollset, &args->mu);
+  args->pollset_set = grpc_pollset_set_create();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_pollset_set_add_pollset(&exec_ctx, args->pollset_set, args->pollset);
+  grpc_exec_ctx_finish(&exec_ctx);
   args->addrs = NULL;
 }
 
 void args_finish(args_struct *args) {
   GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
   grpc_resolved_addresses_destroy(args->addrs);
+  grpc_pollset_set_destroy(args->pollset_set);
+  grpc_pollset_destroy(args->pollset);
+}
+
+static gpr_timespec n_sec_deadline(int seconds) {
+  return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                      gpr_time_from_seconds(seconds, GPR_TIMESPAN));
+}
+
+static void actually_poll(void *argsp) {
+  args_struct *args = argsp;
+  gpr_timespec deadline = n_sec_deadline(10);
+  grpc_pollset_worker *worker = NULL;
+  while (true) {
+    bool done = gpr_atm_acq_load(&args->done_atm) != 0;
+    if (done) {
+      break;
+    }
+    gpr_timespec time_left =
+        gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
+    gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done,
+            time_left.tv_sec, time_left.tv_nsec);
+    GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0);
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    gpr_mu_lock(args->mu);
+    GRPC_LOG_IF_ERROR(
+        "pollset_work",
+        grpc_pollset_work(&exec_ctx, args->pollset, &worker,
+                          gpr_now(GPR_CLOCK_REALTIME), n_sec_deadline(1)));
+    gpr_mu_unlock(args->mu);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
+  gpr_event_set(&args->ev, (void *)1);
+}
+
+static void poll_pollset_until_request_done(args_struct *args) {
+  gpr_atm_rel_store(&args->done_atm, 0);
+  gpr_thd_id id;
+  gpr_thd_new(&id, actually_poll, args, NULL);
 }
 
 static void must_succeed(grpc_exec_ctx *exec_ctx, void *argsp,
@@ -64,20 +113,21 @@ static void must_succeed(grpc_exec_ctx *exec_ctx, void *argsp,
   GPR_ASSERT(err == GRPC_ERROR_NONE);
   GPR_ASSERT(args->addrs != NULL);
   GPR_ASSERT(args->addrs->naddrs > 0);
-  gpr_event_set(&args->ev, (void *)1);
+  gpr_atm_rel_store(&args->done_atm, 1);
 }
 
 static void must_fail(grpc_exec_ctx *exec_ctx, void *argsp, grpc_error *err) {
   args_struct *args = argsp;
   GPR_ASSERT(err != GRPC_ERROR_NONE);
-  gpr_event_set(&args->ev, (void *)1);
+  gpr_atm_rel_store(&args->done_atm, 1);
 }
 
 static void test_localhost(void) {
   args_struct args;
   args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resolve_address(&exec_ctx, "localhost:1", NULL,
+  poll_pollset_until_request_done(&args);
+  grpc_resolve_address(&exec_ctx, "localhost:1", NULL, args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
   grpc_exec_ctx_finish(&exec_ctx);
   args_finish(&args);
@@ -87,7 +137,8 @@ static void test_default_port(void) {
   args_struct args;
   args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resolve_address(&exec_ctx, "localhost", "1",
+  poll_pollset_until_request_done(&args);
+  grpc_resolve_address(&exec_ctx, "localhost", "1", args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
   grpc_exec_ctx_finish(&exec_ctx);
   args_finish(&args);
@@ -97,7 +148,8 @@ static void test_missing_default_port(void) {
   args_struct args;
   args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resolve_address(&exec_ctx, "localhost", NULL,
+  poll_pollset_until_request_done(&args);
+  grpc_resolve_address(&exec_ctx, "localhost", NULL, args.pollset_set,
                        grpc_closure_create(must_fail, &args), &args.addrs);
   grpc_exec_ctx_finish(&exec_ctx);
   args_finish(&args);
@@ -107,7 +159,8 @@ static void test_ipv6_with_port(void) {
   args_struct args;
   args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resolve_address(&exec_ctx, "[2001:db8::1]:1", NULL,
+  poll_pollset_until_request_done(&args);
+  grpc_resolve_address(&exec_ctx, "[2001:db8::1]:1", NULL, args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
   grpc_exec_ctx_finish(&exec_ctx);
   args_finish(&args);
@@ -122,7 +175,8 @@ static void test_ipv6_without_port(void) {
     args_struct args;
     args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_resolve_address(&exec_ctx, kCases[i], "80",
+    poll_pollset_until_request_done(&args);
+    grpc_resolve_address(&exec_ctx, kCases[i], "80", args.pollset_set,
                          grpc_closure_create(must_succeed, &args), &args.addrs);
     grpc_exec_ctx_finish(&exec_ctx);
     args_finish(&args);
@@ -138,7 +192,8 @@ static void test_invalid_ip_addresses(void) {
     args_struct args;
     args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_resolve_address(&exec_ctx, kCases[i], NULL,
+    poll_pollset_until_request_done(&args);
+    grpc_resolve_address(&exec_ctx, kCases[i], NULL, args.pollset_set,
                          grpc_closure_create(must_fail, &args), &args.addrs);
     grpc_exec_ctx_finish(&exec_ctx);
     args_finish(&args);
@@ -154,7 +209,8 @@ static void test_unparseable_hostports(void) {
     args_struct args;
     args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_resolve_address(&exec_ctx, kCases[i], "1",
+    poll_pollset_until_request_done(&args);
+    grpc_resolve_address(&exec_ctx, kCases[i], "1", args.pollset_set,
                          grpc_closure_create(must_fail, &args), &args.addrs);
     grpc_exec_ctx_finish(&exec_ctx);
     args_finish(&args);
-- 
GitLab


From f62706f2060a029ff9eaf178fc32946f7feda3c3 Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Thu, 17 Nov 2016 20:59:48 -0800
Subject: [PATCH 153/344] Add pollset_set in grpc_resolver

---
 src/core/ext/client_channel/resolver.c | 2 ++
 src/core/ext/client_channel/resolver.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/src/core/ext/client_channel/resolver.c b/src/core/ext/client_channel/resolver.c
index 2ae4fe862e..4a5e4f751b 100644
--- a/src/core/ext/client_channel/resolver.c
+++ b/src/core/ext/client_channel/resolver.c
@@ -36,6 +36,7 @@
 void grpc_resolver_init(grpc_resolver *resolver,
                         const grpc_resolver_vtable *vtable) {
   resolver->vtable = vtable;
+  resolver->pollset_set = grpc_pollset_set_create();
   gpr_ref_init(&resolver->refs, 1);
 }
 
@@ -62,6 +63,7 @@ void grpc_resolver_unref(grpc_resolver *resolver,
 void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
 #endif
   if (gpr_unref(&resolver->refs)) {
+    grpc_pollset_set_destroy(resolver->pollset_set);
     resolver->vtable->destroy(exec_ctx, resolver);
   }
 }
diff --git a/src/core/ext/client_channel/resolver.h b/src/core/ext/client_channel/resolver.h
index 96ece92b9d..d283120648 100644
--- a/src/core/ext/client_channel/resolver.h
+++ b/src/core/ext/client_channel/resolver.h
@@ -36,6 +36,7 @@
 
 #include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/pollset_set.h"
 
 typedef struct grpc_resolver grpc_resolver;
 typedef struct grpc_resolver_vtable grpc_resolver_vtable;
@@ -43,6 +44,7 @@ typedef struct grpc_resolver_vtable grpc_resolver_vtable;
 /** \a grpc_resolver provides \a grpc_channel_args objects to its caller */
 struct grpc_resolver {
   const grpc_resolver_vtable *vtable;
+  grpc_pollset_set *pollset_set;
   gpr_refcount refs;
 };
 
-- 
GitLab


From b4080a2e947b7a063769a879ad121854a9587071 Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Thu, 17 Nov 2016 22:03:56 -0800
Subject: [PATCH 154/344] Fix resolve_address_test

---
 test/core/iomgr/resolve_address_test.c | 63 +++++++++++++++-----------
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 2f533137d8..1e9e6abb2a 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -32,6 +32,7 @@
  */
 
 #include "src/core/lib/iomgr/resolve_address.h"
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
@@ -53,21 +54,29 @@ typedef struct args_struct {
   grpc_pollset_set *pollset_set;
 } args_struct;
 
-void args_init(args_struct *args) {
+static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
+
+void args_init(grpc_exec_ctx *exec_ctx, args_struct *args) {
   gpr_event_init(&args->ev);
+  args->pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(args->pollset, &args->mu);
   args->pollset_set = grpc_pollset_set_create();
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_pollset_set_add_pollset(&exec_ctx, args->pollset_set, args->pollset);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_pollset_set_add_pollset(exec_ctx, args->pollset_set, args->pollset);
   args->addrs = NULL;
 }
 
-void args_finish(args_struct *args) {
+void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) {
   GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
   grpc_resolved_addresses_destroy(args->addrs);
+  grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset);
   grpc_pollset_set_destroy(args->pollset_set);
+  grpc_closure do_nothing_cb;
+  grpc_closure_init(&do_nothing_cb, do_nothing, NULL);
+  grpc_pollset_shutdown(exec_ctx, args->pollset, &do_nothing_cb);
+  // exec_ctx needs to be flushed before calling grpc_pollset_shutdown
+  grpc_exec_ctx_flush(exec_ctx);
   grpc_pollset_destroy(args->pollset);
+  gpr_free(args->pollset);
 }
 
 static gpr_timespec n_sec_deadline(int seconds) {
@@ -78,7 +87,6 @@ static gpr_timespec n_sec_deadline(int seconds) {
 static void actually_poll(void *argsp) {
   args_struct *args = argsp;
   gpr_timespec deadline = n_sec_deadline(10);
-  grpc_pollset_worker *worker = NULL;
   while (true) {
     bool done = gpr_atm_acq_load(&args->done_atm) != 0;
     if (done) {
@@ -89,6 +97,7 @@ static void actually_poll(void *argsp) {
     gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done,
             time_left.tv_sec, time_left.tv_nsec);
     GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0);
+    grpc_pollset_worker *worker = NULL;
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     gpr_mu_lock(args->mu);
     GRPC_LOG_IF_ERROR(
@@ -123,47 +132,47 @@ static void must_fail(grpc_exec_ctx *exec_ctx, void *argsp, grpc_error *err) {
 }
 
 static void test_localhost(void) {
-  args_struct args;
-  args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  args_struct args;
+  args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
   grpc_resolve_address(&exec_ctx, "localhost:1", NULL, args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
+  args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
-  args_finish(&args);
 }
 
 static void test_default_port(void) {
-  args_struct args;
-  args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  args_struct args;
+  args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
   grpc_resolve_address(&exec_ctx, "localhost", "1", args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
+  args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
-  args_finish(&args);
 }
 
 static void test_missing_default_port(void) {
-  args_struct args;
-  args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  args_struct args;
+  args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
   grpc_resolve_address(&exec_ctx, "localhost", NULL, args.pollset_set,
                        grpc_closure_create(must_fail, &args), &args.addrs);
+  args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
-  args_finish(&args);
 }
 
 static void test_ipv6_with_port(void) {
-  args_struct args;
-  args_init(&args);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  args_struct args;
+  args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
   grpc_resolve_address(&exec_ctx, "[2001:db8::1]:1", NULL, args.pollset_set,
                        grpc_closure_create(must_succeed, &args), &args.addrs);
+  args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
-  args_finish(&args);
 }
 
 static void test_ipv6_without_port(void) {
@@ -172,14 +181,14 @@ static void test_ipv6_without_port(void) {
   };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
-    args_struct args;
-    args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    args_struct args;
+    args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
     grpc_resolve_address(&exec_ctx, kCases[i], "80", args.pollset_set,
                          grpc_closure_create(must_succeed, &args), &args.addrs);
+    args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
-    args_finish(&args);
   }
 }
 
@@ -189,14 +198,14 @@ static void test_invalid_ip_addresses(void) {
   };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
-    args_struct args;
-    args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    args_struct args;
+    args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
     grpc_resolve_address(&exec_ctx, kCases[i], NULL, args.pollset_set,
                          grpc_closure_create(must_fail, &args), &args.addrs);
+    args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
-    args_finish(&args);
   }
 }
 
@@ -206,14 +215,14 @@ static void test_unparseable_hostports(void) {
   };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
-    args_struct args;
-    args_init(&args);
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    args_struct args;
+    args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
     grpc_resolve_address(&exec_ctx, kCases[i], "1", args.pollset_set,
                          grpc_closure_create(must_fail, &args), &args.addrs);
+    args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
-    args_finish(&args);
   }
 }
 
-- 
GitLab


From 426cf85a68a1033edbd100c510199b0ab00461dc Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Fri, 18 Nov 2016 01:55:50 -0800
Subject: [PATCH 155/344] Fix resolve_address_windows

---
 src/core/lib/iomgr/resolve_address_windows.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index e139293c03..fada5ecbe8 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -169,6 +169,7 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
 
 static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  const char *default_port,
+                                 grpc_pollset_set *interested_parties,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addresses) {
   request *r = gpr_malloc(sizeof(request));
@@ -180,9 +181,9 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
   grpc_executor_push(&r->request_closure, GRPC_ERROR_NONE);
 }
 
-void (*grpc_resolve_address)(grpc_exec_ctx *exec_ctx, const char *name,
-                             const char *default_port, grpc_closure *on_done,
-                             grpc_resolved_addresses **addresses) =
-    resolve_address_impl;
+void (*grpc_resolve_address)(
+    grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
+    grpc_pollset_set *interested_parties, grpc_closure *on_done,
+    grpc_resolved_addresses **addresses) = resolve_address_impl;
 
 #endif
-- 
GitLab


From 8fe21f2b1914ef054ea9c585ced06d982fb2b85b Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Mon, 21 Nov 2016 13:34:16 -0800
Subject: [PATCH 156/344] Address review comments

---
 test/core/iomgr/resolve_address_test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 1e9e6abb2a..e4136a7a7a 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -73,7 +73,7 @@ void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) {
   grpc_closure do_nothing_cb;
   grpc_closure_init(&do_nothing_cb, do_nothing, NULL);
   grpc_pollset_shutdown(exec_ctx, args->pollset, &do_nothing_cb);
-  // exec_ctx needs to be flushed before calling grpc_pollset_shutdown
+  // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
   grpc_exec_ctx_flush(exec_ctx);
   grpc_pollset_destroy(args->pollset);
   gpr_free(args->pollset);
-- 
GitLab


From b3bda54df8a89904fb22f55558ec9a43e56ade47 Mon Sep 17 00:00:00 2001
From: Eric Gribkoff <ericgribkoff@google.com>
Date: Thu, 15 Dec 2016 11:02:59 -0800
Subject: [PATCH 157/344] Modify HTTP/2 test server to display a list of
 available test cases and accept non-positional arguments.

---
 test/http2_test/http2_test_server.py | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 1549d6da61..fc88410f69 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -45,15 +45,18 @@ class H2Factory(twisted.internet.protocol.Factory):
     else:
       return t().get_base_server()
 
-if __name__ == "__main__":
-  logging.basicConfig(format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s", level=logging.INFO)
+if __name__ == '__main__':
+  logging.basicConfig(
+    format='%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s',
+    level=logging.INFO)
   parser = argparse.ArgumentParser()
-  parser.add_argument("test")
-  parser.add_argument("port")
+  parser.add_argument('--test_case', choices=sorted(_TEST_CASE_MAPPING.keys()),
+    help='test case to run', required=True)
+  parser.add_argument('--port', type=int, default=8080,
+    help='port to run the server (default: 8080)')
   args = parser.parse_args()
-  if args.test not in _TEST_CASE_MAPPING.keys():
-    logging.error('unknown test: %s' % args.test)
-  else:
-    endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(twisted.internet.reactor, int(args.port), backlog=128)
-    endpoint.listen(H2Factory(args.test))
-    twisted.internet.reactor.run()
+  logging.info('Running test case %s on port %d' % (args.test_case, args.port))
+  endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(
+    twisted.internet.reactor, args.port, backlog=128)
+  endpoint.listen(H2Factory(args.test_case))
+  twisted.internet.reactor.run()
-- 
GitLab


From 63e3e3b1df2ffc212acf5114aac49c7c75987f6b Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Thu, 15 Dec 2016 12:06:33 -0800
Subject: [PATCH 158/344] Add grpc_pollset_set as an arg in
 grpc_resolver_create

---
 src/core/ext/client_channel/client_channel.c   |  4 +++-
 src/core/ext/client_channel/resolver.c         |  2 --
 src/core/ext/client_channel/resolver.h         |  2 --
 src/core/ext/client_channel/resolver_factory.c |  5 +++--
 src/core/ext/client_channel/resolver_factory.h |  8 ++++++--
 .../ext/client_channel/resolver_registry.c     |  9 ++++++---
 .../ext/client_channel/resolver_registry.h     |  6 ++++--
 .../ext/resolver/dns/native/dns_resolver.c     | 18 ++++++++++++++----
 .../ext/resolver/sockaddr/sockaddr_resolver.c  |  3 ++-
 .../resolvers/dns_resolver_connectivity_test.c |  9 ++++-----
 .../resolvers/dns_resolver_test.c              |  4 ++--
 .../resolvers/sockaddr_resolver_test.c         |  4 ++--
 test/core/end2end/fake_resolver.c              |  3 ++-
 13 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 5698d65572..9d46338428 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -526,7 +526,9 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
-  chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
+  chand->resolver =
+      grpc_resolver_create(exec_ctx, arg->value.string, args->channel_args,
+                           chand->interested_parties);
   if (chand->resolver == NULL) {
     return GRPC_ERROR_CREATE("resolver creation failed");
   }
diff --git a/src/core/ext/client_channel/resolver.c b/src/core/ext/client_channel/resolver.c
index 4a5e4f751b..2ae4fe862e 100644
--- a/src/core/ext/client_channel/resolver.c
+++ b/src/core/ext/client_channel/resolver.c
@@ -36,7 +36,6 @@
 void grpc_resolver_init(grpc_resolver *resolver,
                         const grpc_resolver_vtable *vtable) {
   resolver->vtable = vtable;
-  resolver->pollset_set = grpc_pollset_set_create();
   gpr_ref_init(&resolver->refs, 1);
 }
 
@@ -63,7 +62,6 @@ void grpc_resolver_unref(grpc_resolver *resolver,
 void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
 #endif
   if (gpr_unref(&resolver->refs)) {
-    grpc_pollset_set_destroy(resolver->pollset_set);
     resolver->vtable->destroy(exec_ctx, resolver);
   }
 }
diff --git a/src/core/ext/client_channel/resolver.h b/src/core/ext/client_channel/resolver.h
index d283120648..96ece92b9d 100644
--- a/src/core/ext/client_channel/resolver.h
+++ b/src/core/ext/client_channel/resolver.h
@@ -36,7 +36,6 @@
 
 #include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/iomgr/iomgr.h"
-#include "src/core/lib/iomgr/pollset_set.h"
 
 typedef struct grpc_resolver grpc_resolver;
 typedef struct grpc_resolver_vtable grpc_resolver_vtable;
@@ -44,7 +43,6 @@ typedef struct grpc_resolver_vtable grpc_resolver_vtable;
 /** \a grpc_resolver provides \a grpc_channel_args objects to its caller */
 struct grpc_resolver {
   const grpc_resolver_vtable *vtable;
-  grpc_pollset_set *pollset_set;
   gpr_refcount refs;
 };
 
diff --git a/src/core/ext/client_channel/resolver_factory.c b/src/core/ext/client_channel/resolver_factory.c
index 7c3d644257..00bbb92dd0 100644
--- a/src/core/ext/client_channel/resolver_factory.c
+++ b/src/core/ext/client_channel/resolver_factory.c
@@ -43,9 +43,10 @@ void grpc_resolver_factory_unref(grpc_resolver_factory* factory) {
 
 /** Create a resolver instance for a name */
 grpc_resolver* grpc_resolver_factory_create_resolver(
-    grpc_resolver_factory* factory, grpc_resolver_args* args) {
+    grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
+    grpc_resolver_args* args) {
   if (factory == NULL) return NULL;
-  return factory->vtable->create_resolver(factory, args);
+  return factory->vtable->create_resolver(exec_ctx, factory, args);
 }
 
 char* grpc_resolver_factory_get_default_authority(
diff --git a/src/core/ext/client_channel/resolver_factory.h b/src/core/ext/client_channel/resolver_factory.h
index 4da42e84d2..3792ddca18 100644
--- a/src/core/ext/client_channel/resolver_factory.h
+++ b/src/core/ext/client_channel/resolver_factory.h
@@ -37,6 +37,7 @@
 #include "src/core/ext/client_channel/client_channel_factory.h"
 #include "src/core/ext/client_channel/resolver.h"
 #include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/lib/iomgr/pollset_set.h"
 
 typedef struct grpc_resolver_factory grpc_resolver_factory;
 typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable;
@@ -48,6 +49,7 @@ struct grpc_resolver_factory {
 typedef struct grpc_resolver_args {
   grpc_uri *uri;
   const grpc_channel_args *args;
+  grpc_pollset_set *pollset_set;
 } grpc_resolver_args;
 
 struct grpc_resolver_factory_vtable {
@@ -55,7 +57,8 @@ struct grpc_resolver_factory_vtable {
   void (*unref)(grpc_resolver_factory *factory);
 
   /** Implementation of grpc_resolver_factory_create_resolver */
-  grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory,
+  grpc_resolver *(*create_resolver)(grpc_exec_ctx *exec_ctx,
+                                    grpc_resolver_factory *factory,
                                     grpc_resolver_args *args);
 
   /** Implementation of grpc_resolver_factory_get_default_authority */
@@ -70,7 +73,8 @@ void grpc_resolver_factory_unref(grpc_resolver_factory *resolver);
 
 /** Create a resolver instance for a name */
 grpc_resolver *grpc_resolver_factory_create_resolver(
-    grpc_resolver_factory *factory, grpc_resolver_args *args);
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args);
 
 /** Return a (freshly allocated with gpr_malloc) string representing
     the default authority to use for this scheme. */
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c
index 2b62b976a9..5110a7cad9 100644
--- a/src/core/ext/client_channel/resolver_registry.c
+++ b/src/core/ext/client_channel/resolver_registry.c
@@ -131,8 +131,9 @@ static grpc_resolver_factory *resolve_factory(const char *target,
   return factory;
 }
 
-grpc_resolver *grpc_resolver_create(const char *target,
-                                    const grpc_channel_args *args) {
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
+                                    const grpc_channel_args *args,
+                                    grpc_pollset_set *pollset_set) {
   grpc_uri *uri = NULL;
   char *canonical_target = NULL;
   grpc_resolver_factory *factory =
@@ -142,7 +143,9 @@ grpc_resolver *grpc_resolver_create(const char *target,
   memset(&resolver_args, 0, sizeof(resolver_args));
   resolver_args.uri = uri;
   resolver_args.args = args;
-  resolver = grpc_resolver_factory_create_resolver(factory, &resolver_args);
+  resolver_args.pollset_set = pollset_set;
+  resolver =
+      grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args);
   grpc_uri_destroy(uri);
   gpr_free(canonical_target);
   return resolver;
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
index 24678bc05f..4fb16131db 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/client_channel/resolver_registry.h
@@ -35,6 +35,7 @@
 #define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
 
 #include "src/core/ext/client_channel/resolver_factory.h"
+#include "src/core/lib/iomgr/pollset_set.h"
 
 void grpc_resolver_registry_init();
 void grpc_resolver_registry_shutdown(void);
@@ -60,8 +61,9 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
     If a resolver factory was not found, return NULL.
     \a args is a set of channel arguments to be included in the result
     (typically the set of arguments passed in from the client API). */
-grpc_resolver *grpc_resolver_create(const char *target,
-                                    const grpc_channel_args *args);
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
+                                    const grpc_channel_args *args,
+                                    grpc_pollset_set *pollset_set);
 
 /** Find a resolver factory given a name and return an (owned-by-the-caller)
  *  reference to it */
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 688c4fa845..2675fa931f 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -61,6 +61,8 @@ typedef struct {
   char *default_port;
   /** channel args. */
   grpc_channel_args *channel_args;
+  /** pollset_set to drive the name resolution process */
+  grpc_pollset_set *interested_parties;
 
   /** mutex guarding the rest of the state */
   gpr_mu mu;
@@ -218,7 +220,7 @@ static void dns_start_resolving_locked(grpc_exec_ctx *exec_ctx,
   r->resolving = true;
   r->addresses = NULL;
   grpc_resolve_address(exec_ctx, r->name_to_resolve, r->default_port,
-                       r->base.pollset_set,
+                       r->interested_parties,
                        grpc_closure_create(dns_on_resolved, r), &r->addresses);
 }
 
@@ -241,13 +243,15 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   if (r->resolved_result != NULL) {
     grpc_channel_args_destroy(r->resolved_result);
   }
+  grpc_pollset_set_destroy(r->interested_parties);
   gpr_free(r->name_to_resolve);
   gpr_free(r->default_port);
   grpc_channel_args_destroy(r->channel_args);
   gpr_free(r);
 }
 
-static grpc_resolver *dns_create(grpc_resolver_args *args,
+static grpc_resolver *dns_create(grpc_exec_ctx *exec_ctx,
+                                 grpc_resolver_args *args,
                                  const char *default_port) {
   if (0 != strcmp(args->uri->authority, "")) {
     gpr_log(GPR_ERROR, "authority based dns uri's not supported");
@@ -266,6 +270,11 @@ static grpc_resolver *dns_create(grpc_resolver_args *args,
   r->name_to_resolve = proxy_name == NULL ? gpr_strdup(path) : proxy_name;
   r->default_port = gpr_strdup(default_port);
   r->channel_args = grpc_channel_args_copy(args->args);
+  r->interested_parties = grpc_pollset_set_create();
+  if (args->pollset_set != NULL) {
+    grpc_pollset_set_add_pollset_set(exec_ctx, r->interested_parties,
+                                     args->pollset_set);
+  }
   gpr_backoff_init(&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS,
                    GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER,
                    GRPC_DNS_RECONNECT_JITTER,
@@ -283,8 +292,9 @@ static void dns_factory_ref(grpc_resolver_factory *factory) {}
 static void dns_factory_unref(grpc_resolver_factory *factory) {}
 
 static grpc_resolver *dns_factory_create_resolver(
-    grpc_resolver_factory *factory, grpc_resolver_args *args) {
-  return dns_create(args, "https");
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args) {
+  return dns_create(exec_ctx, args, "https");
 }
 
 static char *dns_factory_get_default_host_name(grpc_resolver_factory *factory,
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 0a9b1aa49a..88808c674f 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -214,7 +214,8 @@ static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
 
 #define DECL_FACTORY(name)                                                  \
   static grpc_resolver *name##_factory_create_resolver(                     \
-      grpc_resolver_factory *factory, grpc_resolver_args *args) {           \
+      grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,              \
+      grpc_resolver_args *args) {                                           \
     return sockaddr_create(args, parse_##name);                             \
   }                                                                         \
   static const grpc_resolver_factory_vtable name##_factory_vtable = {       \
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index ffa167a0e7..b421720492 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -63,7 +63,8 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
   }
 }
 
-static grpc_resolver *create_resolver(const char *name) {
+static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx,
+                                      const char *name) {
   grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
   grpc_uri *uri = grpc_uri_parse(name, 0);
   GPR_ASSERT(uri);
@@ -71,7 +72,7 @@ static grpc_resolver *create_resolver(const char *name) {
   memset(&args, 0, sizeof(args));
   args.uri = uri;
   grpc_resolver *resolver =
-      grpc_resolver_factory_create_resolver(factory, &args);
+      grpc_resolver_factory_create_resolver(exec_ctx, factory, &args);
   grpc_resolver_factory_unref(factory);
   grpc_uri_destroy(uri);
   return resolver;
@@ -101,12 +102,10 @@ int main(int argc, char **argv) {
   grpc_init();
   gpr_mu_init(&g_mu);
   grpc_blocking_resolve_address = my_resolve_address;
-
-  grpc_resolver *resolver = create_resolver("dns:test");
-
   grpc_channel_args *result = (grpc_channel_args *)1;
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_resolver *resolver = create_resolver(&exec_ctx, "dns:test");
   gpr_event ev1;
   gpr_event_init(&ev1);
   grpc_resolver_next(&exec_ctx, resolver, &result,
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 41a9125431..5603a57b5f 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -48,7 +48,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
   grpc_uri_destroy(uri);
@@ -65,7 +65,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index 5ef248f036..a9fd85aea1 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -62,7 +62,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
 
   on_resolution_arg on_res_arg;
@@ -88,7 +88,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 7380dccd80..ed85030797 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -140,7 +140,8 @@ static void fake_resolver_factory_unref(grpc_resolver_factory* factory) {}
 
 static void do_nothing(void* ignored) {}
 
-static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
+static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
+                                           grpc_resolver_factory* factory,
                                            grpc_resolver_args* args) {
   if (0 != strcmp(args->uri->authority, "")) {
     gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
-- 
GitLab


From fcb2d1470664419a79692610f9aa60587f0aedc1 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Thu, 15 Dec 2016 12:13:02 -0800
Subject: [PATCH 159/344] Add negative http2 interop description file

---
 ...egative-http2-interop-test-descriptions.md | 193 ++++++++++++++++++
 1 file changed, 193 insertions(+)
 create mode 100644 doc/negative-http2-interop-test-descriptions.md

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
new file mode 100644
index 0000000000..a06c00710f
--- /dev/null
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -0,0 +1,193 @@
+Negative HTTP/2 Interop Test Case Descriptions
+=======================================
+
+Client and server use
+[test.proto](../src/proto/grpc/testing/test.proto).
+
+Server
+------
+The code for the custom http2 server can be found
+[here](https://github.com/grpc/grpc/tree/master/test/http2_test).
+It is responsible for handling requests and sending responses, and also for 
+fulfilling the behavior of each particular test case.
+
+Server should accept these arguments:
+* --port=PORT
+  * The port the server will run on. For example, "8080"
+* --test_case=TESTCASE
+  * The name of the test case to execute. For example, "goaway"
+
+Client
+------
+
+Clients implement test cases that test certain functionally. Each client is
+provided the test case it is expected to run as a command-line parameter. Names
+should be lowercase and without spaces.
+
+Clients should accept these arguments:
+* --server_host=HOSTNAME
+    * The server host to connect to. For example, "localhost" or "127.0.0.1"
+* --server_port=PORT
+    * The server port to connect to. For example, "8080"
+* --test_case=TESTCASE
+    * The name of the test case to execute. For example, "goaway"
+
+Note
+-----
+
+Note that the server and client must be invoked with the same test case or else
+the test will be meaningless. For convenience, we provide a shell script wrapper
+that invokes both server and client at the same time, with the same test_case.
+This is the preferred way to run these tests.
+
+## Test Cases
+
+### goaway
+
+This test verifies that the client correctly responds to a goaway sent by the
+server. The client should handle the goaway by switching to a new stream without
+the user application having to do a thing.
+
+Client Procedure:
+ 1. Client sends two UnaryCall requests with:
+ 
+     ```
+    {
+      response_size: 1024
+      payload:{
+        body: 1024 bytes of zeros
+      }
+    }
+    ```
+
+Client asserts:
+* call was successful.
+* response payload body is 1024 bytes in size.
+
+Server Procedure:
+  1. Server sends a GOAWAY after receiving the first UnaryCall.
+
+Server asserts:
+* The second UnaryCall has a different stream_id than the first one.
+
+### rst_after_header
+
+This test verifies that the client fails "correctly" when the server sends a
+RST_STREAM immediately after sending headers to the client.
+
+Procedure:
+ 1. Client sends UnaryCall with:
+ 
+  ```
+  {
+    response_size: 1024
+    payload:{
+      body: 1024 bytes of zeros
+    }
+  }
+  ```
+
+Client asserts:
+* Call was not successful
+
+Server Procedure:
+  1. Server sends a RST_STREAM with error code 0 after sending headers to the client.
+  
+*At the moment the error code and message returned are not standardized throughout all
+languages. Those checks will be added once all client languages behave the same way.*
+
+### rst_during_data
+
+This test verifies that the client fails "correctly" when the server sends a
+RST_STREAM halfway through sending data to the client.
+
+Procedure:
+ 1. Client sends UnaryCall with:
+ 
+  ```
+  {
+    response_size: 1024
+    payload:{
+      body: 1024 bytes of zeros
+    }
+  }
+  ```
+
+Client asserts:
+* Call was not successful
+
+Server Procedure:
+  1. Server sends a RST_STREAM with error code 0 after sending half of 
+     the requested data to the client.
+
+### rst_after_data
+
+This test verifies that the client fails "correctly" when the server sends a
+RST_STREAM after sending all of the data to the client.
+
+Procedure:
+ 1. Client sends UnaryCall with:
+  ```
+  {
+    response_size: 1024
+    payload:{
+      body: 1024 bytes of zeros
+    }
+  }
+  ```
+
+Client asserts:
+* Call was not successful
+
+Server Procedure:
+  1. Server sends a RST_STREAM with error code 0 after sending all of the
+  data to the client.
+
+*Certain client languages allow the data to be accessed even though a RST_STREAM
+was encountered. Once all client languages behave this way, checks will be added on
+the incoming data.*
+
+### ping
+
+This test verifies that the client correctly acknowledges all pings it gets from the
+server.
+
+Procedure:
+ 1. Client sends UnaryCall with:
+ 
+  ```
+  {
+    response_size: 1024
+    payload:{
+      body: 1024 bytes of zeros
+    }
+  }
+  ```
+  
+Client asserts:
+* call was successful.
+* response payload body is 1024 bytes in size.
+
+Server Procedure:
+  1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1 
+  when it receives an ack from the client)
+  2. Server sends pings before and after sending headers, also before and after sending data
+  
+Server Asserts:
+* Number of outstanding pings is 0 when the connection is lost
+
+### max_streams
+
+This test verifies that the client observes the MAX_CONCURRENT_STREAMS limit set by the server
+
+Client Procedure:
+  1. Client sends initial UnaryCall to allow the server to update its MAX_CONCURRENT_STREAMS settings.
+  2. Client asynchronously sends 15 UnaryCalls
+  
+Client Asserts:
+* All UnaryCalls were successful, and had the correct type and payload size
+ 
+Server Procedure:
+  1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made
+
+*The assertion that the MAX_CONCURRENT_STREAMS limit is upheld occurs in the http2 library we used.*
-- 
GitLab


From 65a45aebbe21e4aa7b96392d2dee22f5bb52ca84 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Thu, 15 Dec 2016 14:35:17 -0800
Subject: [PATCH 160/344] Add copywrite to new files

---
 test/http2_test/http2_base_server.py     | 29 ++++++++++++++++++++
 test/http2_test/http2_test_server.py     | 34 +++++++++++++++++++++---
 test/http2_test/test_goaway.py           | 29 ++++++++++++++++++++
 test/http2_test/test_max_streams.py      | 29 ++++++++++++++++++++
 test/http2_test/test_ping.py             | 29 ++++++++++++++++++++
 test/http2_test/test_rst_after_data.py   | 29 ++++++++++++++++++++
 test/http2_test/test_rst_after_header.py | 29 ++++++++++++++++++++
 test/http2_test/test_rst_during_data.py  | 29 ++++++++++++++++++++
 8 files changed, 234 insertions(+), 3 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index 4d356d4385..ee7719b1a8 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import logging
 import messages_pb2
 import struct
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 1549d6da61..c9b33e00f1 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -1,6 +1,34 @@
-"""
-  HTTP2 Test Server. Highly experimental work in progress.
-"""
+# Copyright 2016, 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.
+
+"""HTTP2 Test Server"""
+
 import argparse
 import logging
 import twisted
diff --git a/test/http2_test/test_goaway.py b/test/http2_test/test_goaway.py
index 6deb883d4e..61f4beb74a 100644
--- a/test/http2_test/test_goaway.py
+++ b/test/http2_test/test_goaway.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import logging
 import time
 
diff --git a/test/http2_test/test_max_streams.py b/test/http2_test/test_max_streams.py
index 10a9da3deb..9942b1bb9a 100644
--- a/test/http2_test/test_max_streams.py
+++ b/test/http2_test/test_max_streams.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import hyperframe.frame
 import logging
 
diff --git a/test/http2_test/test_ping.py b/test/http2_test/test_ping.py
index 873eb4f39e..da41fd01bb 100644
--- a/test/http2_test/test_ping.py
+++ b/test/http2_test/test_ping.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import logging
 
 import http2_base_server
diff --git a/test/http2_test/test_rst_after_data.py b/test/http2_test/test_rst_after_data.py
index f7927cbcd3..9236025395 100644
--- a/test/http2_test/test_rst_after_data.py
+++ b/test/http2_test/test_rst_after_data.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import http2_base_server
 
 class TestcaseRstStreamAfterData(object):
diff --git a/test/http2_test/test_rst_after_header.py b/test/http2_test/test_rst_after_header.py
index e9a6b1129c..41e1adb8ad 100644
--- a/test/http2_test/test_rst_after_header.py
+++ b/test/http2_test/test_rst_after_header.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import http2_base_server
 
 class TestcaseRstStreamAfterHeader(object):
diff --git a/test/http2_test/test_rst_during_data.py b/test/http2_test/test_rst_during_data.py
index 6767ccaf66..7c859db267 100644
--- a/test/http2_test/test_rst_during_data.py
+++ b/test/http2_test/test_rst_during_data.py
@@ -1,3 +1,32 @@
+# Copyright 2016, 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.
+
 import http2_base_server
 
 class TestcaseRstStreamDuringData(object):
-- 
GitLab


From d3b83f4693026ec306397da371ce7b4cd9d5f892 Mon Sep 17 00:00:00 2001
From: David Garcia Quintas <dgq@google.com>
Date: Thu, 15 Dec 2016 18:07:24 -0800
Subject: [PATCH 161/344] Deflake lb_policies_test

---
 test/core/client_channel/lb_policies_test.c | 32 ++++++++++-----------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 6e4058fc21..016610763c 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -241,6 +241,8 @@ static request_sequences request_sequences_create(size_t n) {
   res.n = n;
   res.connections = gpr_malloc(sizeof(*res.connections) * n);
   res.connectivity_states = gpr_malloc(sizeof(*res.connectivity_states) * n);
+  memset(res.connections, 0, sizeof(*res.connections) * n);
+  memset(res.connectivity_states, 0, sizeof(*res.connectivity_states) * n);
   return res;
 }
 
@@ -782,17 +784,15 @@ static void verify_total_carnage_round_robin(const servers_fixture *f,
     }
   }
 
-  /* no server is ever available. The persistent state is TRANSIENT_FAILURE. May
-   * also be CONNECTING if, under load, this check took too long to run and some
-   * subchannel already transitioned to retrying. */
+  /* No server is ever available. There should be no READY states (or SHUTDOWN).
+   * Note that all other states (IDLE, CONNECTING, TRANSIENT_FAILURE) are still
+   * possible, as the policy transitions while attempting to reconnect. */
   for (size_t i = 0; i < sequences->n; i++) {
     const grpc_connectivity_state actual = sequences->connectivity_states[i];
-    if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
-        actual != GRPC_CHANNEL_CONNECTING) {
+    if (actual == GRPC_CHANNEL_READY || actual == GRPC_CHANNEL_SHUTDOWN) {
       gpr_log(GPR_ERROR,
-              "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
-              "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
-              "'%s' at iteration #%d",
+              "CONNECTIVITY STATUS SEQUENCE FAILURE: got unexpected state "
+              "'%s' at iteration #%d.",
               grpc_connectivity_state_name(actual), (int)i);
       abort();
     }
@@ -841,17 +841,15 @@ static void verify_partial_carnage_round_robin(
     abort();
   }
 
-  /* ... and that the last one should be TRANSIENT_FAILURE, after all servers
-   * are gone. May also be CONNECTING if, under load, this check took too long
-   * to run and the subchannel already transitioned to retrying. */
+  /* ... and that the last one shouldn't be READY (or SHUTDOWN): all servers are
+   * gone. It may be all other states (IDLE, CONNECTING, TRANSIENT_FAILURE), as
+   * the policy transitions while attempting to reconnect. */
   actual = sequences->connectivity_states[num_iters - 1];
   for (i = 0; i < sequences->n; i++) {
-    if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
-        actual != GRPC_CHANNEL_CONNECTING) {
+    if (actual == GRPC_CHANNEL_READY || actual == GRPC_CHANNEL_SHUTDOWN) {
       gpr_log(GPR_ERROR,
-              "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
-              "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
-              "'%s' at iteration #%d",
+              "CONNECTIVITY STATUS SEQUENCE FAILURE: got unexpected state "
+              "'%s' at iteration #%d.",
               grpc_connectivity_state_name(actual), (int)i);
       abort();
     }
@@ -948,8 +946,8 @@ int main(int argc, char **argv) {
   const size_t NUM_ITERS = 10;
   const size_t NUM_SERVERS = 4;
 
-  grpc_test_init(argc, argv);
   grpc_init();
+  grpc_test_init(argc, argv);
   grpc_tracer_set_enabled("round_robin", 1);
 
   GPR_ASSERT(grpc_lb_policy_create(&exec_ctx, "this-lb-policy-does-not-exist",
-- 
GitLab


From c549a3e37b21e0aee90acc21fce2d3c0cf4e57b5 Mon Sep 17 00:00:00 2001
From: Bryan Blanchard <bryan.blanchard@gmail.com>
Date: Tue, 13 Dec 2016 07:46:28 -0500
Subject: [PATCH 162/344] don't print multiple imports to protobuf modules

---
 src/compiler/python_generator.cc | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index b0a60092ab..0fac1b88cd 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -40,6 +40,7 @@
 #include <map>
 #include <memory>
 #include <ostream>
+#include <set>
 #include <sstream>
 #include <tuple>
 #include <vector>
@@ -64,7 +65,9 @@ using std::make_pair;
 using std::map;
 using std::pair;
 using std::replace;
+using std::tuple;
 using std::vector;
+using std::set;
 
 namespace grpc_python_generator {
 
@@ -73,6 +76,8 @@ namespace {
 typedef vector<const Descriptor*> DescriptorVector;
 typedef map<grpc::string, grpc::string> StringMap;
 typedef vector<grpc::string> StringVector;
+typedef tuple<grpc::string, grpc::string> StringPair;
+typedef set<StringPair> StringPairSet;
 
 // Provides RAII indentation handling. Use as:
 // {
@@ -651,6 +656,7 @@ bool PrivateGenerator::PrintPreamble() {
       "face_utilities\n");
   if (generate_in_pb2_grpc) {
     out->Print("\n");
+    StringPairSet imports_set;
     for (int i = 0; i < file->service_count(); ++i) {
       const ServiceDescriptor* service = file->service(i);
       for (int j = 0; j < service->method_count(); ++j) {
@@ -662,11 +668,15 @@ bool PrivateGenerator::PrintPreamble() {
           grpc::string type_file_name = type->file()->name();
           grpc::string module_name = ModuleName(type_file_name);
           grpc::string module_alias = ModuleAlias(type_file_name);
-          out->Print("import $ModuleName$ as $ModuleAlias$\n", "ModuleName",
-                     module_name, "ModuleAlias", module_alias);
+          imports_set.insert(std::make_tuple(module_name, module_alias));
         }
       }
     }
+    for (StringPairSet::iterator it = imports_set.begin();
+         it != imports_set.end(); ++it) {
+      out->Print("import $ModuleName$ as $ModuleAlias$\n", "ModuleName",
+                 std::get<0>(*it), "ModuleAlias", std::get<1>(*it));
+    }
   }
   return true;
 }
-- 
GitLab


From 7eef316e201e0674fff861cde55400aa4ed436be Mon Sep 17 00:00:00 2001
From: Sree Kuchibhotla <sreek@google.com>
Date: Fri, 16 Dec 2016 11:30:35 -0800
Subject: [PATCH 163/344] Fix metrics server

---
 test/cpp/interop/stress_test.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index fc35db5233..97e658869f 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -371,9 +371,9 @@ int main(int argc, char** argv) {
   }
 
   // Start metrics server before waiting for the stress test threads
+  std::unique_ptr<grpc::Server> metrics_server;
   if (FLAGS_metrics_port > 0) {
-    std::unique_ptr<grpc::Server> metrics_server =
-        metrics_service.StartServer(FLAGS_metrics_port);
+    metrics_server = metrics_service.StartServer(FLAGS_metrics_port);
   }
 
   // Wait for the stress test threads to complete
-- 
GitLab


From 855a1063ecfe777935f5d92a25a610856179a630 Mon Sep 17 00:00:00 2001
From: David Garcia Quintas <dgq@google.com>
Date: Fri, 16 Dec 2016 13:11:49 -0800
Subject: [PATCH 164/344] grpclb: skip slash in server uri path if present

---
 src/core/ext/lb_policy/grpclb/grpclb.c | 10 ++++++++--
 test/cpp/grpclb/grpclb_test.cc         |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 38eebdc758..bed5e6c901 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -768,8 +768,14 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
-  grpc_uri *uri = grpc_uri_parse(arg->value.string, 1);
-  glb_policy->server_name = gpr_strdup(uri->path);
+  grpc_uri *uri = grpc_uri_parse(arg->value.string, true);
+  GPR_ASSERT(uri->path[0] != '\0');
+  glb_policy->server_name =
+      gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
+  if (grpc_lb_glb_trace) {
+    gpr_log(GPR_INFO, "Will use '%s' as the server name for LB request.",
+            glb_policy->server_name);
+  }
   grpc_uri_destroy(uri);
 
   /* All input addresses in addresses come from a resolver that claims
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index fcdcaba6a2..de304b9f89 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -659,7 +659,7 @@ static test_fixture setup_test_fixture(int lb_server_update_delay_ms) {
   char *server_uri;
   // The grpclb LB policy will be automatically selected by virtue of
   // the fact that the returned addresses are balancer addresses.
-  gpr_asprintf(&server_uri, "test:%s?lb_enabled=1",
+  gpr_asprintf(&server_uri, "test:///%s?lb_enabled=1",
                tf.lb_server.servers_hostport);
   setup_client(server_uri, &tf.client);
   gpr_free(server_uri);
-- 
GitLab


From d803b805aef97a03bd5873c1a8c3e534bd22feb7 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Fri, 16 Dec 2016 13:59:04 -0800
Subject: [PATCH 165/344] Fix RST_STREAM(0) inconsistency

---
 src/core/ext/transport/chttp2/transport/frame_rst_stream.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
index b4c5ed769b..20043f5fbf 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c
@@ -109,7 +109,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx,
                       (((uint32_t)p->reason_bytes[2]) << 8) |
                       (((uint32_t)p->reason_bytes[3]));
     grpc_error *error = GRPC_ERROR_NONE;
-    if (reason != GRPC_CHTTP2_NO_ERROR) {
+    if (reason != GRPC_CHTTP2_NO_ERROR || s->header_frames_received < 2) {
       error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"),
                                  GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
       grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status(
-- 
GitLab


From 0eb69186f0b22f0e4bd5d6f1b4e31252bf614b76 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Fri, 16 Dec 2016 15:28:22 -0800
Subject: [PATCH 166/344] Addressed github comments

---
 ...egative-http2-interop-test-descriptions.md | 93 ++++++++++---------
 1 file changed, 47 insertions(+), 46 deletions(-)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index a06c00710f..38aaa95a79 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -20,7 +20,7 @@ Server should accept these arguments:
 Client
 ------
 
-Clients implement test cases that test certain functionally. Each client is
+Clients implement test cases that test certain functionality. Each client is
 provided the test case it is expected to run as a command-line parameter. Names
 should be lowercase and without spaces.
 
@@ -51,18 +51,18 @@ the user application having to do a thing.
 Client Procedure:
  1. Client sends two UnaryCall requests with:
  
-     ```
+    ```
     {
-      response_size: 1024
+      response_size: 314159
       payload:{
-        body: 1024 bytes of zeros
+        body: 271828 bytes of zeros
       }
     }
     ```
 
 Client asserts:
-* call was successful.
-* response payload body is 1024 bytes in size.
+* Call was successful.
+* Response payload body is 1024 bytes in size.
 
 Server Procedure:
   1. Server sends a GOAWAY after receiving the first UnaryCall.
@@ -72,29 +72,29 @@ Server asserts:
 
 ### rst_after_header
 
-This test verifies that the client fails "correctly" when the server sends a
+This test verifies that the client fails correctly when the server sends a
 RST_STREAM immediately after sending headers to the client.
 
 Procedure:
  1. Client sends UnaryCall with:
  
-  ```
-  {
-    response_size: 1024
-    payload:{
-      body: 1024 bytes of zeros
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
     }
-  }
-  ```
+    ```
 
 Client asserts:
-* Call was not successful
+* Call was not successful.
 
 Server Procedure:
   1. Server sends a RST_STREAM with error code 0 after sending headers to the client.
   
 *At the moment the error code and message returned are not standardized throughout all
-languages. Those checks will be added once all client languages behave the same way.*
+languages. Those checks will be added once all client languages behave the same way. [#9142](https://github.com/grpc/grpc/issues/9142) is in flight.*
 
 ### rst_during_data
 
@@ -104,17 +104,17 @@ RST_STREAM halfway through sending data to the client.
 Procedure:
  1. Client sends UnaryCall with:
  
-  ```
-  {
-    response_size: 1024
-    payload:{
-      body: 1024 bytes of zeros
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
     }
-  }
-  ```
+    ```
 
 Client asserts:
-* Call was not successful
+* Call was not successful.
 
 Server Procedure:
   1. Server sends a RST_STREAM with error code 0 after sending half of 
@@ -127,17 +127,18 @@ RST_STREAM after sending all of the data to the client.
 
 Procedure:
  1. Client sends UnaryCall with:
-  ```
-  {
-    response_size: 1024
-    payload:{
-      body: 1024 bytes of zeros
+ 
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
     }
-  }
-  ```
+    ```
 
 Client asserts:
-* Call was not successful
+* Call was not successful.
 
 Server Procedure:
   1. Server sends a RST_STREAM with error code 0 after sending all of the
@@ -155,14 +156,14 @@ server.
 Procedure:
  1. Client sends UnaryCall with:
  
-  ```
-  {
-    response_size: 1024
-    payload:{
-      body: 1024 bytes of zeros
+    ```
+    {
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
     }
-  }
-  ```
+    ```
   
 Client asserts:
 * call was successful.
@@ -170,24 +171,24 @@ Client asserts:
 
 Server Procedure:
   1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1 
-  when it receives an ack from the client)
-  2. Server sends pings before and after sending headers, also before and after sending data
+  when it receives an ack from the client).
+  2. Server sends pings before and after sending headers, also before and after sending data.
   
 Server Asserts:
-* Number of outstanding pings is 0 when the connection is lost
+* Number of outstanding pings is 0 when the connection is lost.
 
 ### max_streams
 
-This test verifies that the client observes the MAX_CONCURRENT_STREAMS limit set by the server
+This test verifies that the client observes the MAX_CONCURRENT_STREAMS limit set by the server.
 
 Client Procedure:
   1. Client sends initial UnaryCall to allow the server to update its MAX_CONCURRENT_STREAMS settings.
-  2. Client asynchronously sends 15 UnaryCalls
+  2. Client concurrently sends 10 UnaryCalls.
   
 Client Asserts:
-* All UnaryCalls were successful, and had the correct type and payload size
+* All UnaryCalls were successful, and had the correct type and payload size.
  
 Server Procedure:
-  1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made
+  1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made.
 
 *The assertion that the MAX_CONCURRENT_STREAMS limit is upheld occurs in the http2 library we used.*
-- 
GitLab


From 2d1d324a3ac6a123f2697d751e833ff976743385 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Fri, 16 Dec 2016 15:57:28 -0800
Subject: [PATCH 167/344] Update negative-http2-interop-test-descriptions.md

---
 doc/negative-http2-interop-test-descriptions.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index 38aaa95a79..5ea3a96dff 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -62,7 +62,7 @@ Client Procedure:
 
 Client asserts:
 * Call was successful.
-* Response payload body is 1024 bytes in size.
+* Response payload body is 314159 bytes in size.
 
 Server Procedure:
   1. Server sends a GOAWAY after receiving the first UnaryCall.
@@ -167,7 +167,7 @@ Procedure:
   
 Client asserts:
 * call was successful.
-* response payload body is 1024 bytes in size.
+* response payload body is 314159 bytes in size.
 
 Server Procedure:
   1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1 
-- 
GitLab


From 6aedd44fb69ac8015a4e48071582a9d74fa57f00 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Sat, 17 Dec 2016 00:42:00 +0000
Subject: [PATCH 168/344] Drop use of Exception.message in metadata test

Apparently Exception.message was introduced in Python 2.5 and
deprecated almost immediately afterward in Python 2.6.
---
 .../tests/unit/_invalid_metadata_test.py             | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
index 0411c58900..2dc225de29 100644
--- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -83,8 +83,7 @@ class InvalidMetadataTest(unittest.TestCase):
     expected_error_details = "metadata was invalid: %s" % metadata
     with self.assertRaises(ValueError) as exception_context:
       self._unary_unary(request, metadata=metadata)
-    self.assertEqual(
-        expected_error_details, exception_context.exception.message)
+    self.assertIn(expected_error_details, str(exception_context.exception))
 
   def testUnaryRequestBlockingUnaryResponseWithCall(self):
     request = b'\x07\x08'
@@ -92,8 +91,7 @@ class InvalidMetadataTest(unittest.TestCase):
     expected_error_details = "metadata was invalid: %s" % metadata
     with self.assertRaises(ValueError) as exception_context:
       self._unary_unary.with_call(request, metadata=metadata)
-    self.assertEqual(
-        expected_error_details, exception_context.exception.message)
+    self.assertIn(expected_error_details, str(exception_context.exception))
 
   def testUnaryRequestFutureUnaryResponse(self):
     request = b'\x07\x08'
@@ -129,8 +127,7 @@ class InvalidMetadataTest(unittest.TestCase):
     expected_error_details = "metadata was invalid: %s" % metadata
     with self.assertRaises(ValueError) as exception_context:
       self._stream_unary(request_iterator, metadata=metadata)
-    self.assertEqual(
-        expected_error_details, exception_context.exception.message)
+    self.assertIn(expected_error_details, str(exception_context.exception))
 
   def testStreamRequestBlockingUnaryResponseWithCall(self):
     request_iterator = (
@@ -140,8 +137,7 @@ class InvalidMetadataTest(unittest.TestCase):
     multi_callable = _stream_unary_multi_callable(self._channel)
     with self.assertRaises(ValueError) as exception_context:
       multi_callable.with_call(request_iterator, metadata=metadata)
-    self.assertEqual(
-        expected_error_details, exception_context.exception.message)
+    self.assertIn(expected_error_details, str(exception_context.exception))
 
   def testStreamRequestFutureUnaryResponse(self):
     request_iterator = (
-- 
GitLab


From c336268a403126767934933865b146eb50cd8c96 Mon Sep 17 00:00:00 2001
From: siddharthshukla <siddharthshukla@outlook.com>
Date: Sat, 17 Dec 2016 03:49:06 +0100
Subject: [PATCH 169/344] Fix invalid tests.json

Add a comma delimiter for "_invalid_metadata_test.InvalidMetadataTest".
---
 src/python/grpcio_tests/tests/tests.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 0eea66da40..2ac51ac542 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -25,7 +25,7 @@
   "_implementations_test.CallCredentialsTest",
   "_implementations_test.ChannelCredentialsTest",
   "_insecure_interop_test.InsecureInteropTest",
-  "_invalid_metadata_test.InvalidMetadataTest"
+  "_invalid_metadata_test.InvalidMetadataTest",
   "_logging_pool_test.LoggingPoolTest",
   "_metadata_code_details_test.MetadataCodeDetailsTest",
   "_metadata_test.MetadataTest",
-- 
GitLab


From 07383e7e28eb8713e245cb350f65b5749e8d3061 Mon Sep 17 00:00:00 2001
From: "David G. Quintas" <dgq@google.com>
Date: Sat, 17 Dec 2016 17:07:37 -0800
Subject: [PATCH 170/344] Revert "Revert "Reduce memory bloat (each server cq
 is very expensive)""

---
 include/grpc++/server_builder.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 9252c6a63a..2ac2f0a1ef 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -187,7 +187,7 @@ class ServerBuilder {
 
   struct SyncServerSettings {
     SyncServerSettings()
-        : num_cqs(GPR_MAX(gpr_cpu_num_cores(), 4)),
+        : num_cqs(1),
           min_pollers(1),
           max_pollers(INT_MAX),
           cq_timeout_msec(1000) {}
-- 
GitLab


From fffb2676b5fe65c0ed70258692886954b5b2c2a1 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 19 Dec 2016 15:24:45 +0100
Subject: [PATCH 171/344] test timeouts eliminated by mistake

---
 tools/run_tests/run_tests.py | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index c49ee4a6cc..546a3c42e2 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -382,10 +382,9 @@ class NodeLanguage(object):
 
   def test_specs(self):
     if self.platform == 'windows':
-      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'], None)]
+      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'])]
     else:
       return [self.config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
-                                   None,
                                    environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -427,7 +426,7 @@ class PhpLanguage(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['src/php/bin/run_tests.sh'], None,
+    return [self.config.job_spec(['src/php/bin/run_tests.sh'],
                                   environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -463,7 +462,7 @@ class Php7Language(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['src/php/bin/run_tests.sh'], None,
+    return [self.config.job_spec(['src/php/bin/run_tests.sh'],
                                   environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -702,7 +701,6 @@ class CSharpLanguage(object):
         for test in tests_by_assembly[assembly]:
           cmdline = runtime_cmd + [assembly_file, '--test=%s' % test] + nunit_args
           specs.append(self.config.job_spec(cmdline,
-                                            None,
                                             shortname='csharp.%s' % test,
                                             environ=_FORCE_ENVIRON_FOR_WRAPPERS))
       else:
@@ -720,7 +718,6 @@ class CSharpLanguage(object):
         # to prevent problems with registering the profiler.
         run_exclusive = 1000000
         specs.append(self.config.job_spec(cmdline,
-                                          None,
                                           shortname='csharp.coverage.%s' % assembly,
                                           cpu_cost=run_exclusive,
                                           environ=_FORCE_ENVIRON_FOR_WRAPPERS))
@@ -779,7 +776,7 @@ class ObjCLanguage(object):
   def test_specs(self):
     return [
         self.config.job_spec(['src/objective-c/tests/run_tests.sh'],
-                              timeout_seconds=None,
+                              timeout_seconds=60*60,
                               shortname='objc-tests',
                               environ=_FORCE_ENVIRON_FOR_WRAPPERS),
         self.config.job_spec(['src/objective-c/tests/build_example_test.sh'],
@@ -824,7 +821,7 @@ class Sanity(object):
     import yaml
     with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
       return [self.config.job_spec(cmd['script'].split(),
-                                   timeout_seconds=None, environ={'TEST': 'true'},
+                                   timeout_seconds=30*60, environ={'TEST': 'true'},
                                    cpu_cost=cmd.get('cpu_cost', 1))
               for cmd in yaml.load(f)]
 
-- 
GitLab


From 68e27bfef3eeb603733c7520c931c276398acd29 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Fri, 16 Dec 2016 14:09:03 +0100
Subject: [PATCH 172/344] enable running many runs per test without flooding
 the logs

---
 tools/run_tests/jobset.py           | 31 +++++++++++++++++++----------
 tools/run_tests/run_tests.py        | 24 +++++++++++++++-------
 tools/run_tests/run_tests_matrix.py | 20 ++++++++++++++++++-
 3 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index 1b5d6d66a0..7b2c62d1a2 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -219,7 +219,8 @@ class JobResult(object):
 class Job(object):
   """Manages one job."""
 
-  def __init__(self, spec, newline_on_success, travis, add_env):
+  def __init__(self, spec, newline_on_success, travis, add_env,
+               quiet_success=False):
     self._spec = spec
     self._newline_on_success = newline_on_success
     self._travis = travis
@@ -227,7 +228,9 @@ class Job(object):
     self._retries = 0
     self._timeout_retries = 0
     self._suppress_failure_message = False
-    message('START', spec.shortname, do_newline=self._travis)
+    self._quiet_success = quiet_success
+    if not self._quiet_success:
+      message('START', spec.shortname, do_newline=self._travis)
     self.result = JobResult()
     self.start()
 
@@ -302,10 +305,11 @@ class Job(object):
           if real > 0.5:
             cores = (user + sys) / real
             measurement = '; cpu_cost=%.01f; estimated=%.01f' % (cores, self._spec.cpu_cost)
-        message('PASSED', '%s [time=%.1fsec; retries=%d:%d%s]' % (
-            self._spec.shortname, elapsed, self._retries, self._timeout_retries, measurement),
-            stdout() if self._spec.verbose_success else None,
-            do_newline=self._newline_on_success or self._travis)
+        if not self._quiet_success:
+          message('PASSED', '%s [time=%.1fsec; retries=%d:%d%s]' % (
+              self._spec.shortname, elapsed, self._retries, self._timeout_retries, measurement),
+              stdout() if self._spec.verbose_success else None,
+              do_newline=self._newline_on_success or self._travis)
         self.result.state = 'PASSED'
     elif (self._state == _RUNNING and
           self._spec.timeout_seconds is not None and
@@ -341,7 +345,7 @@ class Jobset(object):
   """Manages one run of jobs."""
 
   def __init__(self, check_cancelled, maxjobs, newline_on_success, travis,
-               stop_on_failure, add_env):
+               stop_on_failure, add_env, quiet_success):
     self._running = set()
     self._check_cancelled = check_cancelled
     self._cancelled = False
@@ -352,6 +356,7 @@ class Jobset(object):
     self._travis = travis
     self._stop_on_failure = stop_on_failure
     self._add_env = add_env
+    self._quiet_success = quiet_success
     self.resultset = {}
     self._remaining = None
     self._start_time = time.time()
@@ -380,7 +385,8 @@ class Jobset(object):
     job = Job(spec,
               self._newline_on_success,
               self._travis,
-              self._add_env)
+              self._add_env,
+              self._quiet_success)
     self._running.add(job)
     if job.GetSpec().shortname not in self.resultset:
       self.resultset[job.GetSpec().shortname] = []
@@ -403,7 +409,8 @@ class Jobset(object):
         break
       for job in dead:
         self._completed += 1
-        self.resultset[job.GetSpec().shortname].append(job.result)
+        if not self._quiet_success or job.result.state != 'PASSED':
+          self.resultset[job.GetSpec().shortname].append(job.result)
         self._running.remove(job)
       if dead: return
       if not self._travis and platform_string() != 'windows':
@@ -463,7 +470,8 @@ def run(cmdlines,
         infinite_runs=False,
         stop_on_failure=False,
         add_env={},
-        skip_jobs=False):
+        skip_jobs=False,
+        quiet_success=False):
   if skip_jobs:
     results = {}
     skipped_job_result = JobResult()
@@ -474,7 +482,8 @@ def run(cmdlines,
     return results
   js = Jobset(check_cancelled,
               maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
-              newline_on_success, travis, stop_on_failure, add_env)
+              newline_on_success, travis, stop_on_failure, add_env,
+              quiet_success)
   for cmdline, remaining in tag_remaining(cmdlines):
     if not js.start(cmdline):
       break
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 546a3c42e2..fe56f4a175 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -1094,6 +1094,12 @@ argp.add_argument('-x', '--xml_report', default=None, type=str,
         help='Generates a JUnit-compatible XML report')
 argp.add_argument('--report_suite_name', default='tests', type=str,
         help='Test suite name to use in generated JUnit XML report')
+argp.add_argument('--quiet_success',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Dont print anything when a test passes. Passing tests also will not be reported in XML report. ' +
+                       'Useful when running many iterations of each test (argument -n).')
 argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
                   help='Dont try to iterate over many polling strategies when they exist')
 args = argp.parse_args()
@@ -1441,20 +1447,24 @@ def _build_and_run(
                      else itertools.repeat(massaged_one_run, runs_per_test))
     all_runs = itertools.chain.from_iterable(runs_sequence)
 
+    if args.quiet_success:
+      jobset.message('START', 'Running tests quietly, only failing tests will be reported', do_newline=True)
     num_test_failures, resultset = jobset.run(
         all_runs, check_cancelled, newline_on_success=newline_on_success,
         travis=args.travis, infinite_runs=infinite_runs, maxjobs=args.jobs,
         stop_on_failure=args.stop_on_failure,
-        add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
+        add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port},
+        quiet_success=args.quiet_success)
     if resultset:
       for k, v in sorted(resultset.items()):
         num_runs, num_failures = _calculate_num_runs_failures(v)
-        if num_failures == num_runs:  # what about infinite_runs???
-          jobset.message('FAILED', k, do_newline=True)
-        elif num_failures > 0:
-          jobset.message(
-              'FLAKE', '%s [%d/%d runs flaked]' % (k, num_failures, num_runs),
-              do_newline=True)
+        if num_failures > 0:
+          if num_failures == num_runs:  # what about infinite_runs???
+            jobset.message('FAILED', k, do_newline=True)
+          else:
+            jobset.message(
+                'FLAKE', '%s [%d/%d runs flaked]' % (k, num_failures, num_runs),
+                do_newline=True)
   finally:
     for antagonist in antagonists:
       antagonist.kill()
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 989bc7eb21..d954aad403 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -242,6 +242,17 @@ def _allowed_labels():
   return sorted(all_labels)
 
 
+def _runs_per_test_type(arg_str):
+    """Auxiliary function to parse the "runs_per_test" flag."""
+    try:
+        n = int(arg_str)
+        if n <= 0: raise ValueError
+        return n
+    except:
+        msg = '\'{}\' is not a positive integer'.format(arg_str)
+        raise argparse.ArgumentTypeError(msg)
+
+
 if __name__ == "__main__":
   argp = argparse.ArgumentParser(description='Run a matrix of run_tests.py tests.')
   argp.add_argument('-j', '--jobs',
@@ -269,7 +280,7 @@ if __name__ == "__main__":
                     default=False,
                     action='store_const',
                     const=True,
-                    help='Filters out tests irrelavant to pull request changes.')
+                    help='Filters out tests irrelevant to pull request changes.')
   argp.add_argument('--base_branch',
                     default='origin/master',
                     type=str,
@@ -278,6 +289,9 @@ if __name__ == "__main__":
                     default=_DEFAULT_INNER_JOBS,
                     type=int,
                     help='Number of jobs in each run_tests.py instance')
+  argp.add_argument('-n', '--runs_per_test', default=1, type=_runs_per_test_type,
+                    help='How many times to run each tests. >1 runs implies ' +
+                    'omitting passing test from the output & reports.')
   args = argp.parse_args()
 
   extra_args = []
@@ -285,6 +299,10 @@ if __name__ == "__main__":
     extra_args.append('--build_only')
   if args.force_default_poller:
     extra_args.append('--force_default_poller')
+  if args.runs_per_test > 1:
+    extra_args.append('-n')
+    extra_args.append('%s' % args.runs_per_test)
+    extra_args.append('--quiet_success')
 
   all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \
              _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs)
-- 
GitLab


From 02a7d4272aee5aa6e539bc69c81c7b99a393eb73 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Tue, 13 Dec 2016 13:48:14 -0800
Subject: [PATCH 173/344] Add python client to test negative http2 conditions

Documentation for the new tests can be found https://github.com/grpc/grpc/blob/master/doc/negative-http2-interop-test-descriptions.md
---
 .../tests/http2/_negative_http2_client.py     | 153 ++++++++++++++++++
 1 file changed, 153 insertions(+)
 create mode 100644 src/python/grpcio_tests/tests/http2/_negative_http2_client.py

diff --git a/src/python/grpcio_tests/tests/http2/_negative_http2_client.py b/src/python/grpcio_tests/tests/http2/_negative_http2_client.py
new file mode 100644
index 0000000000..f8604683b3
--- /dev/null
+++ b/src/python/grpcio_tests/tests/http2/_negative_http2_client.py
@@ -0,0 +1,153 @@
+# Copyright 2016, 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.
+
+"""The Python client used to test negative http2 conditions."""
+
+import argparse
+
+import grpc
+from src.proto.grpc.testing import test_pb2
+from src.proto.grpc.testing import messages_pb2
+
+def _validate_payload_type_and_length(response, expected_type, expected_length):
+  if response.payload.type is not expected_type:
+    raise ValueError(
+      'expected payload type %s, got %s' %
+          (expected_type, type(response.payload.type)))
+  elif len(response.payload.body) != expected_length:
+    raise ValueError(
+      'expected payload body size %d, got %d' %
+          (expected_length, len(response.payload.body)))
+
+def _expect_status_code(call, expected_code):
+  if call.code() != expected_code:
+    raise ValueError(
+      'expected code %s, got %s' % (expected_code, call.code()))
+
+def _expect_status_details(call, expected_details):
+  if call.details() != expected_details:
+    raise ValueError(
+      'expected message %s, got %s' % (expected_details, call.details()))
+
+def _validate_status_code_and_details(call, expected_code, expected_details):
+  _expect_status_code(call, expected_code)
+  _expect_status_details(call, expected_details)
+
+# common requests
+_REQUEST_SIZE = 314159
+_RESPONSE_SIZE = 271828
+
+_SIMPLE_REQUEST = messages_pb2.SimpleRequest(
+    response_type=messages_pb2.COMPRESSABLE,
+    response_size=_RESPONSE_SIZE,
+    payload=messages_pb2.Payload(body=b'\x00' * _REQUEST_SIZE))
+
+def _goaway(stub):
+  first_response = stub.UnaryCall(_SIMPLE_REQUEST)
+  _validate_payload_type_and_length(first_response, 
+      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+  second_response = stub.UnaryCall(_SIMPLE_REQUEST)
+  _validate_payload_type_and_length(second_response, 
+      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
+def _rst_after_header(stub):
+  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNAVAILABLE, "")
+
+def _rst_during_data(stub):
+  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+
+def _rst_after_data(stub):
+  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+  _validate_payload_type_and_length(next(resp_future),
+      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+
+def _ping(stub):
+  response = stub.UnaryCall(_SIMPLE_REQUEST)
+  _validate_payload_type_and_length(response, 
+      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
+def _max_streams(stub):
+  # send one req to ensure server sets MAX_STREAMS
+  response = stub.UnaryCall(_SIMPLE_REQUEST)
+  _validate_payload_type_and_length(response, 
+      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
+  # give the streams a workout
+  futures = []
+  for _ in range(15):
+    futures.append(stub.UnaryCall.future(_SIMPLE_REQUEST))
+  for future in futures:
+    _validate_payload_type_and_length(future.result(),
+        messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
+def _run_test_case(test_case, stub):
+  if test_case == 'goaway':
+    _goaway(stub)
+  elif test_case == 'rst_after_header':
+    _rst_after_header(stub)
+  elif test_case == 'rst_during_data':
+    _rst_during_data(stub)
+  elif test_case == 'rst_after_data':
+    _rst_after_data(stub)
+  elif test_case =='ping':
+    _ping(stub)
+  elif test_case == 'max_streams':
+    _max_streams(stub)
+  else:
+    raise ValueError("Invalid test case: %s" % test_case)
+
+def _args():
+  parser = argparse.ArgumentParser()
+  parser.add_argument(
+      '--server_host', help='the host to which to connect', type=str,
+      default="127.0.0.1")
+  parser.add_argument(
+      '--server_port', help='the port to which to connect', type=int,
+      default="8080")
+  parser.add_argument(
+      '--test_case', help='the test case to execute', type=str,
+      default="goaway")
+  return parser.parse_args()
+
+def _stub(server_host, server_port):
+  target = '{}:{}'.format(server_host, server_port)
+  channel = grpc.insecure_channel(target)
+  return test_pb2.TestServiceStub(channel)
+
+def main():
+  args = _args()
+  stub = _stub(args.server_host, args.server_port)
+  _run_test_case(args.test_case, stub)
+
+
+if __name__ == '__main__':
+  main()
-- 
GitLab


From b810b85e5226a9a096c7fcfbfb4bad8d70ca3e7c Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Mon, 19 Dec 2016 13:51:58 -0800
Subject: [PATCH 174/344] Get wrapped endpoint's fd in secure_endpoint's
 endpoint_get_fd

---
 src/core/lib/security/transport/secure_endpoint.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 1b278410e8..331a8f1835 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -372,7 +372,10 @@ static char *endpoint_get_peer(grpc_endpoint *secure_ep) {
   return grpc_endpoint_get_peer(ep->wrapped_ep);
 }
 
-static int endpoint_get_fd(grpc_endpoint *secure_ep) { return -1; }
+static int endpoint_get_fd(grpc_endpoint *secure_ep) {
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  return grpc_endpoint_get_fd(ep->wrapped_ep);
+}
 
 static grpc_workqueue *endpoint_get_workqueue(grpc_endpoint *secure_ep) {
   secure_endpoint *ep = (secure_endpoint *)secure_ep;
-- 
GitLab


From a025ea7c1cab7515acab6fec7f4379390b2d2990 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Mon, 19 Dec 2016 15:24:45 +0100
Subject: [PATCH 175/344] test timeouts eliminated by mistake

---
 tools/run_tests/run_tests.py | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 0424cf3d6f..2a28a87d56 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -307,10 +307,9 @@ class NodeLanguage(object):
 
   def test_specs(self):
     if self.platform == 'windows':
-      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'], None)]
+      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'])]
     else:
       return [self.config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
-                                   None,
                                    environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -352,7 +351,7 @@ class PhpLanguage(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['src/php/bin/run_tests.sh'], None,
+    return [self.config.job_spec(['src/php/bin/run_tests.sh'],
                                   environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -388,7 +387,7 @@ class Php7Language(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['src/php/bin/run_tests.sh'], None,
+    return [self.config.job_spec(['src/php/bin/run_tests.sh'],
                                   environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
@@ -610,7 +609,6 @@ class CSharpLanguage(object):
         for test in tests_by_assembly[assembly]:
           cmdline = runtime_cmd + [assembly_file, '--test=%s' % test] + nunit_args
           specs.append(self.config.job_spec(cmdline,
-                                            None,
                                             shortname='csharp.%s' % test,
                                             environ=_FORCE_ENVIRON_FOR_WRAPPERS))
       else:
@@ -628,7 +626,6 @@ class CSharpLanguage(object):
         # to prevent problems with registering the profiler.
         run_exclusive = 1000000
         specs.append(self.config.job_spec(cmdline,
-                                          None,
                                           shortname='csharp.coverage.%s' % assembly,
                                           cpu_cost=run_exclusive,
                                           environ=_FORCE_ENVIRON_FOR_WRAPPERS))
@@ -687,7 +684,7 @@ class ObjCLanguage(object):
   def test_specs(self):
     return [
         self.config.job_spec(['src/objective-c/tests/run_tests.sh'],
-                              timeout_seconds=None,
+                              timeout_seconds=60*60,
                               shortname='objc-tests',
                               environ=_FORCE_ENVIRON_FOR_WRAPPERS),
         self.config.job_spec(['src/objective-c/tests/build_example_test.sh'],
@@ -732,7 +729,7 @@ class Sanity(object):
     import yaml
     with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
       return [self.config.job_spec(cmd['script'].split(),
-                                   timeout_seconds=None, environ={'TEST': 'true'},
+                                   timeout_seconds=30*60, environ={'TEST': 'true'},
                                    cpu_cost=cmd.get('cpu_cost', 1))
               for cmd in yaml.load(f)]
 
-- 
GitLab


From 6a85129d1ad4a191bff37d743a9df9f5b7e11f82 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 20 Dec 2016 10:20:42 +0100
Subject: [PATCH 176/344] support --exclude in run_tests_matrix.py

---
 tools/run_tests/run_tests_matrix.py | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index d954aad403..df48099971 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -243,14 +243,14 @@ def _allowed_labels():
 
 
 def _runs_per_test_type(arg_str):
-    """Auxiliary function to parse the "runs_per_test" flag."""
-    try:
-        n = int(arg_str)
-        if n <= 0: raise ValueError
-        return n
-    except:
-        msg = '\'{}\' is not a positive integer'.format(arg_str)
-        raise argparse.ArgumentTypeError(msg)
+  """Auxiliary function to parse the "runs_per_test" flag."""
+  try:
+    n = int(arg_str)
+    if n <= 0: raise ValueError
+    return n
+  except:
+    msg = '\'{}\' is not a positive integer'.format(arg_str)
+    raise argparse.ArgumentTypeError(msg)
 
 
 if __name__ == "__main__":
@@ -264,6 +264,11 @@ if __name__ == "__main__":
                     nargs='+',
                     default=[],
                     help='Filter targets to run by label with AND semantics.')
+  argp.add_argument('--exclude',
+                    choices=_allowed_labels(),
+                    nargs='+',
+                    default=[],
+                    help='Exclude targets with any of given labels.')
   argp.add_argument('--build_only',
                     default=False,
                     action='store_const',
@@ -310,7 +315,8 @@ if __name__ == "__main__":
   jobs = []
   for job in all_jobs:
     if not args.filter or all(filter in job.labels for filter in args.filter):
-      jobs.append(job)
+      if not any(exclude_label in job.labels for exclude_label in args.exclude):
+        jobs.append(job)
 
   if not jobs:
     jobset.message('FAILED', 'No test suites match given criteria.',
-- 
GitLab


From 6bfa91a795c64c56fcc559cb842b7148baccf036 Mon Sep 17 00:00:00 2001
From: siddharthshukla <siddharthshukla@outlook.com>
Date: Fri, 4 Nov 2016 23:01:22 +0100
Subject: [PATCH 177/344] Handle non-iterator objects in
 consume_request_iterator

Restructure the consume_request_iterator method to handle exceptions
where the object being passed is not an iterator. Fixes #8231 and #8454.
---
 src/python/grpcio/grpc/_channel.py | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 1298cfbb6f..f07142aad3 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -32,6 +32,7 @@
 import sys
 import threading
 import time
+import logging
 
 import grpc
 from grpc import _common
@@ -197,7 +198,16 @@ def _consume_request_iterator(
   event_handler = _event_handler(state, call, None)
 
   def consume_request_iterator():
-    for request in request_iterator:
+    while True:
+      try:
+        request = next(request_iterator)
+      except StopIteration:
+        break
+      except Exception as e:
+        logging.exception("Exception iterating requests!")
+        call.cancel()
+        _abort(state, grpc.StatusCode.UNKNOWN, "Exception iterating requests!")
+        return
       serialized_request = _common.serialize(request, request_serializer)
       with state.condition:
         if state.code is None and not state.cancelled:
-- 
GitLab


From dd52a31337616fe935f79debfe5d56c6d73a4402 Mon Sep 17 00:00:00 2001
From: siddharthshukla <siddharthshukla@outlook.com>
Date: Wed, 23 Nov 2016 20:31:36 +0100
Subject: [PATCH 178/344] Replace Python unit test iterables by iterators

Cast iterables into iterators for stream based compression, empty
message, and metadata tests.
---
 src/python/grpcio_tests/tests/unit/_compression_test.py   | 2 +-
 src/python/grpcio_tests/tests/unit/_empty_message_test.py | 4 ++--
 src/python/grpcio_tests/tests/unit/_exit_scenarios.py     | 2 +-
 src/python/grpcio_tests/tests/unit/_metadata_test.py      | 4 ++--
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 83b9109466..4d3f02e917 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -125,7 +125,7 @@ class CompressionTest(unittest.TestCase):
     compressed_channel = grpc.insecure_channel('localhost:%d' % self._port,
         options=[('grpc.default_compression_algorithm', 1)])
     multi_callable = compressed_channel.stream_stream(_STREAM_STREAM)
-    call = multi_callable([request] * test_constants.STREAM_LENGTH)
+    call = multi_callable(iter([request] * test_constants.STREAM_LENGTH))
     for response in call:
       self.assertEqual(request, response)
 
diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
index 131f6e9452..69f4689279 100644
--- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
@@ -123,12 +123,12 @@ class EmptyMessageTest(unittest.TestCase):
 
   def testStreamUnary(self):
     response = self._channel.stream_unary(_STREAM_UNARY)(
-        [_REQUEST] * test_constants.STREAM_LENGTH)
+        iter([_REQUEST] * test_constants.STREAM_LENGTH))
     self.assertEqual(_RESPONSE, response)
 
   def testStreamStream(self):
     response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
-        [_REQUEST] * test_constants.STREAM_LENGTH)
+        iter([_REQUEST] * test_constants.STREAM_LENGTH))
     self.assertSequenceEqual(
         [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
 
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index b33802bf57..777527137f 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -240,7 +240,7 @@ if __name__ == '__main__':
       multi_callable = channel.stream_unary(method)
       future = multi_callable.future(infinite_request_iterator())
       result, call = multi_callable.with_call(
-          [REQUEST] * test_constants.STREAM_LENGTH)
+          iter([REQUEST] * test_constants.STREAM_LENGTH))
     elif (args.scenario == IN_FLIGHT_STREAM_STREAM_CALL or
           args.scenario == IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL):
       multi_callable = channel.stream_stream(method)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py
index da73476929..caba53ffcc 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py
@@ -193,7 +193,7 @@ class MetadataTest(unittest.TestCase):
   def testStreamUnary(self):
     multi_callable = self._channel.stream_unary(_STREAM_UNARY)
     unused_response, call = multi_callable.with_call(
-        [_REQUEST] * test_constants.STREAM_LENGTH,
+        iter([_REQUEST] * test_constants.STREAM_LENGTH),
         metadata=_CLIENT_METADATA)
     self.assertTrue(test_common.metadata_transmitted(
         _SERVER_INITIAL_METADATA, call.initial_metadata()))
@@ -202,7 +202,7 @@ class MetadataTest(unittest.TestCase):
 
   def testStreamStream(self):
     multi_callable = self._channel.stream_stream(_STREAM_STREAM)
-    call = multi_callable([_REQUEST] * test_constants.STREAM_LENGTH,
+    call = multi_callable(iter([_REQUEST] * test_constants.STREAM_LENGTH),
                           metadata=_CLIENT_METADATA)
     self.assertTrue(test_common.metadata_transmitted(
         _SERVER_INITIAL_METADATA, call.initial_metadata()))
-- 
GitLab


From 0702f628d70d9055159e8b90507d124d79e8e0a5 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 20 Dec 2016 12:44:36 -0800
Subject: [PATCH 179/344] Change grpcio_tools to grpcio-tools

This should address the difference in how we ask users to install
grpcio-tools and the files the user ends up downloading from PyPI.
---
 tools/distrib/python/grpcio_tools/setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index 581ecc40c0..502d7ef27b 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -184,7 +184,7 @@ def extension_modules():
     return extensions
 
 setuptools.setup(
-  name='grpcio_tools',
+  name='grpcio-tools',
   version=grpc_version.VERSION,
   license='3-clause BSD',
   ext_modules=extension_modules(),
-- 
GitLab


From 66c67827517120b0cf2115e4c9c8af60a24bf252 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Fri, 9 Dec 2016 10:22:50 -0800
Subject: [PATCH 180/344] add --perf_args usage to jenkins performance runner
 scripts

---
 tools/jenkins/run_performance_flamegraphs.sh | 56 ++++++++++++++++++++
 tools/jenkins/run_sweep_performance.sh       |  1 +
 tools/run_tests/run_performance_tests.py     | 15 +++---
 3 files changed, 65 insertions(+), 7 deletions(-)
 create mode 100755 tools/jenkins/run_performance_flamegraphs.sh

diff --git a/tools/jenkins/run_performance_flamegraphs.sh b/tools/jenkins/run_performance_flamegraphs.sh
new file mode 100755
index 0000000000..22081e2248
--- /dev/null
+++ b/tools/jenkins/run_performance_flamegraphs.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+# 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.
+#
+# This script is invoked by Jenkins and runs full performance test suite.
+set -ex
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../..
+
+# scalability with 32cores c++ benchmarks
+tools/run_tests/run_performance_tests.py \
+    -l c++ \
+    --category scalable \
+    --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \
+    --perf_args "record -F 97 --call-graph dwarf" \
+    --flame_graph_reports cpp_flamegraphs \
+    || EXIT_CODE=1
+
+# scalability with 32cores go benchmarks
+tools/run_tests/run_performance_tests.py \
+    -l go \
+    --category scalable \
+    --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \
+    --perf_args "record -F 97 -g" \
+    --flame_graph_reports go_flamegraphs \
+    || EXIT_CODE=1
+
+exit $EXIT_CODE
+
diff --git a/tools/jenkins/run_sweep_performance.sh b/tools/jenkins/run_sweep_performance.sh
index 3b22e25a45..12054dc3dc 100755
--- a/tools/jenkins/run_sweep_performance.sh
+++ b/tools/jenkins/run_sweep_performance.sh
@@ -43,6 +43,7 @@ tools/run_tests/run_performance_tests.py \
     --category sweep \
     --bq_result_table performance_test.performance_experiment_32core \
     --remote_worker_host ${SERVER_HOST} ${CLIENT_HOST1} ${CLIENT_HOST2} \
+    --perf_args "record -F 97 --call-graph dwarf" \
     || EXIT_CODE=1
 
 exit $EXIT_CODE
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index 69ccff85cf..06aa42756e 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -58,8 +58,6 @@ os.chdir(_ROOT)
 
 _REMOTE_HOST_USERNAME = 'jenkins'
 
-_PERF_REPORT_OUTPUT_DIR = 'perf_reports'
-
 
 class QpsWorkerJob:
   """Encapsulates a qps worker server job."""
@@ -300,11 +298,11 @@ def perf_report_processor_job(worker_host, perf_base_name, output_filename):
     user_at_host = "%s@%s" % (_REMOTE_HOST_USERNAME, worker_host)
     cmd = "USER_AT_HOST=%s OUTPUT_FILENAME=%s OUTPUT_DIR=%s PERF_BASE_NAME=%s\
          tools/run_tests/performance/process_remote_perf_flamegraphs.sh" \
-          % (user_at_host, output_filename, _PERF_REPORT_OUTPUT_DIR, perf_base_name)
+          % (user_at_host, output_filename, args.flame_graph_reports, perf_base_name)
   else:
     cmd = "OUTPUT_FILENAME=%s OUTPUT_DIR=%s PERF_BASE_NAME=%s\
           tools/run_tests/performance/process_local_perf_flamegraphs.sh" \
-          % (output_filename, _PERF_REPORT_OUTPUT_DIR, perf_base_name)
+          % (output_filename, args.flame_graph_reports, perf_base_name)
 
   return jobset.JobSpec(cmdline=cmd,
                         timeout_seconds=3*60,
@@ -469,7 +467,7 @@ argp.add_argument('--perf_args',
                         'with the arguments to perf specified here. '
                         '".svg" flame graph profiles will be '
                         'created for each Qps Worker on each scenario. '
-                        'Files will output to "<repo_root>/perf_reports" '
+                        'Files will output to "<repo_root>/<args.flame_graph_reports>" '
                         'directory. Output files from running the worker '
                         'under perf are saved in the repo root where its ran. '
                         'Note that the perf "-g" flag is necessary for '
@@ -489,6 +487,8 @@ argp.add_argument('--skip_generate_flamegraphs',
                   help=('Turn flame graph generation off. '
                         'May be useful if "perf_args" arguments do not make sense for '
                         'generating flamegraphs (e.g., "--perf_args=stat ...")'))
+argp.add_argument('-f', '--flame_graph_reports', default='perf_reports', type=str,
+                  help='Name of directory to output flame graph profiles to, if any are created.')
 
 
 args = argp.parse_args()
@@ -522,8 +522,9 @@ if not args.dry_run:
 
 perf_cmd = None
 if args.perf_args:
+  print('Running workers under perf profiler')
   # Expect /usr/bin/perf to be installed here, as is usual
-  perf_cmd = ['/usr/bin/perf'] 
+  perf_cmd = ['/usr/bin/perf']
   perf_cmd.extend(re.split('\s+', args.perf_args))
 
 qpsworker_jobs = create_qpsworkers(languages, args.remote_worker_host, perf_cmd=perf_cmd)
@@ -582,7 +583,7 @@ for scenario in scenarios:
 # 'profile_output_files' will only have names for scenarios that passed
 if perf_cmd and not args.skip_generate_flamegraphs:
   # write the index fil to the output dir, with all profiles from all scenarios/workers
-  report_utils.render_perf_profiling_results('%s/index.html' % _PERF_REPORT_OUTPUT_DIR, profile_output_files)
+  report_utils.render_perf_profiling_results('%s/index.html' % args.flame_graph_reports, profile_output_files)
 
 if total_scenario_failures > 0 or qps_workers_killed > 0:
   print('%s scenarios failed and %s qps worker jobs killed' % (total_scenario_failures, qps_workers_killed))
-- 
GitLab


From e955c1f2367288f5e7047e33c48ad55ad58a9c80 Mon Sep 17 00:00:00 2001
From: Dan Born <dborn@google.com>
Date: Tue, 20 Dec 2016 13:48:11 -0800
Subject: [PATCH 181/344] Method to expose the resource quota of a resource
 user

---
 src/core/lib/iomgr/resource_quota.c | 5 +++++
 src/core/lib/iomgr/resource_quota.h | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 213d29600c..74c6c3e0fb 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -695,6 +695,11 @@ grpc_resource_user *grpc_resource_user_create(
   return resource_user;
 }
 
+grpc_resource_quota *grpc_resource_user_quota(
+    grpc_resource_user *resource_user) {
+  return resource_user->resource_quota;
+}
+
 static void ru_ref_by(grpc_resource_user *resource_user, gpr_atm amount) {
   GPR_ASSERT(amount > 0);
   GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&resource_user->refs, amount) != 0);
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 0181fd978b..14475c864e 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -88,6 +88,8 @@ typedef struct grpc_resource_user grpc_resource_user;
 
 grpc_resource_user *grpc_resource_user_create(
     grpc_resource_quota *resource_quota, const char *name);
+grpc_resource_quota *grpc_resource_user_quota(
+    grpc_resource_user *resource_user);
 void grpc_resource_user_ref(grpc_resource_user *resource_user);
 void grpc_resource_user_unref(grpc_exec_ctx *exec_ctx,
                               grpc_resource_user *resource_user);
-- 
GitLab


From eb69c34f8345a8777c894b35a4211caed20132a4 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Tue, 20 Dec 2016 16:32:50 -0800
Subject: [PATCH 182/344] attach trailing metadata to ruby bidi call op when
 it's received

---
 src/ruby/lib/grpc/generic/bidi_call.rb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index d7cd9e6df2..e6ea7d8697 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -200,6 +200,7 @@ module GRPC
             if is_client
               batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
               @call.status = batch_result.status
+              @call.trailing_metadata = @call.status.metadata if @call.status
               batch_result.check_status
               GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
             end
-- 
GitLab


From 4873d30ea2f3eedef161496f13152745f553e0c1 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Mon, 19 Dec 2016 15:58:15 -0800
Subject: [PATCH 183/344] allow disable core_list setting and override qps
 server in benchmarks

---
 test/cpp/qps/driver.cc          | 84 +++++++++++++++++++--------------
 test/cpp/qps/driver.h           |  4 +-
 test/cpp/qps/qps_json_driver.cc | 18 +++++--
 3 files changed, 64 insertions(+), 42 deletions(-)

diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 22b2cd080d..3e509e2abd 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -195,7 +195,8 @@ static void postprocess_scenario_result(ScenarioResult* result) {
 std::unique_ptr<ScenarioResult> RunScenario(
     const ClientConfig& initial_client_config, size_t num_clients,
     const ServerConfig& initial_server_config, size_t num_servers,
-    int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count) {
+    int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
+    const char* qps_server_target_override, bool configure_core_lists) {
   // Log everything from the driver
   gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
 
@@ -241,9 +242,6 @@ std::unique_ptr<ScenarioResult> RunScenario(
     }
   }
 
-  // Setup the hosts and core counts
-  auto hosts_cores = get_hosts_and_cores(workers);
-
   // if num_clients is set to <=0, do dynamic sizing: all workers
   // except for servers are clients
   if (num_clients <= 0) {
@@ -264,6 +262,11 @@ std::unique_ptr<ScenarioResult> RunScenario(
     unique_ptr<ClientReaderWriter<ServerArgs, ServerStatus>> stream;
   };
   std::vector<ServerData> servers(num_servers);
+  std::unordered_map<string, std::deque<int>> hosts_cores;
+
+  if (configure_core_lists) {
+    hosts_cores = get_hosts_and_cores(workers);
+  }
   for (size_t i = 0; i < num_servers; i++) {
     gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
             workers[i].c_str(), i);
@@ -271,37 +274,36 @@ std::unique_ptr<ScenarioResult> RunScenario(
         CreateChannel(workers[i], InsecureChannelCredentials()));
 
     ServerConfig server_config = initial_server_config;
-    char* host;
-    char* driver_port;
-    char* cli_target;
-    gpr_split_host_port(workers[i].c_str(), &host, &driver_port);
-    string host_str(host);
     int server_core_limit = initial_server_config.core_limit();
     int client_core_limit = initial_client_config.core_limit();
 
-    if (server_core_limit == 0 && client_core_limit > 0) {
-      // In this case, limit the server cores if it matches the
-      // same host as one or more clients
-      const auto& dq = hosts_cores.at(host_str);
-      bool match = false;
-      int limit = dq.size();
-      for (size_t cli = 0; cli < num_clients; cli++) {
-        if (host_str == get_host(workers[cli + num_servers])) {
-          limit -= client_core_limit;
-          match = true;
+    if (configure_core_lists) {
+      string host_str(get_host(workers[i]));
+      if (server_core_limit == 0 && client_core_limit > 0) {
+        // In this case, limit the server cores if it matches the
+        // same host as one or more clients
+        const auto& dq = hosts_cores.at(host_str);
+        bool match = false;
+        int limit = dq.size();
+        for (size_t cli = 0; cli < num_clients; cli++) {
+          if (host_str == get_host(workers[cli + num_servers])) {
+            limit -= client_core_limit;
+            match = true;
+          }
+        }
+        if (match) {
+          GPR_ASSERT(limit > 0);
+          server_core_limit = limit;
         }
       }
-      if (match) {
-        GPR_ASSERT(limit > 0);
-        server_core_limit = limit;
-      }
-    }
-    if (server_core_limit > 0) {
-      auto& dq = hosts_cores.at(host_str);
-      GPR_ASSERT(dq.size() >= static_cast<size_t>(server_core_limit));
-      for (int core = 0; core < server_core_limit; core++) {
-        server_config.add_core_list(dq.front());
-        dq.pop_front();
+      if (server_core_limit > 0) {
+        auto& dq = hosts_cores.at(host_str);
+        GPR_ASSERT(dq.size() >= static_cast<size_t>(server_core_limit));
+        gpr_log(GPR_INFO, "Setting server core_list");
+        for (int core = 0; core < server_core_limit; core++) {
+          server_config.add_core_list(dq.front());
+          dq.pop_front();
+        }
       }
     }
 
@@ -315,11 +317,19 @@ std::unique_ptr<ScenarioResult> RunScenario(
     if (!servers[i].stream->Read(&init_status)) {
       gpr_log(GPR_ERROR, "Server %zu did not yield initial status", i);
     }
-    gpr_join_host_port(&cli_target, host, init_status.port());
-    client_config.add_server_targets(cli_target);
-    gpr_free(host);
-    gpr_free(driver_port);
-    gpr_free(cli_target);
+    if (qps_server_target_override != NULL &&
+        strlen(qps_server_target_override) > 0) {
+      // overriding the qps server target only works if there is 1 server
+      GPR_ASSERT(num_servers == 1);
+      client_config.add_server_targets(qps_server_target_override);
+    } else {
+      std::string host;
+      char* cli_target;
+      host = get_host(workers[i]);
+      gpr_join_host_port(&cli_target, host.c_str(), init_status.port());
+      client_config.add_server_targets(cli_target);
+      gpr_free(cli_target);
+    }
   }
 
   // Targets are all set by now
@@ -341,7 +351,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
 
     int server_core_limit = initial_server_config.core_limit();
     int client_core_limit = initial_client_config.core_limit();
-    if ((server_core_limit > 0) || (client_core_limit > 0)) {
+    if (configure_core_lists &&
+        ((server_core_limit > 0) || (client_core_limit > 0))) {
       auto& dq = hosts_cores.at(get_host(worker));
       if (client_core_limit == 0) {
         // limit client cores if it matches a server host
@@ -359,6 +370,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
       }
       if (client_core_limit > 0) {
         GPR_ASSERT(dq.size() >= static_cast<size_t>(client_core_limit));
+        gpr_log(GPR_INFO, "Setting client core_list");
         for (int core = 0; core < client_core_limit; core++) {
           per_client_config.add_core_list(dq.front());
           dq.pop_front();
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index 93f4370caf..b5c8152e1b 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -45,7 +45,9 @@ namespace testing {
 std::unique_ptr<ScenarioResult> RunScenario(
     const grpc::testing::ClientConfig& client_config, size_t num_clients,
     const grpc::testing::ServerConfig& server_config, size_t num_servers,
-    int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count);
+    int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
+    const char* qps_server_target_override = "",
+    bool configure_core_lists = true);
 
 bool RunQuit();
 }  // namespace testing
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index 31b5917fb7..da835b995a 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -67,17 +67,25 @@ DEFINE_double(error_tolerance, 0.01,
               "range is narrower than the error_tolerance computed range, we "
               "stop the search.");
 
+DEFINE_string(qps_server_target_override, "",
+              "Override QPS server target to configure in client configs."
+              "Only applicable if there is a single benchmark server.");
+DEFINE_bool(configure_core_lists, true,
+            "Provide 'core_list' parameters to workers. Value determined "
+            "by cores available and 'core_limit' parameters of the scenarios.");
+
 namespace grpc {
 namespace testing {
 
 static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
                                                     bool* success) {
   std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
-  auto result =
-      RunScenario(scenario.client_config(), scenario.num_clients(),
-                  scenario.server_config(), scenario.num_servers(),
-                  scenario.warmup_seconds(), scenario.benchmark_seconds(),
-                  scenario.spawn_local_worker_count());
+  auto result = RunScenario(
+      scenario.client_config(), scenario.num_clients(),
+      scenario.server_config(), scenario.num_servers(),
+      scenario.warmup_seconds(), scenario.benchmark_seconds(),
+      scenario.spawn_local_worker_count(),
+      FLAGS_qps_server_target_override.c_str(), FLAGS_configure_core_lists);
 
   // Amend the result with scenario config. Eventually we should adjust
   // RunScenario contract so we don't need to touch the result here.
-- 
GitLab


From 9f89107f1741278d16e2b39651293f5bf77380b7 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 21 Dec 2016 12:19:14 +0100
Subject: [PATCH 184/344] better qps_json_driver message when QPS_WORKERS env
 is missing

---
 test/cpp/qps/driver.cc | 44 +++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 3e509e2abd..93ef32db77 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -44,6 +44,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/support/env.h"
@@ -99,23 +100,36 @@ static std::unordered_map<string, std::deque<int>> get_hosts_and_cores(
   return hosts;
 }
 
-static deque<string> get_workers(const string& name) {
-  char* env = gpr_getenv(name.c_str());
-  if (!env || strlen(env) == 0) return deque<string>();
-
+static deque<string> get_workers(const string& env_name) {
+  char* env = gpr_getenv(env_name.c_str());
+  if (!env) {
+    env = gpr_strdup("");
+  }
   deque<string> out;
   char* p = env;
-  for (;;) {
-    char* comma = strchr(p, ',');
-    if (comma) {
-      out.emplace_back(p, comma);
-      p = comma + 1;
-    } else {
-      out.emplace_back(p);
-      gpr_free(env);
-      return out;
+  if (strlen(env) != 0) {
+    for (;;) {
+      char* comma = strchr(p, ',');
+      if (comma) {
+        out.emplace_back(p, comma);
+        p = comma + 1;
+      } else {
+        out.emplace_back(p);
+        break;
+      }
     }
   }
+  if (out.size() == 0) {
+    gpr_log(GPR_ERROR,
+            "Environment variable \"%s\" does not contain a list of QPS "
+            "workers to use. Set it to a comma-separated list of "
+            "hostname:port pairs, starting with hosts that should act as "
+            "servers. E.g. export "
+            "%s=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\"",
+            env_name.c_str(), env_name.c_str());
+  }
+  gpr_free(env);
+  return out;
 }
 
 // helpers for postprocess_scenario_result
@@ -241,6 +255,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
       workers.push_back(addr);
     }
   }
+  GPR_ASSERT(workers.size() != 0);
 
   // if num_clients is set to <=0, do dynamic sizing: all workers
   // except for servers are clients
@@ -560,6 +575,9 @@ bool RunQuit() {
   // Get client, server lists
   bool result = true;
   auto workers = get_workers("QPS_WORKERS");
+  if (workers.size() == 0) {
+    return false;
+  }
   for (size_t i = 0; i < workers.size(); i++) {
     auto stub = WorkerService::NewStub(
         CreateChannel(workers[i], InsecureChannelCredentials()));
-- 
GitLab


From c15ee83882dad131b7ff9c71e29ec9cc1663781e Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Thu, 15 Dec 2016 22:58:29 +0000
Subject: [PATCH 185/344] Update Python examples with fresh generated code

---
 examples/python/helloworld/greeter_client.py  |   3 +-
 examples/python/helloworld/greeter_server.py  |   5 +-
 examples/python/helloworld/helloworld_pb2.py  | 193 ++++---
 .../python/helloworld/helloworld_pb2_grpc.py  |  47 ++
 examples/python/multiplex/helloworld_pb2.py   | 193 ++++---
 .../python/multiplex/helloworld_pb2_grpc.py   |  47 ++
 examples/python/multiplex/multiplex_client.py |   6 +-
 examples/python/multiplex/multiplex_server.py |  10 +-
 examples/python/multiplex/route_guide_pb2.py  | 485 +++++++++---------
 .../python/multiplex/route_guide_pb2_grpc.py  | 114 ++++
 examples/python/multiplex/run_codegen.py      |   0
 .../python/route_guide/route_guide_client.py  |   3 +-
 .../python/route_guide/route_guide_pb2.py     | 485 +++++++++---------
 .../route_guide/route_guide_pb2_grpc.py       | 114 ++++
 .../python/route_guide/route_guide_server.py  |   5 +-
 15 files changed, 1070 insertions(+), 640 deletions(-)
 create mode 100644 examples/python/helloworld/helloworld_pb2_grpc.py
 create mode 100644 examples/python/multiplex/helloworld_pb2_grpc.py
 create mode 100644 examples/python/multiplex/route_guide_pb2_grpc.py
 mode change 100755 => 100644 examples/python/multiplex/run_codegen.py
 create mode 100644 examples/python/route_guide/route_guide_pb2_grpc.py

diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py
index 44d42c102b..281a68f3c3 100644
--- a/examples/python/helloworld/greeter_client.py
+++ b/examples/python/helloworld/greeter_client.py
@@ -34,11 +34,12 @@ from __future__ import print_function
 import grpc
 
 import helloworld_pb2
+import helloworld_pb2_grpc
 
 
 def run():
   channel = grpc.insecure_channel('localhost:50051')
-  stub = helloworld_pb2.GreeterStub(channel)
+  stub = helloworld_pb2_grpc.GreeterStub(channel)
   response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
   print("Greeter client received: " + response.message)
 
diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py
index 37d8bd49cc..0afc21d243 100644
--- a/examples/python/helloworld/greeter_server.py
+++ b/examples/python/helloworld/greeter_server.py
@@ -35,11 +35,12 @@ import time
 import grpc
 
 import helloworld_pb2
+import helloworld_pb2_grpc
 
 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
 
 
-class Greeter(helloworld_pb2.GreeterServicer):
+class Greeter(helloworld_pb2_grpc.GreeterServicer):
 
   def SayHello(self, request, context):
     return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
@@ -47,7 +48,7 @@ class Greeter(helloworld_pb2.GreeterServicer):
 
 def serve():
   server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-  helloworld_pb2.add_GreeterServicer_to_server(Greeter(), server)
+  helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
   server.add_insecure_port('[::]:50051')
   server.start()
   try:
diff --git a/examples/python/helloworld/helloworld_pb2.py b/examples/python/helloworld/helloworld_pb2.py
index 3ce33fbf2b..6665b1f687 100644
--- a/examples/python/helloworld/helloworld_pb2.py
+++ b/examples/python/helloworld/helloworld_pb2.py
@@ -107,98 +107,123 @@ _sym_db.RegisterMessage(HelloReply)
 
 DESCRIPTOR.has_options = True
 DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
-import grpc
-from grpc.beta import implementations as beta_implementations
-from grpc.beta import interfaces as beta_interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
+try:
+  # THESE ELEMENTS WILL BE DEPRECATED.
+  # Please use the generated *_pb2_grpc.py files instead.
+  import grpc
+  from grpc.framework.common import cardinality
+  from grpc.framework.interfaces.face import utilities as face_utilities
+  from grpc.beta import implementations as beta_implementations
+  from grpc.beta import interfaces as beta_interfaces
+
+
+  class GreeterStub(object):
+    """The greeting service definition.
+    """
 
+    def __init__(self, channel):
+      """Constructor.
 
-class GreeterStub(object):
-  """The greeting service definition.
-  """
+      Args:
+        channel: A grpc.Channel.
+      """
+      self.SayHello = channel.unary_unary(
+          '/helloworld.Greeter/SayHello',
+          request_serializer=HelloRequest.SerializeToString,
+          response_deserializer=HelloReply.FromString,
+          )
 
-  def __init__(self, channel):
-    """Constructor.
 
-    Args:
-      channel: A grpc.Channel.
+  class GreeterServicer(object):
+    """The greeting service definition.
     """
-    self.SayHello = channel.unary_unary(
-        '/helloworld.Greeter/SayHello',
-        request_serializer=HelloRequest.SerializeToString,
-        response_deserializer=HelloReply.FromString,
-        )
-
-
-class GreeterServicer(object):
-  """The greeting service definition.
-  """
 
-  def SayHello(self, request, context):
-    """Sends a greeting
+    def SayHello(self, request, context):
+      """Sends a greeting
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+
+  def add_GreeterServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+        'SayHello': grpc.unary_unary_rpc_method_handler(
+            servicer.SayHello,
+            request_deserializer=HelloRequest.FromString,
+            response_serializer=HelloReply.SerializeToString,
+        ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+        'helloworld.Greeter', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+  class BetaGreeterServicer(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """The greeting service definition.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_GreeterServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'SayHello': grpc.unary_unary_rpc_method_handler(
-          servicer.SayHello,
-          request_deserializer=HelloRequest.FromString,
-          response_serializer=HelloReply.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'helloworld.Greeter', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-
-
-class BetaGreeterServicer(object):
-  """The greeting service definition.
-  """
-  def SayHello(self, request, context):
-    """Sends a greeting
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def SayHello(self, request, context):
+      """Sends a greeting
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
 
+  class BetaGreeterStub(object):
+    """The Beta API is deprecated for 0.15.0 and later.
 
-class BetaGreeterStub(object):
-  """The greeting service definition.
-  """
-  def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """Sends a greeting
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """The greeting service definition.
     """
-    raise NotImplementedError()
-  SayHello.future = None
-
-
-def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
-  request_deserializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
-  }
-  response_serializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
-  }
-  method_implementations = {
-    ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
-  }
-  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
-  return beta_implementations.server(method_implementations, options=server_options)
-
-
-def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
-  request_serializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
-  }
-  response_deserializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
-  }
-  cardinalities = {
-    'SayHello': cardinality.Cardinality.UNARY_UNARY,
-  }
-  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
-  return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
+    def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Sends a greeting
+      """
+      raise NotImplementedError()
+    SayHello.future = None
+
+
+  def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_deserializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
+    }
+    response_serializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
+    }
+    method_implementations = {
+      ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
+    }
+    server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+    return beta_implementations.server(method_implementations, options=server_options)
+
+
+  def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_serializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
+    }
+    response_deserializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
+    }
+    cardinalities = {
+      'SayHello': cardinality.Cardinality.UNARY_UNARY,
+    }
+    stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+    return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
+except ImportError:
+  pass
 # @@protoc_insertion_point(module_scope)
diff --git a/examples/python/helloworld/helloworld_pb2_grpc.py b/examples/python/helloworld/helloworld_pb2_grpc.py
new file mode 100644
index 0000000000..682dc36cd8
--- /dev/null
+++ b/examples/python/helloworld/helloworld_pb2_grpc.py
@@ -0,0 +1,47 @@
+import grpc
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+import helloworld_pb2 as helloworld__pb2
+
+
+class GreeterStub(object):
+  """The greeting service definition.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.SayHello = channel.unary_unary(
+        '/helloworld.Greeter/SayHello',
+        request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
+        response_deserializer=helloworld__pb2.HelloReply.FromString,
+        )
+
+
+class GreeterServicer(object):
+  """The greeting service definition.
+  """
+
+  def SayHello(self, request, context):
+    """Sends a greeting
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_GreeterServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'SayHello': grpc.unary_unary_rpc_method_handler(
+          servicer.SayHello,
+          request_deserializer=helloworld__pb2.HelloRequest.FromString,
+          response_serializer=helloworld__pb2.HelloReply.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'helloworld.Greeter', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/examples/python/multiplex/helloworld_pb2.py b/examples/python/multiplex/helloworld_pb2.py
index 3ce33fbf2b..6665b1f687 100644
--- a/examples/python/multiplex/helloworld_pb2.py
+++ b/examples/python/multiplex/helloworld_pb2.py
@@ -107,98 +107,123 @@ _sym_db.RegisterMessage(HelloReply)
 
 DESCRIPTOR.has_options = True
 DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
-import grpc
-from grpc.beta import implementations as beta_implementations
-from grpc.beta import interfaces as beta_interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
+try:
+  # THESE ELEMENTS WILL BE DEPRECATED.
+  # Please use the generated *_pb2_grpc.py files instead.
+  import grpc
+  from grpc.framework.common import cardinality
+  from grpc.framework.interfaces.face import utilities as face_utilities
+  from grpc.beta import implementations as beta_implementations
+  from grpc.beta import interfaces as beta_interfaces
+
+
+  class GreeterStub(object):
+    """The greeting service definition.
+    """
 
+    def __init__(self, channel):
+      """Constructor.
 
-class GreeterStub(object):
-  """The greeting service definition.
-  """
+      Args:
+        channel: A grpc.Channel.
+      """
+      self.SayHello = channel.unary_unary(
+          '/helloworld.Greeter/SayHello',
+          request_serializer=HelloRequest.SerializeToString,
+          response_deserializer=HelloReply.FromString,
+          )
 
-  def __init__(self, channel):
-    """Constructor.
 
-    Args:
-      channel: A grpc.Channel.
+  class GreeterServicer(object):
+    """The greeting service definition.
     """
-    self.SayHello = channel.unary_unary(
-        '/helloworld.Greeter/SayHello',
-        request_serializer=HelloRequest.SerializeToString,
-        response_deserializer=HelloReply.FromString,
-        )
-
-
-class GreeterServicer(object):
-  """The greeting service definition.
-  """
 
-  def SayHello(self, request, context):
-    """Sends a greeting
+    def SayHello(self, request, context):
+      """Sends a greeting
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+
+  def add_GreeterServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+        'SayHello': grpc.unary_unary_rpc_method_handler(
+            servicer.SayHello,
+            request_deserializer=HelloRequest.FromString,
+            response_serializer=HelloReply.SerializeToString,
+        ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+        'helloworld.Greeter', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+  class BetaGreeterServicer(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """The greeting service definition.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_GreeterServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'SayHello': grpc.unary_unary_rpc_method_handler(
-          servicer.SayHello,
-          request_deserializer=HelloRequest.FromString,
-          response_serializer=HelloReply.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'helloworld.Greeter', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-
-
-class BetaGreeterServicer(object):
-  """The greeting service definition.
-  """
-  def SayHello(self, request, context):
-    """Sends a greeting
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def SayHello(self, request, context):
+      """Sends a greeting
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
 
+  class BetaGreeterStub(object):
+    """The Beta API is deprecated for 0.15.0 and later.
 
-class BetaGreeterStub(object):
-  """The greeting service definition.
-  """
-  def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """Sends a greeting
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """The greeting service definition.
     """
-    raise NotImplementedError()
-  SayHello.future = None
-
-
-def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
-  request_deserializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
-  }
-  response_serializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
-  }
-  method_implementations = {
-    ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
-  }
-  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
-  return beta_implementations.server(method_implementations, options=server_options)
-
-
-def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
-  request_serializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
-  }
-  response_deserializers = {
-    ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
-  }
-  cardinalities = {
-    'SayHello': cardinality.Cardinality.UNARY_UNARY,
-  }
-  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
-  return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
+    def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Sends a greeting
+      """
+      raise NotImplementedError()
+    SayHello.future = None
+
+
+  def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_deserializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
+    }
+    response_serializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
+    }
+    method_implementations = {
+      ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
+    }
+    server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+    return beta_implementations.server(method_implementations, options=server_options)
+
+
+  def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_serializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
+    }
+    response_deserializers = {
+      ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
+    }
+    cardinalities = {
+      'SayHello': cardinality.Cardinality.UNARY_UNARY,
+    }
+    stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+    return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
+except ImportError:
+  pass
 # @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/helloworld_pb2_grpc.py b/examples/python/multiplex/helloworld_pb2_grpc.py
new file mode 100644
index 0000000000..682dc36cd8
--- /dev/null
+++ b/examples/python/multiplex/helloworld_pb2_grpc.py
@@ -0,0 +1,47 @@
+import grpc
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+import helloworld_pb2 as helloworld__pb2
+
+
+class GreeterStub(object):
+  """The greeting service definition.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.SayHello = channel.unary_unary(
+        '/helloworld.Greeter/SayHello',
+        request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
+        response_deserializer=helloworld__pb2.HelloReply.FromString,
+        )
+
+
+class GreeterServicer(object):
+  """The greeting service definition.
+  """
+
+  def SayHello(self, request, context):
+    """Sends a greeting
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_GreeterServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'SayHello': grpc.unary_unary_rpc_method_handler(
+          servicer.SayHello,
+          request_deserializer=helloworld__pb2.HelloRequest.FromString,
+          response_serializer=helloworld__pb2.HelloReply.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'helloworld.Greeter', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py
index 2e8162926b..b2d2021e02 100644
--- a/examples/python/multiplex/multiplex_client.py
+++ b/examples/python/multiplex/multiplex_client.py
@@ -37,7 +37,9 @@ import time
 import grpc
 
 import helloworld_pb2
+import helloworld_pb2_grpc
 import route_guide_pb2
+import route_guide_pb2_grpc
 import route_guide_resources
 
 
@@ -120,8 +122,8 @@ def guide_route_chat(route_guide_stub):
 
 def run():
   channel = grpc.insecure_channel('localhost:50051')
-  greeter_stub = helloworld_pb2.GreeterStub(channel)
-  route_guide_stub = route_guide_pb2.RouteGuideStub(channel)
+  greeter_stub = helloworld_pb2_grpc.GreeterStub(channel)
+  route_guide_stub = route_guide_pb2_grpc.RouteGuideStub(channel)
   greeter_response = greeter_stub.SayHello(
       helloworld_pb2.HelloRequest(name='you'))
   print("Greeter client received: " + greeter_response.message)
diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py
index 32a4ee4a49..b8b32e7bf8 100644
--- a/examples/python/multiplex/multiplex_server.py
+++ b/examples/python/multiplex/multiplex_server.py
@@ -36,7 +36,9 @@ import math
 import grpc
 
 import helloworld_pb2
+import helloworld_pb2_grpc
 import route_guide_pb2
+import route_guide_pb2_grpc
 import route_guide_resources
 
 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -70,13 +72,13 @@ def _get_distance(start, end):
   return R * c;
 
 
-class _GreeterServicer(helloworld_pb2.GreeterServicer):
+class _GreeterServicer(helloworld_pb2_grpc.GreeterServicer):
 
   def SayHello(self, request, context):
     return helloworld_pb2.HelloReply(message='Hello, {}!'.format(request.name))
 
 
-class _RouteGuideServicer(route_guide_pb2.RouteGuideServicer):
+class _RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
   """Provides methods that implement functionality of route guide server."""
 
   def __init__(self):
@@ -133,8 +135,8 @@ class _RouteGuideServicer(route_guide_pb2.RouteGuideServicer):
 
 def serve():
   server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-  helloworld_pb2.add_GreeterServicer_to_server(_GreeterServicer(), server)
-  route_guide_pb2.add_RouteGuideServicer_to_server(
+  helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer(), server)
+  route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
       _RouteGuideServicer(), server)
   server.add_insecure_port('[::]:50051')
   server.start()
diff --git a/examples/python/multiplex/route_guide_pb2.py b/examples/python/multiplex/route_guide_pb2.py
index 924e186e06..e6775eb814 100644
--- a/examples/python/multiplex/route_guide_pb2.py
+++ b/examples/python/multiplex/route_guide_pb2.py
@@ -277,240 +277,265 @@ _sym_db.RegisterMessage(RouteSummary)
 
 DESCRIPTOR.has_options = True
 DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG'))
-import grpc
-from grpc.beta import implementations as beta_implementations
-from grpc.beta import interfaces as beta_interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
-
-
-class RouteGuideStub(object):
-  """Interface exported by the server.
-  """
-
-  def __init__(self, channel):
-    """Constructor.
-
-    Args:
-      channel: A grpc.Channel.
+try:
+  # THESE ELEMENTS WILL BE DEPRECATED.
+  # Please use the generated *_pb2_grpc.py files instead.
+  import grpc
+  from grpc.framework.common import cardinality
+  from grpc.framework.interfaces.face import utilities as face_utilities
+  from grpc.beta import implementations as beta_implementations
+  from grpc.beta import interfaces as beta_interfaces
+
+
+  class RouteGuideStub(object):
+    """Interface exported by the server.
     """
-    self.GetFeature = channel.unary_unary(
-        '/routeguide.RouteGuide/GetFeature',
-        request_serializer=Point.SerializeToString,
-        response_deserializer=Feature.FromString,
-        )
-    self.ListFeatures = channel.unary_stream(
-        '/routeguide.RouteGuide/ListFeatures',
-        request_serializer=Rectangle.SerializeToString,
-        response_deserializer=Feature.FromString,
-        )
-    self.RecordRoute = channel.stream_unary(
-        '/routeguide.RouteGuide/RecordRoute',
-        request_serializer=Point.SerializeToString,
-        response_deserializer=RouteSummary.FromString,
-        )
-    self.RouteChat = channel.stream_stream(
-        '/routeguide.RouteGuide/RouteChat',
-        request_serializer=RouteNote.SerializeToString,
-        response_deserializer=RouteNote.FromString,
-        )
-
-
-class RouteGuideServicer(object):
-  """Interface exported by the server.
-  """
-
-  def GetFeature(self, request, context):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def ListFeatures(self, request, context):
-    """A server-to-client streaming RPC.
 
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
+    def __init__(self, channel):
+      """Constructor.
+
+      Args:
+        channel: A grpc.Channel.
+      """
+      self.GetFeature = channel.unary_unary(
+          '/routeguide.RouteGuide/GetFeature',
+          request_serializer=Point.SerializeToString,
+          response_deserializer=Feature.FromString,
+          )
+      self.ListFeatures = channel.unary_stream(
+          '/routeguide.RouteGuide/ListFeatures',
+          request_serializer=Rectangle.SerializeToString,
+          response_deserializer=Feature.FromString,
+          )
+      self.RecordRoute = channel.stream_unary(
+          '/routeguide.RouteGuide/RecordRoute',
+          request_serializer=Point.SerializeToString,
+          response_deserializer=RouteSummary.FromString,
+          )
+      self.RouteChat = channel.stream_stream(
+          '/routeguide.RouteGuide/RouteChat',
+          request_serializer=RouteNote.SerializeToString,
+          response_deserializer=RouteNote.FromString,
+          )
+
+
+  class RouteGuideServicer(object):
+    """Interface exported by the server.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def RecordRoute(self, request_iterator, context):
-    """A client-to-server streaming RPC.
 
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
+    def GetFeature(self, request, context):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def ListFeatures(self, request, context):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def RecordRoute(self, request_iterator, context):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def RouteChat(self, request_iterator, context):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+
+  def add_RouteGuideServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+        'GetFeature': grpc.unary_unary_rpc_method_handler(
+            servicer.GetFeature,
+            request_deserializer=Point.FromString,
+            response_serializer=Feature.SerializeToString,
+        ),
+        'ListFeatures': grpc.unary_stream_rpc_method_handler(
+            servicer.ListFeatures,
+            request_deserializer=Rectangle.FromString,
+            response_serializer=Feature.SerializeToString,
+        ),
+        'RecordRoute': grpc.stream_unary_rpc_method_handler(
+            servicer.RecordRoute,
+            request_deserializer=Point.FromString,
+            response_serializer=RouteSummary.SerializeToString,
+        ),
+        'RouteChat': grpc.stream_stream_rpc_method_handler(
+            servicer.RouteChat,
+            request_deserializer=RouteNote.FromString,
+            response_serializer=RouteNote.SerializeToString,
+        ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+        'routeguide.RouteGuide', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+  class BetaRouteGuideServicer(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """Interface exported by the server.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def RouteChat(self, request_iterator, context):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_RouteGuideServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'GetFeature': grpc.unary_unary_rpc_method_handler(
-          servicer.GetFeature,
-          request_deserializer=Point.FromString,
-          response_serializer=Feature.SerializeToString,
-      ),
-      'ListFeatures': grpc.unary_stream_rpc_method_handler(
-          servicer.ListFeatures,
-          request_deserializer=Rectangle.FromString,
-          response_serializer=Feature.SerializeToString,
-      ),
-      'RecordRoute': grpc.stream_unary_rpc_method_handler(
-          servicer.RecordRoute,
-          request_deserializer=Point.FromString,
-          response_serializer=RouteSummary.SerializeToString,
-      ),
-      'RouteChat': grpc.stream_stream_rpc_method_handler(
-          servicer.RouteChat,
-          request_deserializer=RouteNote.FromString,
-          response_serializer=RouteNote.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'routeguide.RouteGuide', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-
-
-class BetaRouteGuideServicer(object):
-  """Interface exported by the server.
-  """
-  def GetFeature(self, request, context):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def ListFeatures(self, request, context):
-    """A server-to-client streaming RPC.
-
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def RecordRoute(self, request_iterator, context):
-    """A client-to-server streaming RPC.
-
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def RouteChat(self, request_iterator, context):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-
-
-class BetaRouteGuideStub(object):
-  """Interface exported by the server.
-  """
-  def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    raise NotImplementedError()
-  GetFeature.future = None
-  def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A server-to-client streaming RPC.
-
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
-    """
-    raise NotImplementedError()
-  def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A client-to-server streaming RPC.
-
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
-    """
-    raise NotImplementedError()
-  RecordRoute.future = None
-  def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
+    def GetFeature(self, request, context):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def ListFeatures(self, request, context):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def RecordRoute(self, request_iterator, context):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def RouteChat(self, request_iterator, context):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+  class BetaRouteGuideStub(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """Interface exported by the server.
     """
-    raise NotImplementedError()
-
-
-def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
-  request_deserializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
-    ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
-  }
-  response_serializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
-    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
-  }
-  method_implementations = {
-    ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
-    ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
-    ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
-    ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
-  }
-  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
-  return beta_implementations.server(method_implementations, options=server_options)
-
-
-def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
-  request_serializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
-    ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
-  }
-  response_deserializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
-    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
-  }
-  cardinalities = {
-    'GetFeature': cardinality.Cardinality.UNARY_UNARY,
-    'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
-    'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
-    'RouteChat': cardinality.Cardinality.STREAM_STREAM,
-  }
-  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
-  return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
+    def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      raise NotImplementedError()
+    GetFeature.future = None
+    def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      raise NotImplementedError()
+    def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      raise NotImplementedError()
+    RecordRoute.future = None
+    def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      raise NotImplementedError()
+
+
+  def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_deserializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
+      ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+    }
+    response_serializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
+      ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+    }
+    method_implementations = {
+      ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
+      ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
+      ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
+      ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
+    }
+    server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+    return beta_implementations.server(method_implementations, options=server_options)
+
+
+  def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_serializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
+      ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+    }
+    response_deserializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
+      ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+    }
+    cardinalities = {
+      'GetFeature': cardinality.Cardinality.UNARY_UNARY,
+      'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
+      'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
+      'RouteChat': cardinality.Cardinality.STREAM_STREAM,
+    }
+    stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+    return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
+except ImportError:
+  pass
 # @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/route_guide_pb2_grpc.py b/examples/python/multiplex/route_guide_pb2_grpc.py
new file mode 100644
index 0000000000..27b24c747d
--- /dev/null
+++ b/examples/python/multiplex/route_guide_pb2_grpc.py
@@ -0,0 +1,114 @@
+import grpc
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+import route_guide_pb2 as route__guide__pb2
+
+
+class RouteGuideStub(object):
+  """Interface exported by the server.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.GetFeature = channel.unary_unary(
+        '/routeguide.RouteGuide/GetFeature',
+        request_serializer=route__guide__pb2.Point.SerializeToString,
+        response_deserializer=route__guide__pb2.Feature.FromString,
+        )
+    self.ListFeatures = channel.unary_stream(
+        '/routeguide.RouteGuide/ListFeatures',
+        request_serializer=route__guide__pb2.Rectangle.SerializeToString,
+        response_deserializer=route__guide__pb2.Feature.FromString,
+        )
+    self.RecordRoute = channel.stream_unary(
+        '/routeguide.RouteGuide/RecordRoute',
+        request_serializer=route__guide__pb2.Point.SerializeToString,
+        response_deserializer=route__guide__pb2.RouteSummary.FromString,
+        )
+    self.RouteChat = channel.stream_stream(
+        '/routeguide.RouteGuide/RouteChat',
+        request_serializer=route__guide__pb2.RouteNote.SerializeToString,
+        response_deserializer=route__guide__pb2.RouteNote.FromString,
+        )
+
+
+class RouteGuideServicer(object):
+  """Interface exported by the server.
+  """
+
+  def GetFeature(self, request, context):
+    """A simple RPC.
+
+    Obtains the feature at a given position.
+
+    A feature with an empty name is returned if there's no feature at the given
+    position.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def ListFeatures(self, request, context):
+    """A server-to-client streaming RPC.
+
+    Obtains the Features available within the given Rectangle.  Results are
+    streamed rather than returned at once (e.g. in a response message with a
+    repeated field), as the rectangle may cover a large area and contain a
+    huge number of features.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RecordRoute(self, request_iterator, context):
+    """A client-to-server streaming RPC.
+
+    Accepts a stream of Points on a route being traversed, returning a
+    RouteSummary when traversal is completed.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RouteChat(self, request_iterator, context):
+    """A Bidirectional streaming RPC.
+
+    Accepts a stream of RouteNotes sent while a route is being traversed,
+    while receiving other RouteNotes (e.g. from other users).
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_RouteGuideServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'GetFeature': grpc.unary_unary_rpc_method_handler(
+          servicer.GetFeature,
+          request_deserializer=route__guide__pb2.Point.FromString,
+          response_serializer=route__guide__pb2.Feature.SerializeToString,
+      ),
+      'ListFeatures': grpc.unary_stream_rpc_method_handler(
+          servicer.ListFeatures,
+          request_deserializer=route__guide__pb2.Rectangle.FromString,
+          response_serializer=route__guide__pb2.Feature.SerializeToString,
+      ),
+      'RecordRoute': grpc.stream_unary_rpc_method_handler(
+          servicer.RecordRoute,
+          request_deserializer=route__guide__pb2.Point.FromString,
+          response_serializer=route__guide__pb2.RouteSummary.SerializeToString,
+      ),
+      'RouteChat': grpc.stream_stream_rpc_method_handler(
+          servicer.RouteChat,
+          request_deserializer=route__guide__pb2.RouteNote.FromString,
+          response_serializer=route__guide__pb2.RouteNote.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'routeguide.RouteGuide', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/examples/python/multiplex/run_codegen.py b/examples/python/multiplex/run_codegen.py
old mode 100755
new mode 100644
diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py
index 8a80ed892d..d2955231c3 100644
--- a/examples/python/route_guide/route_guide_client.py
+++ b/examples/python/route_guide/route_guide_client.py
@@ -37,6 +37,7 @@ import time
 import grpc
 
 import route_guide_pb2
+import route_guide_pb2_grpc
 import route_guide_resources
 
 
@@ -116,7 +117,7 @@ def guide_route_chat(stub):
 
 def run():
   channel = grpc.insecure_channel('localhost:50051')
-  stub = route_guide_pb2.RouteGuideStub(channel)
+  stub = route_guide_pb2_grpc.RouteGuideStub(channel)
   print("-------------- GetFeature --------------")
   guide_get_feature(stub)
   print("-------------- ListFeatures --------------")
diff --git a/examples/python/route_guide/route_guide_pb2.py b/examples/python/route_guide/route_guide_pb2.py
index 924e186e06..e6775eb814 100644
--- a/examples/python/route_guide/route_guide_pb2.py
+++ b/examples/python/route_guide/route_guide_pb2.py
@@ -277,240 +277,265 @@ _sym_db.RegisterMessage(RouteSummary)
 
 DESCRIPTOR.has_options = True
 DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG'))
-import grpc
-from grpc.beta import implementations as beta_implementations
-from grpc.beta import interfaces as beta_interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
-
-
-class RouteGuideStub(object):
-  """Interface exported by the server.
-  """
-
-  def __init__(self, channel):
-    """Constructor.
-
-    Args:
-      channel: A grpc.Channel.
+try:
+  # THESE ELEMENTS WILL BE DEPRECATED.
+  # Please use the generated *_pb2_grpc.py files instead.
+  import grpc
+  from grpc.framework.common import cardinality
+  from grpc.framework.interfaces.face import utilities as face_utilities
+  from grpc.beta import implementations as beta_implementations
+  from grpc.beta import interfaces as beta_interfaces
+
+
+  class RouteGuideStub(object):
+    """Interface exported by the server.
     """
-    self.GetFeature = channel.unary_unary(
-        '/routeguide.RouteGuide/GetFeature',
-        request_serializer=Point.SerializeToString,
-        response_deserializer=Feature.FromString,
-        )
-    self.ListFeatures = channel.unary_stream(
-        '/routeguide.RouteGuide/ListFeatures',
-        request_serializer=Rectangle.SerializeToString,
-        response_deserializer=Feature.FromString,
-        )
-    self.RecordRoute = channel.stream_unary(
-        '/routeguide.RouteGuide/RecordRoute',
-        request_serializer=Point.SerializeToString,
-        response_deserializer=RouteSummary.FromString,
-        )
-    self.RouteChat = channel.stream_stream(
-        '/routeguide.RouteGuide/RouteChat',
-        request_serializer=RouteNote.SerializeToString,
-        response_deserializer=RouteNote.FromString,
-        )
-
-
-class RouteGuideServicer(object):
-  """Interface exported by the server.
-  """
-
-  def GetFeature(self, request, context):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def ListFeatures(self, request, context):
-    """A server-to-client streaming RPC.
 
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
+    def __init__(self, channel):
+      """Constructor.
+
+      Args:
+        channel: A grpc.Channel.
+      """
+      self.GetFeature = channel.unary_unary(
+          '/routeguide.RouteGuide/GetFeature',
+          request_serializer=Point.SerializeToString,
+          response_deserializer=Feature.FromString,
+          )
+      self.ListFeatures = channel.unary_stream(
+          '/routeguide.RouteGuide/ListFeatures',
+          request_serializer=Rectangle.SerializeToString,
+          response_deserializer=Feature.FromString,
+          )
+      self.RecordRoute = channel.stream_unary(
+          '/routeguide.RouteGuide/RecordRoute',
+          request_serializer=Point.SerializeToString,
+          response_deserializer=RouteSummary.FromString,
+          )
+      self.RouteChat = channel.stream_stream(
+          '/routeguide.RouteGuide/RouteChat',
+          request_serializer=RouteNote.SerializeToString,
+          response_deserializer=RouteNote.FromString,
+          )
+
+
+  class RouteGuideServicer(object):
+    """Interface exported by the server.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def RecordRoute(self, request_iterator, context):
-    """A client-to-server streaming RPC.
 
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
+    def GetFeature(self, request, context):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def ListFeatures(self, request, context):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def RecordRoute(self, request_iterator, context):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def RouteChat(self, request_iterator, context):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+
+  def add_RouteGuideServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+        'GetFeature': grpc.unary_unary_rpc_method_handler(
+            servicer.GetFeature,
+            request_deserializer=Point.FromString,
+            response_serializer=Feature.SerializeToString,
+        ),
+        'ListFeatures': grpc.unary_stream_rpc_method_handler(
+            servicer.ListFeatures,
+            request_deserializer=Rectangle.FromString,
+            response_serializer=Feature.SerializeToString,
+        ),
+        'RecordRoute': grpc.stream_unary_rpc_method_handler(
+            servicer.RecordRoute,
+            request_deserializer=Point.FromString,
+            response_serializer=RouteSummary.SerializeToString,
+        ),
+        'RouteChat': grpc.stream_stream_rpc_method_handler(
+            servicer.RouteChat,
+            request_deserializer=RouteNote.FromString,
+            response_serializer=RouteNote.SerializeToString,
+        ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+        'routeguide.RouteGuide', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+  class BetaRouteGuideServicer(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """Interface exported by the server.
     """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def RouteChat(self, request_iterator, context):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_RouteGuideServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'GetFeature': grpc.unary_unary_rpc_method_handler(
-          servicer.GetFeature,
-          request_deserializer=Point.FromString,
-          response_serializer=Feature.SerializeToString,
-      ),
-      'ListFeatures': grpc.unary_stream_rpc_method_handler(
-          servicer.ListFeatures,
-          request_deserializer=Rectangle.FromString,
-          response_serializer=Feature.SerializeToString,
-      ),
-      'RecordRoute': grpc.stream_unary_rpc_method_handler(
-          servicer.RecordRoute,
-          request_deserializer=Point.FromString,
-          response_serializer=RouteSummary.SerializeToString,
-      ),
-      'RouteChat': grpc.stream_stream_rpc_method_handler(
-          servicer.RouteChat,
-          request_deserializer=RouteNote.FromString,
-          response_serializer=RouteNote.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'routeguide.RouteGuide', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-
-
-class BetaRouteGuideServicer(object):
-  """Interface exported by the server.
-  """
-  def GetFeature(self, request, context):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def ListFeatures(self, request, context):
-    """A server-to-client streaming RPC.
-
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def RecordRoute(self, request_iterator, context):
-    """A client-to-server streaming RPC.
-
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-  def RouteChat(self, request_iterator, context):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
-    """
-    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-
-
-class BetaRouteGuideStub(object):
-  """Interface exported by the server.
-  """
-  def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A simple RPC.
-
-    Obtains the feature at a given position.
-
-    A feature with an empty name is returned if there's no feature at the given
-    position.
-    """
-    raise NotImplementedError()
-  GetFeature.future = None
-  def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A server-to-client streaming RPC.
-
-    Obtains the Features available within the given Rectangle.  Results are
-    streamed rather than returned at once (e.g. in a response message with a
-    repeated field), as the rectangle may cover a large area and contain a
-    huge number of features.
-    """
-    raise NotImplementedError()
-  def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A client-to-server streaming RPC.
-
-    Accepts a stream of Points on a route being traversed, returning a
-    RouteSummary when traversal is completed.
-    """
-    raise NotImplementedError()
-  RecordRoute.future = None
-  def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
-    """A Bidirectional streaming RPC.
-
-    Accepts a stream of RouteNotes sent while a route is being traversed,
-    while receiving other RouteNotes (e.g. from other users).
+    def GetFeature(self, request, context):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def ListFeatures(self, request, context):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def RecordRoute(self, request_iterator, context):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def RouteChat(self, request_iterator, context):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+  class BetaRouteGuideStub(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    """Interface exported by the server.
     """
-    raise NotImplementedError()
-
-
-def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
-  request_deserializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
-    ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
-  }
-  response_serializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
-    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
-  }
-  method_implementations = {
-    ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
-    ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
-    ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
-    ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
-  }
-  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
-  return beta_implementations.server(method_implementations, options=server_options)
-
-
-def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
-  request_serializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
-    ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
-  }
-  response_deserializers = {
-    ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
-    ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
-    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
-    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
-  }
-  cardinalities = {
-    'GetFeature': cardinality.Cardinality.UNARY_UNARY,
-    'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
-    'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
-    'RouteChat': cardinality.Cardinality.STREAM_STREAM,
-  }
-  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
-  return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
+    def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A simple RPC.
+
+      Obtains the feature at a given position.
+
+      A feature with an empty name is returned if there's no feature at the given
+      position.
+      """
+      raise NotImplementedError()
+    GetFeature.future = None
+    def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A server-to-client streaming RPC.
+
+      Obtains the Features available within the given Rectangle.  Results are
+      streamed rather than returned at once (e.g. in a response message with a
+      repeated field), as the rectangle may cover a large area and contain a
+      huge number of features.
+      """
+      raise NotImplementedError()
+    def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A client-to-server streaming RPC.
+
+      Accepts a stream of Points on a route being traversed, returning a
+      RouteSummary when traversal is completed.
+      """
+      raise NotImplementedError()
+    RecordRoute.future = None
+    def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+      """A Bidirectional streaming RPC.
+
+      Accepts a stream of RouteNotes sent while a route is being traversed,
+      while receiving other RouteNotes (e.g. from other users).
+      """
+      raise NotImplementedError()
+
+
+  def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_deserializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
+      ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+    }
+    response_serializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
+      ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+    }
+    method_implementations = {
+      ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
+      ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
+      ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
+      ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
+    }
+    server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+    return beta_implementations.server(method_implementations, options=server_options)
+
+
+  def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_serializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
+      ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+    }
+    response_deserializers = {
+      ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
+      ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
+      ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
+      ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+    }
+    cardinalities = {
+      'GetFeature': cardinality.Cardinality.UNARY_UNARY,
+      'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
+      'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
+      'RouteChat': cardinality.Cardinality.STREAM_STREAM,
+    }
+    stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+    return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
+except ImportError:
+  pass
 # @@protoc_insertion_point(module_scope)
diff --git a/examples/python/route_guide/route_guide_pb2_grpc.py b/examples/python/route_guide/route_guide_pb2_grpc.py
new file mode 100644
index 0000000000..27b24c747d
--- /dev/null
+++ b/examples/python/route_guide/route_guide_pb2_grpc.py
@@ -0,0 +1,114 @@
+import grpc
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+import route_guide_pb2 as route__guide__pb2
+
+
+class RouteGuideStub(object):
+  """Interface exported by the server.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.GetFeature = channel.unary_unary(
+        '/routeguide.RouteGuide/GetFeature',
+        request_serializer=route__guide__pb2.Point.SerializeToString,
+        response_deserializer=route__guide__pb2.Feature.FromString,
+        )
+    self.ListFeatures = channel.unary_stream(
+        '/routeguide.RouteGuide/ListFeatures',
+        request_serializer=route__guide__pb2.Rectangle.SerializeToString,
+        response_deserializer=route__guide__pb2.Feature.FromString,
+        )
+    self.RecordRoute = channel.stream_unary(
+        '/routeguide.RouteGuide/RecordRoute',
+        request_serializer=route__guide__pb2.Point.SerializeToString,
+        response_deserializer=route__guide__pb2.RouteSummary.FromString,
+        )
+    self.RouteChat = channel.stream_stream(
+        '/routeguide.RouteGuide/RouteChat',
+        request_serializer=route__guide__pb2.RouteNote.SerializeToString,
+        response_deserializer=route__guide__pb2.RouteNote.FromString,
+        )
+
+
+class RouteGuideServicer(object):
+  """Interface exported by the server.
+  """
+
+  def GetFeature(self, request, context):
+    """A simple RPC.
+
+    Obtains the feature at a given position.
+
+    A feature with an empty name is returned if there's no feature at the given
+    position.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def ListFeatures(self, request, context):
+    """A server-to-client streaming RPC.
+
+    Obtains the Features available within the given Rectangle.  Results are
+    streamed rather than returned at once (e.g. in a response message with a
+    repeated field), as the rectangle may cover a large area and contain a
+    huge number of features.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RecordRoute(self, request_iterator, context):
+    """A client-to-server streaming RPC.
+
+    Accepts a stream of Points on a route being traversed, returning a
+    RouteSummary when traversal is completed.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RouteChat(self, request_iterator, context):
+    """A Bidirectional streaming RPC.
+
+    Accepts a stream of RouteNotes sent while a route is being traversed,
+    while receiving other RouteNotes (e.g. from other users).
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_RouteGuideServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'GetFeature': grpc.unary_unary_rpc_method_handler(
+          servicer.GetFeature,
+          request_deserializer=route__guide__pb2.Point.FromString,
+          response_serializer=route__guide__pb2.Feature.SerializeToString,
+      ),
+      'ListFeatures': grpc.unary_stream_rpc_method_handler(
+          servicer.ListFeatures,
+          request_deserializer=route__guide__pb2.Rectangle.FromString,
+          response_serializer=route__guide__pb2.Feature.SerializeToString,
+      ),
+      'RecordRoute': grpc.stream_unary_rpc_method_handler(
+          servicer.RecordRoute,
+          request_deserializer=route__guide__pb2.Point.FromString,
+          response_serializer=route__guide__pb2.RouteSummary.SerializeToString,
+      ),
+      'RouteChat': grpc.stream_stream_rpc_method_handler(
+          servicer.RouteChat,
+          request_deserializer=route__guide__pb2.RouteNote.FromString,
+          response_serializer=route__guide__pb2.RouteNote.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'routeguide.RouteGuide', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py
index 3ffe678476..bf49217932 100644
--- a/examples/python/route_guide/route_guide_server.py
+++ b/examples/python/route_guide/route_guide_server.py
@@ -36,6 +36,7 @@ import math
 import grpc
 
 import route_guide_pb2
+import route_guide_pb2_grpc
 import route_guide_resources
 
 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -68,7 +69,7 @@ def get_distance(start, end):
   R = 6371000; # metres
   return R * c;
 
-class RouteGuideServicer(route_guide_pb2.RouteGuideServicer):
+class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
   """Provides methods that implement functionality of route guide server."""
 
   def __init__(self):
@@ -125,7 +126,7 @@ class RouteGuideServicer(route_guide_pb2.RouteGuideServicer):
 
 def serve():
   server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-  route_guide_pb2.add_RouteGuideServicer_to_server(
+  route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
       RouteGuideServicer(), server)
   server.add_insecure_port('[::]:50051')
   server.start()
-- 
GitLab


From ef4ceda6fd2131bda6c0b0a02aadc3c73efcfebb Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@google.com>
Date: Mon, 24 Oct 2016 12:07:55 -0700
Subject: [PATCH 186/344] Add advanced interop tests for Ruby client

---
 src/ruby/lib/grpc/generic/bidi_call.rb        |   1 +
 .../proto/grpc/testing/test_services_pb.rb    |   7 +
 src/ruby/pb/test/client.rb                    | 181 +++++++++++++++++-
 3 files changed, 183 insertions(+), 6 deletions(-)

diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 8943f3f1fe..adc77bbf5d 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -200,6 +200,7 @@ module GRPC
             if is_client
               batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
               @call.status = batch_result.status
+              @call.trailing_metadata = @call.status.metadata if @call.status
               batch_result.check_status
               GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
             end
diff --git a/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
index fde328e4c5..7d1072e512 100644
--- a/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
+++ b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
@@ -54,6 +54,10 @@ module Grpc
         rpc :EmptyCall, Empty, Empty
         # One request followed by one response.
         rpc :UnaryCall, SimpleRequest, SimpleResponse
+        # One request followed by one response. Response has cache control
+        # headers set such that a caching HTTP proxy (such as GFE) can
+        # satisfy subsequent requests.
+        rpc :CacheableUnaryCall, SimpleRequest, SimpleResponse
         # One request followed by a sequence of responses (streamed download).
         # The server returns the payload with client desired type and sizes.
         rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse)
@@ -69,6 +73,9 @@ module Grpc
         # stream of responses are returned to the client when the server starts with
         # first request.
         rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
+        # The test server will not implement this method. It will be used
+        # to test the behavior when clients call unimplemented methods.
+        rpc :UnimplementedCall, Empty, Empty
       end
 
       Stub = Service.rpc_stub_class
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index f101f9d89e..756c68c422 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -158,14 +158,26 @@ def create_stub(opts)
 
     GRPC.logger.info("... connecting securely to #{address}")
     stub_opts[:channel_args].merge!(compression_channel_args)
-    Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts)
+    if opts.test_case == "unimplemented_service"
+      Grpc::Testing::UnimplementedService::Stub.new(address, creds, **stub_opts)
+    else
+      Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts)
+    end
   else
     GRPC.logger.info("... connecting insecurely to #{address}")
-    Grpc::Testing::TestService::Stub.new(
-      address,
-      :this_channel_is_insecure,
-      channel_args: compression_channel_args
-    )
+    if opts.test_case == "unimplemented_service"
+      Grpc::Testing::UnimplementedService::Stub.new(
+        address,
+        :this_channel_is_insecure,
+        channel_args: compression_channel_args
+      )
+    else
+      Grpc::Testing::TestService::Stub.new(
+        address,
+        :this_channel_is_insecure,
+        channel_args: compression_channel_args
+      )
+    end
   end
 end
 
@@ -502,6 +514,163 @@ class NamedTests
     op.wait
   end
 
+  def unimplemented_method
+    begin
+      resp = @stub.unimplemented_call(Empty.new)
+    rescue GRPC::BadStatus => e
+      if e.code != GRPC::Core::StatusCodes::UNIMPLEMENTED
+        fail AssertionError,
+          "Expected status 12 (UNIMPLEMENTED). Received: #{e.code}"
+      end
+    rescue Exception => e
+      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
+    end
+  end
+
+  def unimplemented_service
+    begin
+      resp = @stub.unimplemented_call(Empty.new)
+    rescue GRPC::BadStatus => e
+      if e.code != GRPC::Core::StatusCodes::UNIMPLEMENTED
+        fail AssertionError,
+          "Expected status 12 (UNIMPLEMENTED). Received: #{e.code}"
+      end
+    rescue Exception => e
+      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
+    end
+  end
+
+  def status_code_and_message
+
+    # Function wide constants.
+    message = "test status method"
+    code = 2
+    status = GRPC::Core::StatusCodes::UNKNOWN
+
+    # Testing with UnaryCall.
+    payload = Payload.new(type: :COMPRESSABLE, body: nulls(1))
+    echo_status = EchoStatus.new(code: code, message: message)
+    req = SimpleRequest.new(response_type: :COMPRESSABLE,
+			    response_size: 1,
+			    payload: payload,
+			    response_status: echo_status)
+    seen_correct_exception = false
+    begin
+      resp = @stub.unary_call(req)
+    rescue GRPC::BadStatus => e
+      if e.code != status
+        fail AssertionError,
+	        "Expected status 2 (UNKOWN). Received: #{e.code}"
+      elsif e.details != message
+	      fail AssertionError,
+	        "Expected message #{message}. Received: #{e.details}"
+      end
+      seen_correct_exception = true
+    rescue Exception => e
+      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
+    end
+
+    if not seen_correct_exception
+      fail AssertionError, "Did not see expected status from UnaryCall"
+    end
+
+    # testing with FullDuplex
+    req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters
+    duplex_req = req_cls.new(payload: Payload.new(body: nulls(1)),
+                  response_type: :COMPRESSABLE,
+                  response_parameters: [p_cls.new(size: 1)],
+                  response_status: echo_status)
+    seen_correct_exception = false
+    begin
+      resp = @stub.full_duplex_call([duplex_req])
+      resp.next # triggers initial req to be sent
+    rescue GRPC::BadStatus => e
+      if e.code != status
+        fail AssertionError,
+          "Expected status 2 (UNKOWN). Received: #{e.code}"
+      elsif e.details != message
+        fail AssertionError,
+          "Expected message #{message}. Received: #{e.details}"
+      end
+      seen_correct_exception = true
+    rescue Exception => e
+      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
+    end
+
+    if not seen_correct_exception
+      fail AssertionError, "Did not see expected status from FullDuplexCall"
+    end
+
+  end
+
+
+  def custom_metadata
+
+    # Function wide constants
+    initial_metadata_key = "x-grpc-test-echo-initial"
+    initial_metadata_value = "test_initial_metadata_value"
+    trailing_metadata_key = "x-grpc-test-echo-trailing-bin"
+    trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"
+
+    metadata = {
+      initial_metadata_key => initial_metadata_value,
+      trailing_metadata_key => trailing_metadata_value
+    }
+
+    # Testing with UnaryCall
+    payload = Payload.new(type: :COMPRESSABLE, body: nulls(1))
+    req = SimpleRequest.new(response_type: :COMPRESSABLE,
+			    response_size: 1,
+			    payload: payload)
+
+    op = @stub.unary_call(req, metadata: metadata, return_op: true)
+    op.execute
+    if not op.metadata.has_key?(initial_metadata_key)
+      fail AssertionError, "Expected initial metadata. None received"
+    elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key]
+      fail AssertionError, 
+             "Expected initial metadata: #{metadata[initial_metadata_key]}. "\
+             "Received: #{op.metadata[initial_metadata_key]}"
+    end
+    if not op.trailing_metadata.has_key?(trailing_metadata_key)
+      fail AssertionError, "Expected trailing metadata. None received"
+    elsif op.trailing_metadata[trailing_metadata_key] !=
+          metadata[trailing_metadata_key]
+      fail AssertionError, 
+            "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\
+            "Received: #{op.trailing_metadata[trailing_metadata_key]}"
+    end
+
+    # Testing with FullDuplex
+    req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters
+    duplex_req = req_cls.new(payload: Payload.new(body: nulls(1)),
+                  response_type: :COMPRESSABLE,
+                  response_parameters: [p_cls.new(size: 1)])
+
+    duplex_op = @stub.full_duplex_call([duplex_req], metadata: metadata,
+                                        return_op: true)
+    resp = duplex_op.execute
+    resp.each { |r| } # ensures that the server sends trailing data
+    duplex_op.wait
+    if not duplex_op.metadata.has_key?(initial_metadata_key)
+      fail AssertionError, "Expected initial metadata. None received"
+    elsif duplex_op.metadata[initial_metadata_key] !=
+          metadata[initial_metadata_key]
+      fail AssertionError,
+             "Expected initial metadata: #{metadata[initial_metadata_key]}. "\
+             "Received: #{duplex_op.metadata[initial_metadata_key]}"
+    end
+    if not duplex_op.trailing_metadata[trailing_metadata_key]
+      fail AssertionError, "Expected trailing metadata. None received"
+    elsif duplex_op.trailing_metadata[trailing_metadata_key] !=
+          metadata[trailing_metadata_key]
+      fail AssertionError, 
+          "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\
+          "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}"
+    end
+
+  end
+
   def all
     all_methods = NamedTests.instance_methods(false).map(&:to_s)
     all_methods.each do |m|
-- 
GitLab


From 92fa9608f23791728dc68ff90da1be560511cc7c Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 21 Dec 2016 14:18:07 -0800
Subject: [PATCH 187/344] Check and fail if user provides a metadata key
 starting with :

---
 src/core/lib/surface/validate_metadata.c      |  2 +-
 .../core/end2end/invalid_call_argument_test.c | 24 +++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/surface/validate_metadata.c b/src/core/lib/surface/validate_metadata.c
index 84f0a083bc..f49dd8584b 100644
--- a/src/core/lib/surface/validate_metadata.c
+++ b/src/core/lib/surface/validate_metadata.c
@@ -53,7 +53,7 @@ int grpc_header_key_is_legal(const char *key, size_t length) {
       0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
       0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-  if (length == 0) {
+  if (length == 0 || key[0] == ':') {
     return 0;
   }
   return conforms_to(key, length, legal_header_bits);
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index 765b6ad1be..d974d2c8ff 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -573,6 +573,29 @@ static void test_recv_close_on_server_twice() {
   cleanup_test();
 }
 
+static void test_invalid_initial_metadata_reserved_key() {
+  gpr_log(GPR_INFO, "test_invalid_initial_metadata_reserved_key");
+
+  grpc_metadata metadata;
+  metadata.key = ":start_with_colon";
+  metadata.value = "value";
+  metadata.value_length = 6;
+
+  grpc_op *op;
+  prepare_test(1);
+  op = g_state.ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 1;
+  op->data.send_initial_metadata.metadata = &metadata;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  GPR_ASSERT(GRPC_CALL_ERROR_INVALID_METADATA ==
+             grpc_call_start_batch(g_state.call, g_state.ops,
+                                   (size_t)(op - g_state.ops), tag(1), NULL));
+  cleanup_test();
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
@@ -595,6 +618,7 @@ int main(int argc, char **argv) {
   test_send_server_status_twice();
   test_recv_close_on_server_with_invalid_flags();
   test_recv_close_on_server_twice();
+  test_invalid_initial_metadata_reserved_key();
   grpc_shutdown();
 
   return 0;
-- 
GitLab


From 2e3972ae5497f7bcff260ce891191dfba7f55297 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Wed, 21 Dec 2016 13:57:42 -0800
Subject: [PATCH 188/344] Add advanced interop test behavior for Ruby server
 side

---
 src/ruby/pb/test/server.rb | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/ruby/pb/test/server.rb b/src/ruby/pb/test/server.rb
index 3f1e0a1ccf..c9b71aec76 100755
--- a/src/ruby/pb/test/server.rb
+++ b/src/ruby/pb/test/server.rb
@@ -129,6 +129,27 @@ def nulls(l)
   [].pack('x' * l).force_encoding('ascii-8bit')
 end
 
+def maybe_echo_metadata(_call)
+  
+  # these are consistent for all interop tests
+  initial_metadata_key = "x-grpc-test-echo-initial"
+  trailing_metadata_key = "x-grpc-test-echo-trailing-bin"
+
+  if _call.metadata.has_key?(initial_metadata_key)
+    _call.metadata_to_send[initial_metadata_key] = _call.metadata[initial_metadata_key]
+  end
+  if _call.metadata.has_key?(trailing_metadata_key)
+    _call.output_metadata[trailing_metadata_key] = _call.metadata[trailing_metadata_key]
+  end
+end
+
+def maybe_echo_status_and_message(req)
+  unless req.response_status.nil?
+    fail GRPC::BadStatus.new_status_exception(
+        req.response_status.code, req.response_status.message)
+  end
+end
+
 # A FullDuplexEnumerator passes requests to a block and yields generated responses
 class FullDuplexEnumerator
   include Grpc::Testing
@@ -143,6 +164,7 @@ class FullDuplexEnumerator
     begin
       cls = StreamingOutputCallResponse
       @requests.each do |req|
+        maybe_echo_status_and_message(req)
         req.response_parameters.each do |params|
           resp_size = params.size
           GRPC.logger.info("read a req, response size is #{resp_size}")
@@ -170,18 +192,23 @@ class TestTarget < Grpc::Testing::TestService::Service
   end
 
   def unary_call(simple_req, _call)
+    maybe_echo_metadata(_call)
+    maybe_echo_status_and_message(simple_req)
     req_size = simple_req.response_size
     SimpleResponse.new(payload: Payload.new(type: :COMPRESSABLE,
                                             body: nulls(req_size)))
   end
 
   def streaming_input_call(call)
+    maybe_echo_metadata(call)
     sizes = call.each_remote_read.map { |x| x.payload.body.length }
     sum = sizes.inject(0) { |s, x| s + x }
     StreamingInputCallResponse.new(aggregated_payload_size: sum)
   end
 
   def streaming_output_call(req, _call)
+    maybe_echo_metadata(_call)
+    maybe_echo_status_and_message(req)
     cls = StreamingOutputCallResponse
     req.response_parameters.map do |p|
       cls.new(payload: Payload.new(type: req.response_type,
@@ -189,7 +216,8 @@ class TestTarget < Grpc::Testing::TestService::Service
     end
   end
 
-  def full_duplex_call(reqs)
+  def full_duplex_call(reqs, _call)
+    maybe_echo_metadata(_call)
     # reqs is a lazy Enumerator of the requests sent by the client.
     FullDuplexEnumerator.new(reqs).each_item
   end
-- 
GitLab


From 2ec43d2dacf3244976a86ddc065055995a10417f Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 21 Dec 2016 16:26:02 -0800
Subject: [PATCH 189/344] change ruby default unimplemented ruby server handler
 to have two arguments

---
 src/ruby/lib/grpc/generic/service.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 84f1ce7520..f5a6b49eb4 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -110,7 +110,7 @@ module GRPC
         rpc_descs[name] = RpcDesc.new(name, input, output,
                                       marshal_class_method,
                                       unmarshal_class_method)
-        define_method(GenericService.underscore(name.to_s).to_sym) do
+        define_method(GenericService.underscore(name.to_s).to_sym) do |_, _|
           fail GRPC::BadStatus.new_status_exception(
             GRPC::Core::StatusCodes::UNIMPLEMENTED)
         end
-- 
GitLab


From 48226a2f1f14b555505e39c322141e74aed90417 Mon Sep 17 00:00:00 2001
From: siddharthshukla <siddharthshukla@outlook.com>
Date: Wed, 30 Nov 2016 17:50:18 +0100
Subject: [PATCH 190/344] Add _invocation_defects_test.InvocationDefectsTest

Added tests for detecting invocation time defects arising out of the
runtime.
---
 src/python/grpcio_tests/tests/tests.json      |   1 +
 .../tests/unit/_invocation_defects_test.py    | 247 ++++++++++++++++++
 2 files changed, 248 insertions(+)
 create mode 100644 src/python/grpcio_tests/tests/unit/_invocation_defects_test.py

diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 2ac51ac542..d47631cf75 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -26,6 +26,7 @@
   "_implementations_test.ChannelCredentialsTest",
   "_insecure_interop_test.InsecureInteropTest",
   "_invalid_metadata_test.InvalidMetadataTest",
+  "_invocation_defects_test.InvocationDefectsTest",
   "_logging_pool_test.LoggingPoolTest",
   "_metadata_code_details_test.MetadataCodeDetailsTest",
   "_metadata_test.MetadataTest",
diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
new file mode 100644
index 0000000000..4312679bb9
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
@@ -0,0 +1,247 @@
+# Copyright 2016, 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.
+
+import itertools
+import threading
+import unittest
+from concurrent import futures
+
+import grpc
+from grpc.framework.foundation import logging_pool
+
+from tests.unit.framework.common import test_constants
+from tests.unit.framework.common import test_control
+
+_SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
+_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
+_SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
+_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
+
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
+
+
+class _Callback(object):
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._value = None
+    self._called = False
+
+  def __call__(self, value):
+    with self._condition:
+      self._value = value
+      self._called = True
+      self._condition.notify_all()
+
+  def value(self):
+    with self._condition:
+      while not self._called:
+        self._condition.wait()
+      return self._value
+
+
+class _Handler(object):
+  def __init__(self, control):
+    self._control = control
+
+  def handle_unary_unary(self, request, servicer_context):
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
+    return request
+
+  def handle_unary_stream(self, request, servicer_context):
+    for _ in range(test_constants.STREAM_LENGTH):
+      self._control.control()
+      yield request
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
+
+  def handle_stream_unary(self, request_iterator, servicer_context):
+    if servicer_context is not None:
+      servicer_context.invocation_metadata()
+    self._control.control()
+    response_elements = []
+    for request in request_iterator:
+      self._control.control()
+      response_elements.append(request)
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
+    return b''.join(response_elements)
+
+  def handle_stream_stream(self, request_iterator, servicer_context):
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
+    for request in request_iterator:
+      self._control.control()
+      yield request
+    self._control.control()
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+  def __init__(
+    self, request_streaming, response_streaming, request_deserializer,
+    response_serializer, unary_unary, unary_stream, stream_unary,
+    stream_stream):
+    self.request_streaming = request_streaming
+    self.response_streaming = response_streaming
+    self.request_deserializer = request_deserializer
+    self.response_serializer = response_serializer
+    self.unary_unary = unary_unary
+    self.unary_stream = unary_stream
+    self.stream_unary = stream_unary
+    self.stream_stream = stream_stream
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+  def __init__(self, handler):
+    self._handler = handler
+
+  def service(self, handler_call_details):
+    if handler_call_details.method == _UNARY_UNARY:
+      return _MethodHandler(
+        False, False, None, None, self._handler.handle_unary_unary, None,
+        None, None)
+    elif handler_call_details.method == _UNARY_STREAM:
+      return _MethodHandler(
+        False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None,
+        self._handler.handle_unary_stream, None, None)
+    elif handler_call_details.method == _STREAM_UNARY:
+      return _MethodHandler(
+        True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None,
+        self._handler.handle_stream_unary, None)
+    elif handler_call_details.method == _STREAM_STREAM:
+      return _MethodHandler(
+        True, True, None, None, None, None, None,
+        self._handler.handle_stream_stream)
+    else:
+      return None
+
+
+class FailAfterFewIterationsCounter(object):
+    def __init__(self, high, bytestring):
+        self._current = 0
+        self._high = high
+        self._bytestring = bytestring
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        if self._current >= self._high:
+            raise Exception("This is a deliberate failure in a unit test.")
+        else:
+            self._current += 1
+            return self._bytestring
+
+
+def _unary_unary_multi_callable(channel):
+  return channel.unary_unary(_UNARY_UNARY)
+
+
+def _unary_stream_multi_callable(channel):
+  return channel.unary_stream(
+    _UNARY_STREAM,
+    request_serializer=_SERIALIZE_REQUEST,
+    response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_unary_multi_callable(channel):
+  return channel.stream_unary(
+    _STREAM_UNARY,
+    request_serializer=_SERIALIZE_REQUEST,
+    response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_stream_multi_callable(channel):
+  return channel.stream_stream(_STREAM_STREAM)
+
+
+class InvocationDefectsTest(unittest.TestCase):
+  def setUp(self):
+    self._control = test_control.PauseFailControl()
+    self._handler = _Handler(self._control)
+    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+
+    self._server = grpc.server(self._server_pool)
+    port = self._server.add_insecure_port('[::]:0')
+    self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
+    self._server.start()
+
+    self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+  def tearDown(self):
+    self._server.stop(0)
+
+  def testIterableStreamRequestBlockingUnaryResponse(self):
+    requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
+    multi_callable = _stream_unary_multi_callable(self._channel)
+
+    with self.assertRaises(grpc.RpcError):
+      response = multi_callable(
+        requests,
+        metadata=(('test', 'IterableStreamRequestBlockingUnaryResponse'),))
+
+  def testIterableStreamRequestFutureUnaryResponse(self):
+    requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    response_future = multi_callable.future(
+      requests,
+      metadata=(
+        ('test', 'IterableStreamRequestFutureUnaryResponse'),))
+
+    with self.assertRaises(grpc.RpcError):
+      response = response_future.result()
+
+  def testIterableStreamRequestStreamResponse(self):
+    requests = [b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)]
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+      requests,
+      metadata=(('test', 'IterableStreamRequestStreamResponse'),))
+
+    with self.assertRaises(grpc.RpcError):
+      next(response_iterator)
+
+  def testIteratorStreamRequestStreamResponse(self):
+    requests_iterator = FailAfterFewIterationsCounter(
+      test_constants.STREAM_LENGTH // 2, b'\x07\x08')
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+      requests_iterator,
+      metadata=(('test', 'IteratorStreamRequestStreamResponse'),))
+
+    with self.assertRaises(grpc.RpcError):
+      for _ in range(test_constants.STREAM_LENGTH // 2 + 1):
+        next(response_iterator)
-- 
GitLab


From 964d7bb4828461f4c4d51cfe7f774367fc162013 Mon Sep 17 00:00:00 2001
From: Julien Boeuf <jboeuf@google.com>
Date: Thu, 17 Nov 2016 16:59:48 -0800
Subject: [PATCH 191/344] Fixing JWT verifier.

- Initializes grpc correctly in the JWT utils.
- Make the email mapping work with the new service accounts produced by
  Google IAM.
- Adding check for email issuers where the issuer has to be the subject as well.
- Implementing portable version of memrchr.
---
 .../security/credentials/jwt/jwt_verifier.c   | 38 ++++++++++---
 .../security/credentials/jwt/jwt_verifier.h   |  5 +-
 src/core/lib/support/string.c                 | 11 ++++
 src/core/lib/support/string.h                 |  2 +
 test/core/security/create_jwt.c               |  2 +
 test/core/security/jwt_verifier_test.c        | 54 +++++++++++++++++++
 test/core/security/verify_jwt.c               |  2 +
 test/core/support/string_test.c               | 16 ++++++
 8 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 42bd89dd0a..03097a57c0 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -39,6 +39,7 @@
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/support/string.h"
 #include "src/core/lib/tsi/ssl_types.h"
 
 #include <grpc/support/alloc.h>
@@ -305,6 +306,17 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
     return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE;
   }
 
+  /* This should be probably up to the upper layer to decide but let's harcode
+     the 99% use case here for email issuers, where the JWT must be self
+     issued. */
+  if (grpc_jwt_issuer_email_domain(claims->iss) != NULL &&
+      claims->sub != NULL && strcmp(claims->iss, claims->sub) != 0) {
+    gpr_log(GPR_ERROR,
+            "Email issuer (%s) cannot assert another subject (%s) than itself.",
+            claims->iss, claims->sub);
+    return GRPC_JWT_VERIFIER_BAD_SUBJECT;
+  }
+
   if (audience == NULL) {
     audience_ok = claims->aud == NULL;
   } else {
@@ -705,10 +717,26 @@ static void verifier_put_mapping(grpc_jwt_verifier *v, const char *email_domain,
   GPR_ASSERT(v->num_mappings <= v->allocated_mappings);
 }
 
+/* Very non-sophisticated way to detect an email address. Should be good
+   enough for now... */
+const char *grpc_jwt_issuer_email_domain(const char *issuer) {
+  const char *at_sign = strchr(issuer, '@');
+  if (at_sign == NULL) return NULL;
+  const char *email_domain = at_sign + 1;
+  if (*email_domain == '\0') return NULL;
+  const char *dot = strrchr(email_domain, '.');
+  if (dot == NULL || dot == email_domain) return email_domain;
+  GPR_ASSERT(dot > email_domain);
+  /* There may be a subdomain, we just want the domain. */
+  dot = gpr_memrchr(email_domain, '.', (size_t)(dot - email_domain));
+  if (dot == NULL) return email_domain;
+  return dot + 1;
+}
+
 /* Takes ownership of ctx. */
 static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
                                     verifier_cb_ctx *ctx) {
-  const char *at_sign;
+  const char *email_domain;
   grpc_closure *http_cb;
   char *path_prefix = NULL;
   const char *iss;
@@ -733,13 +761,9 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
      Nobody seems to implement the account/email/webfinger part 2. of the spec
      so we will rely instead on email/url mappings if we detect such an issuer.
      Part 4, on the other hand is implemented by both google and salesforce. */
-
-  /* Very non-sophisticated way to detect an email address. Should be good
-     enough for now... */
-  at_sign = strchr(iss, '@');
-  if (at_sign != NULL) {
+  email_domain = grpc_jwt_issuer_email_domain(iss);
+  if (email_domain != NULL) {
     email_key_mapping *mapping;
-    const char *email_domain = at_sign + 1;
     GPR_ASSERT(ctx->verifier != NULL);
     mapping = verifier_get_mapping(ctx->verifier, email_domain);
     if (mapping == NULL) {
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index f09f9d5d47..54ff9b05e5 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -43,8 +43,7 @@
 /* --- Constants. --- */
 
 #define GRPC_OPENID_CONFIG_URL_SUFFIX "/.well-known/openid-configuration"
-#define GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN \
-  "developer.gserviceaccount.com"
+#define GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN "gserviceaccount.com"
 #define GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX \
   "www.googleapis.com/robot/v1/metadata/x509"
 
@@ -57,6 +56,7 @@ typedef enum {
   GRPC_JWT_VERIFIER_BAD_AUDIENCE,
   GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
   GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE,
+  GRPC_JWT_VERIFIER_BAD_SUBJECT,
   GRPC_JWT_VERIFIER_GENERIC_ERROR
 } grpc_jwt_verifier_status;
 
@@ -132,5 +132,6 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
 grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer);
 grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
                                                const char *audience);
+const char *grpc_jwt_issuer_email_domain(const char *issuer);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H */
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index f10a30f0fd..f263f82baf 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -275,3 +275,14 @@ int gpr_stricmp(const char *a, const char *b) {
   } while (ca == cb && ca && cb);
   return ca - cb;
 }
+
+void *gpr_memrchr(const void *s, int c, size_t n) {
+  if (s == NULL) return NULL;
+  char *b = (char *)s;
+  for (size_t i = 0; i < n; i++) {
+    if (b[n - i - 1] == c) {
+      return &b[n - i - 1];
+    }
+  }
+  return NULL;
+}
diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h
index e933e2eb46..6d1f7cc632 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/support/string.h
@@ -118,6 +118,8 @@ char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length);
     lower(a)==lower(b), >0 if lower(a)>lower(b) */
 int gpr_stricmp(const char *a, const char *b);
 
+void *gpr_memrchr(const void *s, int c, size_t n);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/test/core/security/create_jwt.c b/test/core/security/create_jwt.c
index 741ace9bdd..ac795f29d2 100644
--- a/test/core/security/create_jwt.c
+++ b/test/core/security/create_jwt.c
@@ -72,6 +72,7 @@ int main(int argc, char **argv) {
   char *scope = NULL;
   char *json_key_file_path = NULL;
   char *service_url = NULL;
+  grpc_init();
   gpr_cmdline *cl = gpr_cmdline_create("create_jwt");
   gpr_cmdline_add_string(cl, "json_key", "File path of the json key.",
                          &json_key_file_path);
@@ -102,5 +103,6 @@ int main(int argc, char **argv) {
   create_jwt(json_key_file_path, service_url, scope);
 
   gpr_cmdline_destroy(cl);
+  grpc_shutdown();
   return 0;
 }
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index f8afba8d6d..9a21814adc 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -166,6 +166,13 @@ static const char claims_without_time_constraint[] =
     "  \"jti\": \"jwtuniqueid\","
     "  \"foo\": \"bar\"}";
 
+static const char claims_with_bad_subject[] =
+    "{ \"aud\": \"https://foo.com\","
+    "  \"iss\": \"evil@blah.foo.com\","
+    "  \"sub\": \"juju@blah.foo.com\","
+    "  \"jti\": \"jwtuniqueid\","
+    "  \"foo\": \"bar\"}";
+
 static const char invalid_claims[] =
     "{ \"aud\": \"https://foo.com\","
     "  \"iss\": 46," /* Issuer cannot be a number. */
@@ -179,6 +186,38 @@ typedef struct {
   const char *expected_subject;
 } verifier_test_config;
 
+static void test_jwt_issuer_email_domain(void) {
+  const char *d = grpc_jwt_issuer_email_domain("https://foo.com");
+  GPR_ASSERT(d == NULL);
+  d = grpc_jwt_issuer_email_domain("foo.com");
+  GPR_ASSERT(d == NULL);
+  d = grpc_jwt_issuer_email_domain("");
+  GPR_ASSERT(d == NULL);
+  d = grpc_jwt_issuer_email_domain("@");
+  GPR_ASSERT(d == NULL);
+  d = grpc_jwt_issuer_email_domain("bar@foo");
+  GPR_ASSERT(strcmp(d, "foo") == 0);
+  d = grpc_jwt_issuer_email_domain("bar@foo.com");
+  GPR_ASSERT(strcmp(d, "foo.com") == 0);
+  d = grpc_jwt_issuer_email_domain("bar@blah.foo.com");
+  GPR_ASSERT(strcmp(d, "foo.com") == 0);
+  d = grpc_jwt_issuer_email_domain("bar.blah@blah.foo.com");
+  GPR_ASSERT(strcmp(d, "foo.com") == 0);
+  d = grpc_jwt_issuer_email_domain("bar.blah@baz.blah.foo.com");
+  GPR_ASSERT(strcmp(d, "foo.com") == 0);
+
+  /* This is not a very good parser but make sure we do not crash on these weird
+     inputs. */
+  d = grpc_jwt_issuer_email_domain("@foo");
+  GPR_ASSERT(strcmp(d, "foo") == 0);
+  d = grpc_jwt_issuer_email_domain("bar@.");
+  GPR_ASSERT(d != NULL);
+  d = grpc_jwt_issuer_email_domain("bar@..");
+  GPR_ASSERT(d != NULL);
+  d = grpc_jwt_issuer_email_domain("bar@...");
+  GPR_ASSERT(d != NULL);
+}
+
 static void test_claims_success(void) {
   grpc_jwt_claims *claims;
   grpc_slice s = grpc_slice_from_copied_string(claims_without_time_constraint);
@@ -242,6 +281,19 @@ static void test_bad_audience_claims_failure(void) {
   grpc_jwt_claims_destroy(claims);
 }
 
+static void test_bad_subject_claims_failure(void) {
+  grpc_jwt_claims *claims;
+  grpc_slice s = grpc_slice_from_copied_string(claims_with_bad_subject);
+  grpc_json *json = grpc_json_parse_string_with_len(
+      (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
+  GPR_ASSERT(json != NULL);
+  claims = grpc_jwt_claims_from_json(json, s);
+  GPR_ASSERT(claims != NULL);
+  GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
+             GRPC_JWT_VERIFIER_BAD_SUBJECT);
+  grpc_jwt_claims_destroy(claims);
+}
+
 static char *json_key_str(const char *last_part) {
   size_t result_len = strlen(json_key_str_part1) + strlen(json_key_str_part2) +
                       strlen(last_part);
@@ -563,10 +615,12 @@ static void test_jwt_verifier_bad_format(void) {
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
+  test_jwt_issuer_email_domain();
   test_claims_success();
   test_expired_claims_failure();
   test_invalid_claims_failure();
   test_bad_audience_claims_failure();
+  test_bad_subject_claims_failure();
   test_jwt_verifier_google_email_issuer_success();
   test_jwt_verifier_custom_email_issuer_success();
   test_jwt_verifier_url_issuer_success();
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 043d29e6bb..ccc85c9f32 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -93,6 +93,7 @@ int main(int argc, char **argv) {
   char *aud = NULL;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
+  grpc_init();
   cl = gpr_cmdline_create("JWT verifier tool");
   gpr_cmdline_add_string(cl, "jwt", "JSON web token to verify", &jwt);
   gpr_cmdline_add_string(cl, "aud", "Audience for the JWT", &aud);
@@ -131,5 +132,6 @@ int main(int argc, char **argv) {
 
   grpc_jwt_verifier_destroy(verifier);
   gpr_cmdline_destroy(cl);
+  grpc_shutdown();
   return !sync.success;
 }
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index 78b77fad8e..af232db350 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -243,6 +243,8 @@ static void test_int64toa() {
 static void test_leftpad() {
   char *padded;
 
+  LOG_TEST_NAME("test_leftpad");
+
   padded = gpr_leftpad("foo", ' ', 5);
   GPR_ASSERT(0 == strcmp("  foo", padded));
   gpr_free(padded);
@@ -273,12 +275,25 @@ static void test_leftpad() {
 }
 
 static void test_stricmp(void) {
+  LOG_TEST_NAME("test_stricmp");
+
   GPR_ASSERT(0 == gpr_stricmp("hello", "hello"));
   GPR_ASSERT(0 == gpr_stricmp("HELLO", "hello"));
   GPR_ASSERT(gpr_stricmp("a", "b") < 0);
   GPR_ASSERT(gpr_stricmp("b", "a") > 0);
 }
 
+static void test_memrchr(void) {
+  LOG_TEST_NAME("test_memrchr");
+
+  GPR_ASSERT(NULL == gpr_memrchr(NULL, 'a', 0));
+  GPR_ASSERT(NULL == gpr_memrchr("", 'a', 0));
+  GPR_ASSERT(NULL == gpr_memrchr("hello", 'b', 5));
+  GPR_ASSERT(0 == strcmp((const char *)gpr_memrchr("hello", 'h', 5), "hello"));
+  GPR_ASSERT(0 == strcmp((const char *)gpr_memrchr("hello", 'o', 5), "o"));
+  GPR_ASSERT(0 == strcmp((const char *)gpr_memrchr("hello", 'l', 5), "lo"));
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   test_strdup();
@@ -291,5 +306,6 @@ int main(int argc, char **argv) {
   test_int64toa();
   test_leftpad();
   test_stricmp();
+  test_memrchr();
   return 0;
 }
-- 
GitLab


From 9383d2b809084589b677722e060ba585b536ddfa Mon Sep 17 00:00:00 2001
From: Yuan He <lendage@gmail.com>
Date: Tue, 8 Nov 2016 10:25:30 +0800
Subject: [PATCH 192/344] Ruby: show error class and message instead of unknown

---
 .gitignore                             |  3 +++
 src/ruby/lib/grpc/generic/rpc_desc.rb  |  2 +-
 src/ruby/spec/generic/rpc_desc_spec.rb | 16 +++++++++++-----
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3cc35ff7cd..98d4b00d52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,3 +103,6 @@ artifacts/
 
 # IDE specific folder for JetBrains IDEs
 .idea/
+
+# tmp folder
+tmp
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index cd17aed8e7..d46c4a1b5c 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -119,7 +119,7 @@ module GRPC
       # Send back a UNKNOWN status to the client
       GRPC.logger.warn("failed handler: #{active_call}; sending status:UNKNOWN")
       GRPC.logger.warn(e)
-      send_status(active_call, UNKNOWN, 'unkown error handling call on server')
+      send_status(active_call, UNKNOWN, "#{e.class}: #{e.message}")
     end
 
     def assert_arity_matches(mth)
diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb
index a3f0efa603..1ace7211e9 100644
--- a/src/ruby/spec/generic/rpc_desc_spec.rb
+++ b/src/ruby/spec/generic/rpc_desc_spec.rb
@@ -48,7 +48,6 @@ describe GRPC::RpcDesc do
     @bidi_streamer = RpcDesc.new('ss', Stream.new(Object.new),
                                  Stream.new(Object.new), 'encode', 'decode')
     @bs_code = INTERNAL
-    @no_reason = 'unkown error handling call on server'
     @ok_response = Object.new
   end
 
@@ -62,8 +61,9 @@ describe GRPC::RpcDesc do
 
     it 'sends status UNKNOWN if other StandardErrors are raised' do
       expect(@call).to receive(:remote_read).once.and_return(Object.new)
-      expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason,
-                                                        false, metadata: {})
+      expect(@call).to receive(:send_status).once.with(UNKNOWN,
+                                                       arg_error_msg,
+                                                       false, metadata: {})
       this_desc.run_server_method(@call, method(:other_error))
     end
 
@@ -112,7 +112,7 @@ describe GRPC::RpcDesc do
       end
 
       it 'sends status UNKNOWN if other StandardErrors are raised' do
-        expect(@call).to receive(:send_status).once.with(UNKNOWN, @no_reason,
+        expect(@call).to receive(:send_status).once.with(UNKNOWN, arg_error_msg,
                                                          false, metadata: {})
         @client_streamer.run_server_method(@call, method(:other_error_alt))
       end
@@ -174,8 +174,9 @@ describe GRPC::RpcDesc do
       end
 
       it 'sends status UNKNOWN if other StandardErrors are raised' do
+        error_msg = arg_error_msg(StandardError.new)
         expect(@call).to receive(:run_server_bidi).and_raise(StandardError)
-        expect(@call).to receive(:send_status).once.with(UNKNOWN, @no_reason,
+        expect(@call).to receive(:send_status).once.with(UNKNOWN, error_msg,
                                                          false, metadata: {})
         @bidi_streamer.run_server_method(@call, method(:other_error_alt))
       end
@@ -342,4 +343,9 @@ describe GRPC::RpcDesc do
   def other_error_alt(_call)
     fail(ArgumentError, 'other error')
   end
+
+  def arg_error_msg(error = nil)
+    error ||= ArgumentError.new('other error')
+    "#{error.class}: #{error.message}"
+  end
 end
-- 
GitLab


From 2b605837b004e6b663b9cc51b3e3e2847a2c41f4 Mon Sep 17 00:00:00 2001
From: Yuan He <lendage@gmail.com>
Date: Thu, 22 Dec 2016 15:27:50 +0800
Subject: [PATCH 193/344] take tmp out of .gitignore file

---
 .gitignore | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 98d4b00d52..3cc35ff7cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,6 +103,3 @@ artifacts/
 
 # IDE specific folder for JetBrains IDEs
 .idea/
-
-# tmp folder
-tmp
-- 
GitLab


From 5c79a3199c1b47d1a2d3ff4dc5636c9c90ca2a7f Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 20 Dec 2016 11:02:50 +0100
Subject: [PATCH 194/344] cleanup tools/run_tests directory

---
 .gitignore                                    |  2 +-
 .../{ => generated}/configs.json.template     |  0
 .../sources_and_headers.json.template         |  0
 .../{ => generated}/tests.json.template       |  0
 tools/buildgen/generate_projects.py           |  2 +-
 .../__init__.py}                              | 41 +----------
 .../{ => artifacts}/artifact_targets.py       | 37 +++++-----
 .../{ => artifacts}/build_artifact_csharp.bat |  0
 .../{ => artifacts}/build_artifact_csharp.sh  |  2 +-
 .../{ => artifacts}/build_artifact_node.bat   |  0
 .../{ => artifacts}/build_artifact_node.sh    |  2 +-
 .../{ => artifacts}/build_artifact_php.sh     |  2 +-
 .../{ => artifacts}/build_artifact_protoc.bat |  2 +-
 .../{ => artifacts}/build_artifact_protoc.sh  |  2 +-
 .../{ => artifacts}/build_artifact_python.bat |  0
 .../{ => artifacts}/build_artifact_python.sh  |  2 +-
 .../{ => artifacts}/build_artifact_ruby.sh    |  2 +-
 .../{ => artifacts}/build_package_node.sh     |  2 +-
 .../{ => artifacts}/build_package_php.sh      |  2 +-
 .../{ => artifacts}/build_package_python.sh   |  2 +-
 .../{ => artifacts}/build_package_ruby.sh     |  2 +-
 .../{ => artifacts}/distribtest_targets.py    |  6 +-
 .../{ => artifacts}/package_targets.py        | 15 ++--
 .../{ => build_stats}/build_stats_schema.json |  0
 .../build_stats_schema_no_matrix.json         |  0
 tools/run_tests/{ => generated}/configs.json  |  0
 .../{ => generated}/sources_and_headers.json  |  0
 tools/run_tests/{ => generated}/tests.json    |  0
 .../{ => helper_scripts}/build_csharp.sh      |  2 +-
 .../build_csharp_coreclr.bat                  |  2 +-
 .../build_csharp_coreclr.sh                   |  2 +-
 .../{ => helper_scripts}/build_node.bat       |  0
 .../{ => helper_scripts}/build_node.sh        |  2 +-
 .../{ => helper_scripts}/build_php.sh         |  2 +-
 .../{ => helper_scripts}/build_python.sh      |  2 +-
 .../build_python_msys2.sh                     |  0
 .../{ => helper_scripts}/build_ruby.sh        |  2 +-
 .../{ => helper_scripts}/post_tests_c.sh      |  2 +-
 .../post_tests_csharp.bat                     |  2 +-
 .../{ => helper_scripts}/post_tests_csharp.sh |  2 +-
 .../{ => helper_scripts}/post_tests_php.sh    |  2 +-
 .../{ => helper_scripts}/post_tests_ruby.sh   |  2 +-
 .../{ => helper_scripts}/pre_build_c.bat      |  2 +-
 .../{ => helper_scripts}/pre_build_csharp.bat |  2 +-
 .../{ => helper_scripts}/pre_build_csharp.sh  |  2 +-
 .../{ => helper_scripts}/pre_build_node.bat   |  0
 .../{ => helper_scripts}/pre_build_node.sh    |  0
 .../{ => helper_scripts}/pre_build_ruby.sh    |  2 +-
 .../{ => helper_scripts}/run_lcov.sh          |  2 +-
 .../{ => helper_scripts}/run_node.bat         |  0
 .../{ => helper_scripts}/run_node.sh          |  2 +-
 .../{ => helper_scripts}/run_python.sh        |  2 +-
 .../{ => helper_scripts}/run_ruby.sh          |  2 +-
 .../run_tests_in_workspace.sh                 |  2 +-
 .../interop_html_report.template              |  0
 tools/run_tests/python_utils/__init__.py      | 28 ++++++++
 .../{ => python_utils}/antagonist.py          |  0
 .../run_tests/{ => python_utils}/dockerjob.py |  3 +-
 .../filter_pull_request_tests.py              |  0
 tools/run_tests/{ => python_utils}/jobset.py  |  0
 .../{ => python_utils}/port_server.py         |  0
 .../{ => python_utils}/report_utils.py        |  0
 .../{ => python_utils}/watch_dirs.py          |  0
 tools/run_tests/run_interop_tests.py          |  7 +-
 tools/run_tests/run_performance_tests.py      |  8 +--
 tools/run_tests/run_stress_tests.py           |  5 +-
 tools/run_tests/run_tests.py                  | 72 +++++++++----------
 tools/run_tests/run_tests_matrix.py           |  9 +--
 .../sanity/check_sources_and_headers.py       |  2 +-
 .../run_tests/sanity/check_test_filtering.py  |  2 +-
 tools/run_tests/task_runner.py                |  9 ++-
 71 files changed, 157 insertions(+), 155 deletions(-)
 rename templates/tools/run_tests/{ => generated}/configs.json.template (100%)
 rename templates/tools/run_tests/{ => generated}/sources_and_headers.json.template (100%)
 rename templates/tools/run_tests/{ => generated}/tests.json.template (100%)
 rename tools/run_tests/{prepare_travis.sh => artifacts/__init__.py} (60%)
 mode change 100755 => 100644
 rename tools/run_tests/{ => artifacts}/artifact_targets.py (89%)
 rename tools/run_tests/{ => artifacts}/build_artifact_csharp.bat (100%)
 rename tools/run_tests/{ => artifacts}/build_artifact_csharp.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_artifact_node.bat (100%)
 rename tools/run_tests/{ => artifacts}/build_artifact_node.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_artifact_php.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_artifact_protoc.bat (96%)
 rename tools/run_tests/{ => artifacts}/build_artifact_protoc.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_artifact_python.bat (100%)
 rename tools/run_tests/{ => artifacts}/build_artifact_python.sh (99%)
 rename tools/run_tests/{ => artifacts}/build_artifact_ruby.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_package_node.sh (99%)
 rename tools/run_tests/{ => artifacts}/build_package_php.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_package_python.sh (98%)
 rename tools/run_tests/{ => artifacts}/build_package_ruby.sh (99%)
 rename tools/run_tests/{ => artifacts}/distribtest_targets.py (99%)
 rename tools/run_tests/{ => artifacts}/package_targets.py (94%)
 rename tools/run_tests/{ => build_stats}/build_stats_schema.json (100%)
 rename tools/run_tests/{ => build_stats}/build_stats_schema_no_matrix.json (100%)
 rename tools/run_tests/{ => generated}/configs.json (100%)
 rename tools/run_tests/{ => generated}/sources_and_headers.json (100%)
 rename tools/run_tests/{ => generated}/tests.json (100%)
 rename tools/run_tests/{ => helper_scripts}/build_csharp.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/build_csharp_coreclr.bat (98%)
 rename tools/run_tests/{ => helper_scripts}/build_csharp_coreclr.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/build_node.bat (100%)
 rename tools/run_tests/{ => helper_scripts}/build_node.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/build_php.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/build_python.sh (99%)
 rename tools/run_tests/{ => helper_scripts}/build_python_msys2.sh (100%)
 rename tools/run_tests/{ => helper_scripts}/build_ruby.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/post_tests_c.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/post_tests_csharp.bat (98%)
 rename tools/run_tests/{ => helper_scripts}/post_tests_csharp.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/post_tests_php.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/post_tests_ruby.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_c.bat (98%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_csharp.bat (99%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_csharp.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_node.bat (100%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_node.sh (100%)
 rename tools/run_tests/{ => helper_scripts}/pre_build_ruby.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/run_lcov.sh (97%)
 rename tools/run_tests/{ => helper_scripts}/run_node.bat (100%)
 rename tools/run_tests/{ => helper_scripts}/run_node.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/run_python.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/run_ruby.sh (98%)
 rename tools/run_tests/{ => helper_scripts}/run_tests_in_workspace.sh (98%)
 rename tools/run_tests/{ => interop}/interop_html_report.template (100%)
 create mode 100644 tools/run_tests/python_utils/__init__.py
 rename tools/run_tests/{ => python_utils}/antagonist.py (100%)
 rename tools/run_tests/{ => python_utils}/dockerjob.py (99%)
 rename tools/run_tests/{ => python_utils}/filter_pull_request_tests.py (100%)
 rename tools/run_tests/{ => python_utils}/jobset.py (100%)
 rename tools/run_tests/{ => python_utils}/port_server.py (100%)
 rename tools/run_tests/{ => python_utils}/report_utils.py (100%)
 rename tools/run_tests/{ => python_utils}/watch_dirs.py (100%)

diff --git a/.gitignore b/.gitignore
index 3cc35ff7cd..1610bd40cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,7 +96,7 @@ DerivedData
 Pods/
 
 # Artifacts directory
-artifacts/
+/artifacts/
 
 # Git generated files for conflicting
 *.orig
diff --git a/templates/tools/run_tests/configs.json.template b/templates/tools/run_tests/generated/configs.json.template
similarity index 100%
rename from templates/tools/run_tests/configs.json.template
rename to templates/tools/run_tests/generated/configs.json.template
diff --git a/templates/tools/run_tests/sources_and_headers.json.template b/templates/tools/run_tests/generated/sources_and_headers.json.template
similarity index 100%
rename from templates/tools/run_tests/sources_and_headers.json.template
rename to templates/tools/run_tests/generated/sources_and_headers.json.template
diff --git a/templates/tools/run_tests/tests.json.template b/templates/tools/run_tests/generated/tests.json.template
similarity index 100%
rename from templates/tools/run_tests/tests.json.template
rename to templates/tools/run_tests/generated/tests.json.template
diff --git a/tools/buildgen/generate_projects.py b/tools/buildgen/generate_projects.py
index 5e78ad52d6..f8ddaf4963 100755
--- a/tools/buildgen/generate_projects.py
+++ b/tools/buildgen/generate_projects.py
@@ -36,7 +36,7 @@ import shutil
 import sys
 import tempfile
 import multiprocessing
-sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '..', 'run_tests'))
+sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '..', 'run_tests', 'python_utils'))
 
 assert sys.argv[1:], 'run generate_projects.sh instead of this directly'
 
diff --git a/tools/run_tests/prepare_travis.sh b/tools/run_tests/artifacts/__init__.py
old mode 100755
new mode 100644
similarity index 60%
rename from tools/run_tests/prepare_travis.sh
rename to tools/run_tests/artifacts/__init__.py
index 10546535e8..100a624dc9
--- a/tools/run_tests/prepare_travis.sh
+++ b/tools/run_tests/artifacts/__init__.py
@@ -1,5 +1,4 @@
-#!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,41 +26,3 @@
 # 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.
-
-cd `dirname $0`/../..
-grpc_dir=`pwd`
-
-distrib=`md5sum /etc/issue | cut -f1 -d\ `
-echo "Configuring for distribution $distrib"
-git submodule | while read sha path extra ; do
-  cd /tmp
-  name=`basename $path`
-  file=$name-$sha-$CONFIG-prebuilt-$distrib.tar.gz
-  echo -n "Looking for $file ..."
-  url=http://storage.googleapis.com/grpc-prebuilt-packages/$file
-  wget -q $url && (
-    echo " Found."
-    tar xfz $file
-  ) || echo " Not found."
-done
-
-mkdir -p bins/$CONFIG/protobuf
-mkdir -p libs/$CONFIG/protobuf
-mkdir -p libs/$CONFIG/openssl
-
-function cpt {
-  cp /tmp/prebuilt/$1 $2/$CONFIG/$3
-  touch $2/$CONFIG/$3/`basename $1`
-}
-
-if [ -e /tmp/prebuilt/bin/protoc ] ; then
-  touch third_party/protobuf/configure
-  cpt bin/protoc bins protobuf
-  cpt lib/libprotoc.a libs protobuf
-  cpt lib/libprotobuf.a libs protobuf
-fi
-
-if [ -e /tmp/prebuilt/lib/libssl.a ] ; then
-  cpt lib/libcrypto.a libs openssl
-  cpt lib/libssl.a libs openssl
-fi
diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
similarity index 89%
rename from tools/run_tests/artifact_targets.py
rename to tools/run_tests/artifacts/artifact_targets.py
index 65d34e17e1..005d99790a 100644
--- a/tools/run_tests/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -35,7 +35,8 @@ import random
 import string
 import sys
 
-import jobset
+sys.path.insert(0, os.path.abspath('..'))
+import python_utils.jobset as jobset
 
 
 def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
@@ -113,7 +114,7 @@ class PythonArtifact:
       environ['GRPC_BUILD_MANYLINUX_WHEEL'] = 'TRUE'
       return create_docker_jobspec(self.name,
           'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch,
-          'tools/run_tests/build_artifact_python.sh',
+          'tools/run_tests/artifacts/build_artifact_python.sh',
           environ=environ,
           timeout_seconds=60*60)
     elif self.platform == 'windows':
@@ -125,7 +126,7 @@ class PythonArtifact:
       # seed.  We create a random temp-dir here
       dir = ''.join(random.choice(string.ascii_uppercase) for _ in range(10))
       return create_jobspec(self.name,
-                            ['tools\\run_tests\\build_artifact_python.bat',
+                            ['tools\\run_tests\\artifacts\\build_artifact_python.bat',
                              self.py_version,
                              '32' if self.arch == 'x86' else '64',
                              dir
@@ -136,7 +137,7 @@ class PythonArtifact:
       environ['PYTHON'] = self.py_version
       environ['SKIP_PIP_INSTALL'] = 'TRUE'
       return create_jobspec(self.name,
-                            ['tools/run_tests/build_artifact_python.sh'],
+                            ['tools/run_tests/artifacts/build_artifact_python.sh'],
                             environ=environ)
 
   def __str__(self):
@@ -165,11 +166,11 @@ class RubyArtifact:
           environ['SETARCH_CMD'] = 'linux32'
         return create_docker_jobspec(self.name,
             'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
-            'tools/run_tests/build_artifact_ruby.sh',
+            'tools/run_tests/artifacts/build_artifact_ruby.sh',
             environ=environ)
       else:
         return create_jobspec(self.name,
-                              ['tools/run_tests/build_artifact_ruby.sh'])
+                              ['tools/run_tests/artifacts/build_artifact_ruby.sh'])
 
 
 class CSharpExtArtifact:
@@ -184,7 +185,7 @@ class CSharpExtArtifact:
   def pre_build_jobspecs(self):
     if self.platform == 'windows':
       return [create_jobspec('prebuild_%s' % self.name,
-                             ['tools\\run_tests\\pre_build_c.bat'],
+                             ['tools\\run_tests\\helper_scripts\\pre_build_c.bat'],
                              shell=True,
                              flake_retries=5,
                              timeout_retries=2)]
@@ -195,7 +196,7 @@ class CSharpExtArtifact:
     if self.platform == 'windows':
       msbuild_platform = 'Win32' if self.arch == 'x86' else self.arch
       return create_jobspec(self.name,
-                            ['tools\\run_tests\\build_artifact_csharp.bat',
+                            ['tools\\run_tests\\artifacts\\build_artifact_csharp.bat',
                              'vsprojects\\grpc_csharp_ext.sln',
                              '/p:Configuration=Release',
                              '/p:PlatformToolset=v120',
@@ -210,14 +211,14 @@ class CSharpExtArtifact:
       if self.platform == 'linux':
         return create_docker_jobspec(self.name,
             'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
-            'tools/run_tests/build_artifact_csharp.sh',
+            'tools/run_tests/artifacts/build_artifact_csharp.sh',
             environ=environ)
       else:
         archflag = _ARCH_FLAG_MAP[self.arch]
         environ['CFLAGS'] += ' %s %s' % (archflag, _MACOS_COMPAT_FLAG)
         environ['LDFLAGS'] += ' %s' % archflag
         return create_jobspec(self.name,
-                              ['tools/run_tests/build_artifact_csharp.sh'],
+                              ['tools/run_tests/artifacts/build_artifact_csharp.sh'],
                               environ=environ)
 
   def __str__(self):
@@ -245,7 +246,7 @@ class NodeExtArtifact:
   def build_jobspec(self):
     if self.platform == 'windows':
       return create_jobspec(self.name,
-                            ['tools\\run_tests\\build_artifact_node.bat',
+                            ['tools\\run_tests\\artifacts\\build_artifact_node.bat',
                              self.gyp_arch],
                             shell=True)
     else:
@@ -253,10 +254,10 @@ class NodeExtArtifact:
         return create_docker_jobspec(
             self.name,
             'tools/dockerfile/grpc_artifact_linux_{}'.format(self.arch),
-            'tools/run_tests/build_artifact_node.sh {}'.format(self.gyp_arch))
+            'tools/run_tests/artifacts/build_artifact_node.sh {}'.format(self.gyp_arch))
       else:
         return create_jobspec(self.name,
-                              ['tools/run_tests/build_artifact_node.sh',
+                              ['tools/run_tests/artifacts/build_artifact_node.sh',
                                self.gyp_arch])
 
 class PHPArtifact:
@@ -276,10 +277,10 @@ class PHPArtifact:
       return create_docker_jobspec(
           self.name,
           'tools/dockerfile/grpc_artifact_linux_{}'.format(self.arch),
-          'tools/run_tests/build_artifact_php.sh')
+          'tools/run_tests/artifacts/build_artifact_php.sh')
     else:
       return create_jobspec(self.name,
-                            ['tools/run_tests/build_artifact_php.sh'])
+                            ['tools/run_tests/artifacts/build_artifact_php.sh'])
 
 class ProtocArtifact:
   """Builds protoc and protoc-plugin artifacts"""
@@ -306,18 +307,18 @@ class ProtocArtifact:
       if self.platform == 'linux':
         return create_docker_jobspec(self.name,
             'tools/dockerfile/grpc_artifact_protoc',
-            'tools/run_tests/build_artifact_protoc.sh',
+            'tools/run_tests/artifacts/build_artifact_protoc.sh',
             environ=environ)
       else:
         environ['CXXFLAGS'] += ' -std=c++11 -stdlib=libc++ %s' % _MACOS_COMPAT_FLAG
         return create_jobspec(self.name,
-            ['tools/run_tests/build_artifact_protoc.sh'],
+            ['tools/run_tests/artifacts/build_artifact_protoc.sh'],
             environ=environ)
     else:
       generator = 'Visual Studio 12 Win64' if self.arch == 'x64' else 'Visual Studio 12' 
       vcplatform = 'x64' if self.arch == 'x64' else 'Win32'
       return create_jobspec(self.name,
-                            ['tools\\run_tests\\build_artifact_protoc.bat'],
+                            ['tools\\run_tests\\artifacts\\build_artifact_protoc.bat'],
                             environ={'generator': generator,
                                      'Platform': vcplatform})
 
diff --git a/tools/run_tests/build_artifact_csharp.bat b/tools/run_tests/artifacts/build_artifact_csharp.bat
similarity index 100%
rename from tools/run_tests/build_artifact_csharp.bat
rename to tools/run_tests/artifacts/build_artifact_csharp.bat
diff --git a/tools/run_tests/build_artifact_csharp.sh b/tools/run_tests/artifacts/build_artifact_csharp.sh
similarity index 98%
rename from tools/run_tests/build_artifact_csharp.sh
rename to tools/run_tests/artifacts/build_artifact_csharp.sh
index 7438713f5c..aed04b2745 100755
--- a/tools/run_tests/build_artifact_csharp.sh
+++ b/tools/run_tests/artifacts/build_artifact_csharp.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 make grpc_csharp_ext
 
diff --git a/tools/run_tests/build_artifact_node.bat b/tools/run_tests/artifacts/build_artifact_node.bat
similarity index 100%
rename from tools/run_tests/build_artifact_node.bat
rename to tools/run_tests/artifacts/build_artifact_node.bat
diff --git a/tools/run_tests/build_artifact_node.sh b/tools/run_tests/artifacts/build_artifact_node.sh
similarity index 98%
rename from tools/run_tests/build_artifact_node.sh
rename to tools/run_tests/artifacts/build_artifact_node.sh
index 778a5c95d4..1066ebde19 100755
--- a/tools/run_tests/build_artifact_node.sh
+++ b/tools/run_tests/artifacts/build_artifact_node.sh
@@ -34,7 +34,7 @@ source ~/.nvm/nvm.sh
 nvm use 4
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 rm -rf build || true
 
diff --git a/tools/run_tests/build_artifact_php.sh b/tools/run_tests/artifacts/build_artifact_php.sh
similarity index 98%
rename from tools/run_tests/build_artifact_php.sh
rename to tools/run_tests/artifacts/build_artifact_php.sh
index 669447fa9a..c8d55860c1 100755
--- a/tools/run_tests/build_artifact_php.sh
+++ b/tools/run_tests/artifacts/build_artifact_php.sh
@@ -31,7 +31,7 @@
 PHP_TARGET_ARCH=$1
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 mkdir -p artifacts
 
diff --git a/tools/run_tests/build_artifact_protoc.bat b/tools/run_tests/artifacts/build_artifact_protoc.bat
similarity index 96%
rename from tools/run_tests/build_artifact_protoc.bat
rename to tools/run_tests/artifacts/build_artifact_protoc.bat
index b2bf86da40..fd93318833 100644
--- a/tools/run_tests/build_artifact_protoc.bat
+++ b/tools/run_tests/artifacts/build_artifact_protoc.bat
@@ -34,7 +34,7 @@ cd third_party/protobuf/cmake
 
 mkdir build & cd build
 mkdir solution & cd solution
-cmake -G "%generator%" -Dprotobuf_BUILD_TESTS=OFF ../.. || goto :error
+cmake -G "%generator%" -Dprotobuf_BUILD_TESTS=OFF ../../.. || goto :error
 endlocal
 
 call vsprojects/build_plugins.bat || goto :error
diff --git a/tools/run_tests/build_artifact_protoc.sh b/tools/run_tests/artifacts/build_artifact_protoc.sh
similarity index 98%
rename from tools/run_tests/build_artifact_protoc.sh
rename to tools/run_tests/artifacts/build_artifact_protoc.sh
index 161d3a84d6..26c2280eff 100755
--- a/tools/run_tests/build_artifact_protoc.sh
+++ b/tools/run_tests/artifacts/build_artifact_protoc.sh
@@ -33,7 +33,7 @@ source scl_source enable devtoolset-1.1
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 make plugins
 
diff --git a/tools/run_tests/build_artifact_python.bat b/tools/run_tests/artifacts/build_artifact_python.bat
similarity index 100%
rename from tools/run_tests/build_artifact_python.bat
rename to tools/run_tests/artifacts/build_artifact_python.bat
diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
similarity index 99%
rename from tools/run_tests/build_artifact_python.sh
rename to tools/run_tests/artifacts/build_artifact_python.sh
index 2a1d41fd68..5a5506029a 100755
--- a/tools/run_tests/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 export GRPC_PYTHON_USE_CUSTOM_BDIST=0
 export GRPC_PYTHON_BUILD_WITH_CYTHON=1
diff --git a/tools/run_tests/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh
similarity index 98%
rename from tools/run_tests/build_artifact_ruby.sh
rename to tools/run_tests/artifacts/build_artifact_ruby.sh
index 2d97b4068b..019efb01fd 100755
--- a/tools/run_tests/build_artifact_ruby.sh
+++ b/tools/run_tests/artifacts/build_artifact_ruby.sh
@@ -31,7 +31,7 @@ set -ex
 
 SYSTEM=`uname | cut -f 1 -d_`
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 set +ex
 [[ -s /etc/profile.d/rvm.sh ]] && . /etc/profile.d/rvm.sh
 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/artifacts/build_package_node.sh
similarity index 99%
rename from tools/run_tests/build_package_node.sh
rename to tools/run_tests/artifacts/build_package_node.sh
index a5636cf87a..8b5e8c0bc1 100755
--- a/tools/run_tests/build_package_node.sh
+++ b/tools/run_tests/artifacts/build_package_node.sh
@@ -33,7 +33,7 @@ source ~/.nvm/nvm.sh
 nvm use 4
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 base=$(pwd)
 
diff --git a/tools/run_tests/build_package_php.sh b/tools/run_tests/artifacts/build_package_php.sh
similarity index 98%
rename from tools/run_tests/build_package_php.sh
rename to tools/run_tests/artifacts/build_package_php.sh
index 56e3319ed9..42a8d9f8df 100755
--- a/tools/run_tests/build_package_php.sh
+++ b/tools/run_tests/artifacts/build_package_php.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 mkdir -p artifacts/
 cp -r $EXTERNAL_GIT_ROOT/architecture={x86,x64},language=php,platform={windows,linux,macos}/artifacts/* artifacts/ || true
diff --git a/tools/run_tests/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh
similarity index 98%
rename from tools/run_tests/build_package_python.sh
rename to tools/run_tests/artifacts/build_package_python.sh
index 2511a6ae46..4a1c15ceee 100755
--- a/tools/run_tests/build_package_python.sh
+++ b/tools/run_tests/artifacts/build_package_python.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 mkdir -p artifacts/
 
diff --git a/tools/run_tests/build_package_ruby.sh b/tools/run_tests/artifacts/build_package_ruby.sh
similarity index 99%
rename from tools/run_tests/build_package_ruby.sh
rename to tools/run_tests/artifacts/build_package_ruby.sh
index 0a755bddb0..b4d20d8a4c 100755
--- a/tools/run_tests/build_package_ruby.sh
+++ b/tools/run_tests/artifacts/build_package_ruby.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 base=$(pwd)
 
diff --git a/tools/run_tests/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py
similarity index 99%
rename from tools/run_tests/distribtest_targets.py
rename to tools/run_tests/artifacts/distribtest_targets.py
index a16daac4fe..a7535b3852 100644
--- a/tools/run_tests/distribtest_targets.py
+++ b/tools/run_tests/artifacts/distribtest_targets.py
@@ -30,7 +30,11 @@
 
 """Definition of targets run distribution package tests."""
 
-import jobset
+import os.path
+import sys
+
+sys.path.insert(0, os.path.abspath('..'))
+import python_utils.jobset as jobset
 
 
 def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/artifacts/package_targets.py
similarity index 94%
rename from tools/run_tests/package_targets.py
rename to tools/run_tests/artifacts/package_targets.py
index 673affeac0..d490f571c3 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/artifacts/package_targets.py
@@ -30,7 +30,12 @@
 
 """Definition of targets to build distribution packages."""
 
-import jobset
+import os.path
+import sys
+
+sys.path.insert(0, os.path.abspath('..'))
+import python_utils.jobset as jobset
+
 
 def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
                    flake_retries=0, timeout_retries=0):
@@ -114,7 +119,7 @@ class NodePackage:
     return create_docker_jobspec(
         self.name,
         'tools/dockerfile/grpc_artifact_linux_x64',
-        'tools/run_tests/build_package_node.sh')
+        'tools/run_tests/artifacts/build_package_node.sh')
 
 
 class RubyPackage:
@@ -131,7 +136,7 @@ class RubyPackage:
     return create_docker_jobspec(
         self.name,
         'tools/dockerfile/grpc_artifact_linux_x64',
-        'tools/run_tests/build_package_ruby.sh')
+        'tools/run_tests/artifacts/build_package_ruby.sh')
 
 
 class PythonPackage:
@@ -148,7 +153,7 @@ class PythonPackage:
     return create_docker_jobspec(
         self.name,
         'tools/dockerfile/grpc_artifact_linux_x64',
-        'tools/run_tests/build_package_python.sh')
+        'tools/run_tests/artifacts/build_package_python.sh')
 
 
 class PHPPackage:
@@ -165,7 +170,7 @@ class PHPPackage:
     return create_docker_jobspec(
         self.name,
         'tools/dockerfile/grpc_artifact_linux_x64',
-        'tools/run_tests/build_package_php.sh')
+        'tools/run_tests/artifacts/build_package_php.sh')
 
 
 def targets():
diff --git a/tools/run_tests/build_stats_schema.json b/tools/run_tests/build_stats/build_stats_schema.json
similarity index 100%
rename from tools/run_tests/build_stats_schema.json
rename to tools/run_tests/build_stats/build_stats_schema.json
diff --git a/tools/run_tests/build_stats_schema_no_matrix.json b/tools/run_tests/build_stats/build_stats_schema_no_matrix.json
similarity index 100%
rename from tools/run_tests/build_stats_schema_no_matrix.json
rename to tools/run_tests/build_stats/build_stats_schema_no_matrix.json
diff --git a/tools/run_tests/configs.json b/tools/run_tests/generated/configs.json
similarity index 100%
rename from tools/run_tests/configs.json
rename to tools/run_tests/generated/configs.json
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
similarity index 100%
rename from tools/run_tests/sources_and_headers.json
rename to tools/run_tests/generated/sources_and_headers.json
diff --git a/tools/run_tests/tests.json b/tools/run_tests/generated/tests.json
similarity index 100%
rename from tools/run_tests/tests.json
rename to tools/run_tests/generated/tests.json
diff --git a/tools/run_tests/build_csharp.sh b/tools/run_tests/helper_scripts/build_csharp.sh
similarity index 97%
rename from tools/run_tests/build_csharp.sh
rename to tools/run_tests/helper_scripts/build_csharp.sh
index 48ce11a10b..84c5b1c777 100755
--- a/tools/run_tests/build_csharp.sh
+++ b/tools/run_tests/helper_scripts/build_csharp.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../../src/csharp
+cd $(dirname $0)/../../../src/csharp
 
 # overriding NativeDependenciesConfigurationUnix is needed to make gcov code coverage work.
 xbuild /p:Configuration=$MSBUILD_CONFIG /p:NativeDependenciesConfigurationUnix=$CONFIG Grpc.sln
diff --git a/tools/run_tests/build_csharp_coreclr.bat b/tools/run_tests/helper_scripts/build_csharp_coreclr.bat
similarity index 98%
rename from tools/run_tests/build_csharp_coreclr.bat
rename to tools/run_tests/helper_scripts/build_csharp_coreclr.bat
index b6e3ccbd2b..78e5f5998b 100644
--- a/tools/run_tests/build_csharp_coreclr.bat
+++ b/tools/run_tests/helper_scripts/build_csharp_coreclr.bat
@@ -29,7 +29,7 @@
 
 setlocal
 
-cd /d %~dp0\..\..\src\csharp
+cd /d %~dp0\..\..\..\src\csharp
 
 dotnet restore . || goto :error
 
diff --git a/tools/run_tests/build_csharp_coreclr.sh b/tools/run_tests/helper_scripts/build_csharp_coreclr.sh
similarity index 97%
rename from tools/run_tests/build_csharp_coreclr.sh
rename to tools/run_tests/helper_scripts/build_csharp_coreclr.sh
index 02cf0d39cb..dd5fd31c75 100755
--- a/tools/run_tests/build_csharp_coreclr.sh
+++ b/tools/run_tests/helper_scripts/build_csharp_coreclr.sh
@@ -30,7 +30,7 @@
 
 set -ex
 
-cd $(dirname $0)/../../src/csharp
+cd $(dirname $0)/../../../src/csharp
 
 # TODO(jtattermusch): introduce caching
 dotnet restore .
diff --git a/tools/run_tests/build_node.bat b/tools/run_tests/helper_scripts/build_node.bat
similarity index 100%
rename from tools/run_tests/build_node.bat
rename to tools/run_tests/helper_scripts/build_node.bat
diff --git a/tools/run_tests/build_node.sh b/tools/run_tests/helper_scripts/build_node.sh
similarity index 98%
rename from tools/run_tests/build_node.sh
rename to tools/run_tests/helper_scripts/build_node.sh
index d9292fd8aa..8a928bb762 100755
--- a/tools/run_tests/build_node.sh
+++ b/tools/run_tests/helper_scripts/build_node.sh
@@ -38,6 +38,6 @@ set -ex
 CONFIG=${CONFIG:-opt}
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 npm install --unsafe-perm --build-from-source
diff --git a/tools/run_tests/build_php.sh b/tools/run_tests/helper_scripts/build_php.sh
similarity index 98%
rename from tools/run_tests/build_php.sh
rename to tools/run_tests/helper_scripts/build_php.sh
index 77a8abcfe7..acaaa23adf 100755
--- a/tools/run_tests/build_php.sh
+++ b/tools/run_tests/helper_scripts/build_php.sh
@@ -33,7 +33,7 @@ set -ex
 CONFIG=${CONFIG:-opt}
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 root=`pwd`
 export GRPC_LIB_SUBDIR=libs/$CONFIG
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
similarity index 99%
rename from tools/run_tests/build_python.sh
rename to tools/run_tests/helper_scripts/build_python.sh
index 7cac394960..0e88e96765 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -31,7 +31,7 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 ##########################
 # Portability operations #
diff --git a/tools/run_tests/build_python_msys2.sh b/tools/run_tests/helper_scripts/build_python_msys2.sh
similarity index 100%
rename from tools/run_tests/build_python_msys2.sh
rename to tools/run_tests/helper_scripts/build_python_msys2.sh
diff --git a/tools/run_tests/build_ruby.sh b/tools/run_tests/helper_scripts/build_ruby.sh
similarity index 98%
rename from tools/run_tests/build_ruby.sh
rename to tools/run_tests/helper_scripts/build_ruby.sh
index 10343fce69..32638dede9 100755
--- a/tools/run_tests/build_ruby.sh
+++ b/tools/run_tests/helper_scripts/build_ruby.sh
@@ -34,7 +34,7 @@ set -ex
 export GRPC_CONFIG=${CONFIG:-opt}
 
 # change to grpc's ruby directory
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 rm -rf ./tmp
 rake compile
diff --git a/tools/run_tests/post_tests_c.sh b/tools/run_tests/helper_scripts/post_tests_c.sh
similarity index 97%
rename from tools/run_tests/post_tests_c.sh
rename to tools/run_tests/helper_scripts/post_tests_c.sh
index 4409526dab..a83a59e23b 100755
--- a/tools/run_tests/post_tests_c.sh
+++ b/tools/run_tests/helper_scripts/post_tests_c.sh
@@ -32,7 +32,7 @@ set -ex
 
 if [ "$CONFIG" != "gcov" ] ; then exit ; fi
 
-root=$(readlink -f $(dirname $0)/../..)
+root=$(readlink -f $(dirname $0)/../../..)
 out=$root/reports/c_cxx_coverage
 tmp1=$(mktemp)
 tmp2=$(mktemp)
diff --git a/tools/run_tests/post_tests_csharp.bat b/tools/run_tests/helper_scripts/post_tests_csharp.bat
similarity index 98%
rename from tools/run_tests/post_tests_csharp.bat
rename to tools/run_tests/helper_scripts/post_tests_csharp.bat
index 0d49a00b2a..2359f148ce 100644
--- a/tools/run_tests/post_tests_csharp.bat
+++ b/tools/run_tests/helper_scripts/post_tests_csharp.bat
@@ -36,7 +36,7 @@ if not "%CONFIG%" == "gcov" (
 )
 
 @rem enter src/csharp directory
-cd /d %~dp0\..\..\src\csharp
+cd /d %~dp0\..\..\..\src\csharp
 
 @rem Generate code coverage report
 @rem TODO(jtattermusch): currently the report list is hardcoded
diff --git a/tools/run_tests/post_tests_csharp.sh b/tools/run_tests/helper_scripts/post_tests_csharp.sh
similarity index 98%
rename from tools/run_tests/post_tests_csharp.sh
rename to tools/run_tests/helper_scripts/post_tests_csharp.sh
index bb6f5c6e18..762c1f8827 100755
--- a/tools/run_tests/post_tests_csharp.sh
+++ b/tools/run_tests/helper_scripts/post_tests_csharp.sh
@@ -33,7 +33,7 @@ set -ex
 if [ "$CONFIG" != "gcov" ] ; then exit ; fi
 
 # change to gRPC repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 # Generate the csharp extension coverage report
 gcov objs/gcov/src/csharp/ext/*.o
diff --git a/tools/run_tests/post_tests_php.sh b/tools/run_tests/helper_scripts/post_tests_php.sh
similarity index 97%
rename from tools/run_tests/post_tests_php.sh
rename to tools/run_tests/helper_scripts/post_tests_php.sh
index b4098066ea..23dc202322 100755
--- a/tools/run_tests/post_tests_php.sh
+++ b/tools/run_tests/helper_scripts/post_tests_php.sh
@@ -32,7 +32,7 @@ set -ex
 
 if [ "$CONFIG" != "gcov" ] ; then exit ; fi
 
-root=$(readlink -f $(dirname $0)/../..)
+root=$(readlink -f $(dirname $0)/../../..)
 out=$root/reports/php_ext_coverage
 tmp1=$(mktemp)
 tmp2=$(mktemp)
diff --git a/tools/run_tests/post_tests_ruby.sh b/tools/run_tests/helper_scripts/post_tests_ruby.sh
similarity index 97%
rename from tools/run_tests/post_tests_ruby.sh
rename to tools/run_tests/helper_scripts/post_tests_ruby.sh
index 0877e44805..300edfe8a3 100755
--- a/tools/run_tests/post_tests_ruby.sh
+++ b/tools/run_tests/helper_scripts/post_tests_ruby.sh
@@ -32,7 +32,7 @@ set -ex
 
 if [ "$CONFIG" != "gcov" ] ; then exit ; fi
 
-root=$(readlink -f $(dirname $0)/../..)
+root=$(readlink -f $(dirname $0)/../../..)
 out=$root/reports/ruby_ext_coverage
 tmp1=$(mktemp)
 tmp2=$(mktemp)
diff --git a/tools/run_tests/pre_build_c.bat b/tools/run_tests/helper_scripts/pre_build_c.bat
similarity index 98%
rename from tools/run_tests/pre_build_c.bat
rename to tools/run_tests/helper_scripts/pre_build_c.bat
index e4ab69384c..75b90f85b2 100644
--- a/tools/run_tests/pre_build_c.bat
+++ b/tools/run_tests/helper_scripts/pre_build_c.bat
@@ -32,7 +32,7 @@
 setlocal
 
 @rem enter repo root
-cd /d %~dp0\..\..
+cd /d %~dp0\..\..\..
 
 @rem Location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
diff --git a/tools/run_tests/pre_build_csharp.bat b/tools/run_tests/helper_scripts/pre_build_csharp.bat
similarity index 99%
rename from tools/run_tests/pre_build_csharp.bat
rename to tools/run_tests/helper_scripts/pre_build_csharp.bat
index f15979a96b..139955d4da 100644
--- a/tools/run_tests/pre_build_csharp.bat
+++ b/tools/run_tests/helper_scripts/pre_build_csharp.bat
@@ -32,7 +32,7 @@
 setlocal
 
 @rem enter repo root
-cd /d %~dp0\..\..
+cd /d %~dp0\..\..\..
 
 @rem Location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
diff --git a/tools/run_tests/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh
similarity index 98%
rename from tools/run_tests/pre_build_csharp.sh
rename to tools/run_tests/helper_scripts/pre_build_csharp.sh
index ee678ddce5..1f808556f4 100755
--- a/tools/run_tests/pre_build_csharp.sh
+++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh
@@ -31,7 +31,7 @@
 set -ex
 
 # cd to gRPC csharp directory
-cd $(dirname $0)/../../src/csharp
+cd $(dirname $0)/../../../src/csharp
 
 root=`pwd`
 
diff --git a/tools/run_tests/pre_build_node.bat b/tools/run_tests/helper_scripts/pre_build_node.bat
similarity index 100%
rename from tools/run_tests/pre_build_node.bat
rename to tools/run_tests/helper_scripts/pre_build_node.bat
diff --git a/tools/run_tests/pre_build_node.sh b/tools/run_tests/helper_scripts/pre_build_node.sh
similarity index 100%
rename from tools/run_tests/pre_build_node.sh
rename to tools/run_tests/helper_scripts/pre_build_node.sh
diff --git a/tools/run_tests/pre_build_ruby.sh b/tools/run_tests/helper_scripts/pre_build_ruby.sh
similarity index 98%
rename from tools/run_tests/pre_build_ruby.sh
rename to tools/run_tests/helper_scripts/pre_build_ruby.sh
index e7074c45c2..56b58df544 100755
--- a/tools/run_tests/pre_build_ruby.sh
+++ b/tools/run_tests/helper_scripts/pre_build_ruby.sh
@@ -34,6 +34,6 @@ set -ex
 export GRPC_CONFIG=${CONFIG:-opt}
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 bundle install
diff --git a/tools/run_tests/run_lcov.sh b/tools/run_tests/helper_scripts/run_lcov.sh
similarity index 97%
rename from tools/run_tests/run_lcov.sh
rename to tools/run_tests/helper_scripts/run_lcov.sh
index 796a0b5ceb..bc7b44cd3e 100755
--- a/tools/run_tests/run_lcov.sh
+++ b/tools/run_tests/helper_scripts/run_lcov.sh
@@ -32,7 +32,7 @@ set -ex
 
 out=$(readlink -f ${1:-coverage})
 
-root=$(readlink -f $(dirname $0)/../..)
+root=$(readlink -f $(dirname $0)/../../..)
 shift || true
 tmp=$(mktemp)
 cd $root
diff --git a/tools/run_tests/run_node.bat b/tools/run_tests/helper_scripts/run_node.bat
similarity index 100%
rename from tools/run_tests/run_node.bat
rename to tools/run_tests/helper_scripts/run_node.bat
diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/helper_scripts/run_node.sh
similarity index 98%
rename from tools/run_tests/run_node.sh
rename to tools/run_tests/helper_scripts/run_node.sh
index 44f75645f5..0fafe9481a 100755
--- a/tools/run_tests/run_node.sh
+++ b/tools/run_tests/helper_scripts/run_node.sh
@@ -37,7 +37,7 @@ set -ex
 CONFIG=${CONFIG:-opt}
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 root=`pwd`
 
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/helper_scripts/run_python.sh
similarity index 98%
rename from tools/run_tests/run_python.sh
rename to tools/run_tests/helper_scripts/run_python.sh
index 17e0186f2a..7be473428f 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/helper_scripts/run_python.sh
@@ -31,7 +31,7 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 PYTHON=`realpath -s "${1:-py27/bin/python}"`
 
diff --git a/tools/run_tests/run_ruby.sh b/tools/run_tests/helper_scripts/run_ruby.sh
similarity index 98%
rename from tools/run_tests/run_ruby.sh
rename to tools/run_tests/helper_scripts/run_ruby.sh
index 73a84ac361..ab153b7e25 100755
--- a/tools/run_tests/run_ruby.sh
+++ b/tools/run_tests/helper_scripts/run_ruby.sh
@@ -31,6 +31,6 @@
 set -ex
 
 # change to grpc repo root
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 
 rake
diff --git a/tools/run_tests/run_tests_in_workspace.sh b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh
similarity index 98%
rename from tools/run_tests/run_tests_in_workspace.sh
rename to tools/run_tests/helper_scripts/run_tests_in_workspace.sh
index 9c6c5b76e0..002c8d6de2 100755
--- a/tools/run_tests/run_tests_in_workspace.sh
+++ b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh
@@ -34,7 +34,7 @@
 # newly created workspace)
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)/../../..
 export repo_root=$(pwd)
 
 rm -rf "${WORKSPACE_NAME}"
diff --git a/tools/run_tests/interop_html_report.template b/tools/run_tests/interop/interop_html_report.template
similarity index 100%
rename from tools/run_tests/interop_html_report.template
rename to tools/run_tests/interop/interop_html_report.template
diff --git a/tools/run_tests/python_utils/__init__.py b/tools/run_tests/python_utils/__init__.py
new file mode 100644
index 0000000000..100a624dc9
--- /dev/null
+++ b/tools/run_tests/python_utils/__init__.py
@@ -0,0 +1,28 @@
+# Copyright 2016, 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.
diff --git a/tools/run_tests/antagonist.py b/tools/run_tests/python_utils/antagonist.py
similarity index 100%
rename from tools/run_tests/antagonist.py
rename to tools/run_tests/python_utils/antagonist.py
diff --git a/tools/run_tests/dockerjob.py b/tools/run_tests/python_utils/dockerjob.py
similarity index 99%
rename from tools/run_tests/dockerjob.py
rename to tools/run_tests/python_utils/dockerjob.py
index 4a7e61b3c4..0869c5cee9 100755
--- a/tools/run_tests/dockerjob.py
+++ b/tools/run_tests/python_utils/dockerjob.py
@@ -31,13 +31,14 @@
 
 from __future__ import print_function
 
-import jobset
 import tempfile
 import time
 import uuid
 import os
 import subprocess
 
+import jobset
+
 _DEVNULL = open(os.devnull, 'w')
 
 
diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/python_utils/filter_pull_request_tests.py
similarity index 100%
rename from tools/run_tests/filter_pull_request_tests.py
rename to tools/run_tests/python_utils/filter_pull_request_tests.py
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/python_utils/jobset.py
similarity index 100%
rename from tools/run_tests/jobset.py
rename to tools/run_tests/python_utils/jobset.py
diff --git a/tools/run_tests/port_server.py b/tools/run_tests/python_utils/port_server.py
similarity index 100%
rename from tools/run_tests/port_server.py
rename to tools/run_tests/python_utils/port_server.py
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/python_utils/report_utils.py
similarity index 100%
rename from tools/run_tests/report_utils.py
rename to tools/run_tests/python_utils/report_utils.py
diff --git a/tools/run_tests/watch_dirs.py b/tools/run_tests/python_utils/watch_dirs.py
similarity index 100%
rename from tools/run_tests/watch_dirs.py
rename to tools/run_tests/python_utils/watch_dirs.py
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 83cfc429f9..c14f18af81 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -34,20 +34,21 @@ from __future__ import print_function
 
 import argparse
 import atexit
-import dockerjob
 import itertools
-import jobset
 import json
 import multiprocessing
 import os
 import re
-import report_utils
 import subprocess
 import sys
 import tempfile
 import time
 import uuid
 
+import python_utils.dockerjob as dockerjob
+import python_utils.jobset as jobset
+import python_utils.report_utils as report_utils
+
 # Docker doesn't clean up after itself, so we do it on exit.
 atexit.register(lambda: subprocess.call(['stty', 'echo']))
 
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index 69ccff85cf..b7b742d7af 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -35,21 +35,21 @@ from __future__ import print_function
 import argparse
 import collections
 import itertools
-import jobset
 import json
 import multiprocessing
 import os
-import performance.scenario_config as scenario_config
 import pipes
 import re
-import report_utils
 import subprocess
 import sys
 import tempfile
 import time
 import traceback
 import uuid
-import report_utils
+
+import performance.scenario_config as scenario_config
+import python_utils.jobset as jobset
+import python_utils.report_utils as report_utils
 
 
 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
diff --git a/tools/run_tests/run_stress_tests.py b/tools/run_tests/run_stress_tests.py
index de4a22877c..a94a615b88 100755
--- a/tools/run_tests/run_stress_tests.py
+++ b/tools/run_tests/run_stress_tests.py
@@ -33,9 +33,7 @@ from __future__ import print_function
 
 import argparse
 import atexit
-import dockerjob
 import itertools
-import jobset
 import json
 import multiprocessing
 import os
@@ -46,6 +44,9 @@ import tempfile
 import time
 import uuid
 
+import python_utils.dockerjob as dockerjob
+import python_utils.jobset as jobset
+
 # Docker doesn't clean up after itself, so we do it on exit.
 atexit.register(lambda: subprocess.call(['stty', 'echo']))
 
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index fe56f4a175..1008c6b6cf 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -54,9 +54,9 @@ import time
 from six.moves import urllib
 import uuid
 
-import jobset
-import report_utils
-import watch_dirs
+import python_utils.jobset as jobset
+import python_utils.report_utils as report_utils
+import python_utils.watch_dirs as watch_dirs
 
 
 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
@@ -116,7 +116,7 @@ class Config(object):
 def get_c_tests(travis, test_lang) :
   out = []
   platforms_str = 'ci_platforms' if travis else 'platforms'
-  with open('tools/run_tests/tests.json') as f:
+  with open('tools/run_tests/generated/tests.json') as f:
     js = json.load(f)
     return [tgt
             for tgt in js
@@ -300,7 +300,7 @@ class CLanguage(object):
 
   def pre_build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\pre_build_c.bat']]
+      return [['tools\\run_tests\\helper_scripts\\pre_build_c.bat']]
     else:
       return []
 
@@ -311,7 +311,7 @@ class CLanguage(object):
     if self.platform == 'windows':
       return []
     else:
-      return [['tools/run_tests/post_tests_c.sh']]
+      return [['tools/run_tests/helper_scripts/post_tests_c.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -382,16 +382,16 @@ class NodeLanguage(object):
 
   def test_specs(self):
     if self.platform == 'windows':
-      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'])]
+      return [self.config.job_spec(['tools\\run_tests\\helper_scripts\\run_node.bat'])]
     else:
-      return [self.config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
+      return [self.config.job_spec(['tools/run_tests/helper_scripts/run_node.sh', self.node_version],
                                    environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\pre_build_node.bat']]
+      return [['tools\\run_tests\\helper_scripts\\pre_build_node.bat']]
     else:
-      return [['tools/run_tests/pre_build_node.sh', self.node_version]]
+      return [['tools/run_tests/helper_scripts/pre_build_node.sh', self.node_version]]
 
   def make_targets(self):
     return []
@@ -401,9 +401,9 @@ class NodeLanguage(object):
 
   def build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\build_node.bat']]
+      return [['tools\\run_tests\\helper_scripts\\build_node.bat']]
     else:
-      return [['tools/run_tests/build_node.sh', self.node_version]]
+      return [['tools/run_tests/helper_scripts/build_node.sh', self.node_version]]
 
   def post_tests_steps(self):
     return []
@@ -439,10 +439,10 @@ class PhpLanguage(object):
     return []
 
   def build_steps(self):
-    return [['tools/run_tests/build_php.sh']]
+    return [['tools/run_tests/helper_scripts/build_php.sh']]
 
   def post_tests_steps(self):
-    return [['tools/run_tests/post_tests_php.sh']]
+    return [['tools/run_tests/helper_scripts/post_tests_php.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -475,10 +475,10 @@ class Php7Language(object):
     return []
 
   def build_steps(self):
-    return [['tools/run_tests/build_php.sh']]
+    return [['tools/run_tests/helper_scripts/build_php.sh']]
 
   def post_tests_steps(self):
-    return [['tools/run_tests/post_tests_php.sh']]
+    return [['tools/run_tests/helper_scripts/post_tests_php.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -547,18 +547,18 @@ class PythonLanguage(object):
 
     if os.name == 'nt':
       shell = ['bash']
-      builder = [os.path.abspath('tools/run_tests/build_python_msys2.sh')]
+      builder = [os.path.abspath('tools/run_tests/helper_scripts/build_python_msys2.sh')]
       builder_prefix_arguments = ['MINGW{}'.format(bits)]
       venv_relative_python = ['Scripts/python.exe']
       toolchain = ['mingw32']
     else:
       shell = []
-      builder = [os.path.abspath('tools/run_tests/build_python.sh')]
+      builder = [os.path.abspath('tools/run_tests/helper_scripts/build_python.sh')]
       builder_prefix_arguments = []
       venv_relative_python = ['bin/python']
       toolchain = ['unix']
 
-    runner = [os.path.abspath('tools/run_tests/run_python.sh')]
+    runner = [os.path.abspath('tools/run_tests/helper_scripts/run_python.sh')]
     config_vars = _PythonConfigVars(shell, builder, builder_prefix_arguments,
                               venv_relative_python, toolchain, runner)
     python27_config = _python_config_generator(name='py27', major='2',
@@ -610,12 +610,12 @@ class RubyLanguage(object):
     _check_compiler(self.args.compiler, ['default'])
 
   def test_specs(self):
-    return [self.config.job_spec(['tools/run_tests/run_ruby.sh'],
+    return [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'],
                                  timeout_seconds=10*60,
                                  environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
-    return [['tools/run_tests/pre_build_ruby.sh']]
+    return [['tools/run_tests/helper_scripts/pre_build_ruby.sh']]
 
   def make_targets(self):
     return []
@@ -624,10 +624,10 @@ class RubyLanguage(object):
     return []
 
   def build_steps(self):
-    return [['tools/run_tests/build_ruby.sh']]
+    return [['tools/run_tests/helper_scripts/build_ruby.sh']]
 
   def post_tests_steps(self):
-    return [['tools/run_tests/post_tests_ruby.sh']]
+    return [['tools/run_tests/helper_scripts/post_tests_ruby.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -725,9 +725,9 @@ class CSharpLanguage(object):
 
   def pre_build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\pre_build_csharp.bat']]
+      return [['tools\\run_tests\\helper_scripts\\pre_build_csharp.bat']]
     else:
-      return [['tools/run_tests/pre_build_csharp.sh']]
+      return [['tools/run_tests/helper_scripts/pre_build_csharp.sh']]
 
   def make_targets(self):
     return ['grpc_csharp_ext']
@@ -738,22 +738,22 @@ class CSharpLanguage(object):
   def build_steps(self):
     if self.args.compiler == 'coreclr':
       if self.platform == 'windows':
-        return [['tools\\run_tests\\build_csharp_coreclr.bat']]
+        return [['tools\\run_tests\\helper_scripts\\build_csharp_coreclr.bat']]
       else:
-        return [['tools/run_tests/build_csharp_coreclr.sh']]
+        return [['tools/run_tests/helper_scripts/build_csharp_coreclr.sh']]
     else:
       if self.platform == 'windows':
         return [[_windows_build_bat(self.args.compiler),
                  'src/csharp/Grpc.sln',
                  '/p:Configuration=%s' % _MSBUILD_CONFIG[self.config.build_config]]]
       else:
-        return [['tools/run_tests/build_csharp.sh']]
+        return [['tools/run_tests/helper_scripts/build_csharp.sh']]
 
   def post_tests_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\post_tests_csharp.bat']]
+      return [['tools\\run_tests\\helper_scripts\\post_tests_csharp.bat']]
     else:
-      return [['tools/run_tests/post_tests_csharp.sh']]
+      return [['tools/run_tests/helper_scripts/post_tests_csharp.sh']]
 
   def makefile_name(self):
     return 'Makefile'
@@ -872,9 +872,9 @@ class NodeExpressLanguage(object):
 
   def pre_build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\pre_build_node.bat']]
+      return [['tools\\run_tests\\helper_scripts\\pre_build_node.bat']]
     else:
-      return [['tools/run_tests/pre_build_node.sh', self.node_version]]
+      return [['tools/run_tests/helper_scripts/pre_build_node.sh', self.node_version]]
 
   def make_targets(self):
     return []
@@ -898,7 +898,7 @@ class NodeExpressLanguage(object):
     return 'node_express'
 
 # different configurations we can run under
-with open('tools/run_tests/configs.json') as f:
+with open('tools/run_tests/generated/configs.json') as f:
   _CONFIGS = dict((cfg['config'], Config(**cfg)) for cfg in ast.literal_eval(f.read()))
 
 
@@ -1299,7 +1299,7 @@ def _start_port_server(port_server_port):
     running = False
   if running:
     current_version = int(subprocess.check_output(
-        [sys.executable, os.path.abspath('tools/run_tests/port_server.py'),
+        [sys.executable, os.path.abspath('tools/run_tests/python_utils/port_server.py'),
          'dump_version']))
     print('my port server is version %d' % current_version)
     running = (version >= current_version)
@@ -1311,7 +1311,7 @@ def _start_port_server(port_server_port):
     fd, logfile = tempfile.mkstemp()
     os.close(fd)
     print('starting port_server, with log file %s' % logfile)
-    args = [sys.executable, os.path.abspath('tools/run_tests/port_server.py'),
+    args = [sys.executable, os.path.abspath('tools/run_tests/python_utils/port_server.py'),
             '-p', '%d' % port_server_port, '-l', logfile]
     env = dict(os.environ)
     env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
@@ -1417,7 +1417,7 @@ def _build_and_run(
     return []
 
   # start antagonists
-  antagonists = [subprocess.Popen(['tools/run_tests/antagonist.py'])
+  antagonists = [subprocess.Popen(['tools/run_tests/python_utils/antagonist.py'])
                  for _ in range(0, args.antagonists)]
   port_server_port = 32766
   _start_port_server(port_server_port)
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index df48099971..6e83180c66 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -31,12 +31,13 @@
 """Run test matrix."""
 
 import argparse
-import jobset
 import multiprocessing
 import os
-import report_utils
 import sys
-from filter_pull_request_tests import filter_tests
+
+import python_utils.jobset as jobset
+import python_utils.report_utils as report_utils
+from python_utils.filter_pull_request_tests import filter_tests
 
 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
 os.chdir(_ROOT)
@@ -69,7 +70,7 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_
     workspace_name = 'workspace_%s' % name
   env = {'WORKSPACE_NAME': workspace_name}
   test_job = jobset.JobSpec(
-          cmdline=['tools/run_tests/run_tests_in_workspace.sh',
+          cmdline=['tools/run_tests/helper_scripts/run_tests_in_workspace.sh',
                    '-t',
                    '-j', str(inner_jobs),
                    '-x', '../report_%s.xml' % name,
diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
index b733ba173f..a86db02b80 100755
--- a/tools/run_tests/sanity/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -34,7 +34,7 @@ import re
 import sys
 
 root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
-with open(os.path.join(root, 'tools', 'run_tests', 'sources_and_headers.json')) as f:
+with open(os.path.join(root, 'tools', 'run_tests', 'generated', 'sources_and_headers.json')) as f:
   js = json.loads(f.read())
 
 re_inc1 = re.compile(r'^#\s*include\s*"([^"]*)"')
diff --git a/tools/run_tests/sanity/check_test_filtering.py b/tools/run_tests/sanity/check_test_filtering.py
index b522cdeb49..290a6e2ddf 100755
--- a/tools/run_tests/sanity/check_test_filtering.py
+++ b/tools/run_tests/sanity/check_test_filtering.py
@@ -38,7 +38,7 @@ import re
 # hack import paths to pick up extra code
 sys.path.insert(0, os.path.abspath('tools/run_tests/'))
 from run_tests_matrix import _create_test_jobs, _create_portability_test_jobs
-import filter_pull_request_tests
+import python_utils.filter_pull_request_tests as filter_pull_request_tests
 
 _LIST_OF_LANGUAGE_LABELS = ['c', 'c++', 'csharp', 'node', 'objc', 'php', 'php7', 'python', 'ruby']
 _LIST_OF_PLATFORM_LABELS = ['linux', 'macos', 'windows']
diff --git a/tools/run_tests/task_runner.py b/tools/run_tests/task_runner.py
index 2e3fa443b9..fdc4668222 100755
--- a/tools/run_tests/task_runner.py
+++ b/tools/run_tests/task_runner.py
@@ -33,14 +33,13 @@
 from __future__ import print_function
 
 import argparse
-import atexit
-import jobset
 import multiprocessing
 import sys
 
-import artifact_targets
-import distribtest_targets
-import package_targets
+import artifacts.artifact_targets as artifact_targets
+import artifacts.distribtest_targets as distribtest_targets
+import artifacts.package_targets as package_targets
+import python_utils.jobset as jobset
 
 _TARGETS = []
 _TARGETS += artifact_targets.targets()
-- 
GitLab


From 7dd2cc6f68714228cf8b4c60220f4532b3061d82 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 20 Dec 2016 17:15:39 +0100
Subject: [PATCH 195/344] cleanup and speedup of sanity tests

---
 .../tools/dockerfile/clang_format.include     |  5 +++
 .../grpc_clang_format/Dockerfile.template     | 37 +++++++++++++++++++
 .../test/sanity/Dockerfile.template           | 12 ++----
 tools/distrib/check_nanopb_output.sh          |  4 +-
 tools/distrib/clang_format_code.sh            | 14 +++++--
 tools/dockerfile/grpc_clang_format/Dockerfile | 10 ++---
 .../clang_format_all_the_things.sh            |  4 +-
 tools/dockerfile/test/sanity/Dockerfile       | 24 ++++++++----
 .../dockerize/build_docker_and_run_tests.sh   |  2 -
 tools/run_tests/run_tests.py                  |  6 ++-
 10 files changed, 86 insertions(+), 32 deletions(-)
 create mode 100644 templates/tools/dockerfile/clang_format.include
 create mode 100644 templates/tools/dockerfile/grpc_clang_format/Dockerfile.template

diff --git a/templates/tools/dockerfile/clang_format.include b/templates/tools/dockerfile/clang_format.include
new file mode 100644
index 0000000000..9a2b60ba8c
--- /dev/null
+++ b/templates/tools/dockerfile/clang_format.include
@@ -0,0 +1,5 @@
+RUN apt-get update && apt-get -y install wget
+RUN echo deb http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
+RUN echo deb-src http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
+RUN wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key| apt-key add -
+RUN apt-get update && apt-get -y install clang-format-3.8
diff --git a/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template b/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template
new file mode 100644
index 0000000000..8360fc121c
--- /dev/null
+++ b/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template
@@ -0,0 +1,37 @@
+%YAML 1.2
+--- |
+  # 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.
+  
+  FROM ubuntu:15.10
+  
+  <%include file="../clang_format.include"/>
+  ADD clang_format_all_the_things.sh /
+  CMD ["echo 'Run with tools/distrib/clang_format_code.sh'"]
+  
diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template
index 0168353933..8617666b21 100644
--- a/templates/tools/dockerfile/test/sanity/Dockerfile.template
+++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template
@@ -52,18 +52,12 @@
   # ./compile.sh without a local protoc dependency
   # TODO(mattkwong): install dependencies to support latest Bazel version if newer
   # version is needed
-  RUN git clone https://github.com/bazelbuild/bazel.git /bazel && \
+  RUN git clone https://github.com/bazelbuild/bazel.git /bazel && ${"\\"}
     cd /bazel && git checkout tags/0.4.1 && ./compile.sh
   RUN ln -s /bazel/output/bazel /bin/
   
-  #===================
-  # Docker "inception"
-  # Note this is quite the ugly hack.
-  # This makes sure that the docker binary we inject has its dependencies.
-  RUN curl https://get.docker.com/ | sh
-  RUN apt-get remove --purge -y docker-engine
-  
-  RUN mkdir /var/local/jenkins
+  <%include file="../../clang_format.include"/>
+  <%include file="../../run_tests_addons.include"/>
   
   # Define the default command.
   CMD ["bash"]
diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh
index c0707051a6..eb64e23daf 100755
--- a/tools/distrib/check_nanopb_output.sh
+++ b/tools/distrib/check_nanopb_output.sh
@@ -37,7 +37,7 @@ readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)"
 pushd third_party/protobuf
 ./autogen.sh
 ./configure --prefix="$PROTOBUF_INSTALL_PREFIX"
-make
+make -j 8
 make install
 #ldconfig
 popd
@@ -51,7 +51,7 @@ fi
 # stack up and change to nanopb's proto generator directory
 pushd third_party/nanopb/generator/proto
 export PATH="$PROTOC_BIN_PATH:$PATH"
-make
+make -j 8
 # back to the root directory
 popd
 
diff --git a/tools/distrib/clang_format_code.sh b/tools/distrib/clang_format_code.sh
index 858e074898..13e018709f 100755
--- a/tools/distrib/clang_format_code.sh
+++ b/tools/distrib/clang_format_code.sh
@@ -32,9 +32,15 @@ set -ex
 
 # change to root directory
 cd $(dirname $0)/../..
+REPO_ROOT=$(pwd)
 
-# build clang-format docker image
-docker build -t grpc_clang_format tools/dockerfile/grpc_clang_format
+if [ "$CLANG_FORMAT_SKIP_DOCKER" == "" ]
+then
+  # build clang-format docker image
+  docker build -t grpc_clang_format tools/dockerfile/grpc_clang_format
 
-# run clang-format against the checked out codebase
-docker run -e TEST=$TEST -e CHANGED_FILES="$CHANGED_FILES" --rm=true -v ${HOST_GIT_ROOT:-`pwd`}:/local-code -t grpc_clang_format /clang_format_all_the_things.sh
+  # run clang-format against the checked out codebase
+  docker run -e TEST=$TEST -e CHANGED_FILES="$CHANGED_FILES" -e CLANG_FORMAT_ROOT="/local-code" --rm=true -v "${REPO_ROOT}":/local-code -t grpc_clang_format /clang_format_all_the_things.sh
+else
+  CLANG_FORMAT_ROOT="${REPO_ROOT}" tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
+fi
diff --git a/tools/dockerfile/grpc_clang_format/Dockerfile b/tools/dockerfile/grpc_clang_format/Dockerfile
index ab58017a02..85f5e4db74 100644
--- a/tools/dockerfile/grpc_clang_format/Dockerfile
+++ b/tools/dockerfile/grpc_clang_format/Dockerfile
@@ -27,13 +27,13 @@
 # (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 ubuntu:wily
-RUN apt-get update
-RUN apt-get -y install wget
+FROM ubuntu:15.10
+
+RUN apt-get update && apt-get -y install wget
 RUN echo deb http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
 RUN echo deb-src http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
 RUN wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key| apt-key add -
-RUN apt-get update
-RUN apt-get -y install clang-format-3.8
+RUN apt-get update && apt-get -y install clang-format-3.8
+
 ADD clang_format_all_the_things.sh /
 CMD ["echo 'Run with tools/distrib/clang_format_code.sh'"]
diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
index 462c65ab5e..c6e4aabfe6 100755
--- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
+++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
@@ -44,7 +44,7 @@ for dir in $DIRS
 do
   for glob in $GLOB
   do
-    files="$files `find /local-code/$dir -name $glob -and -not -name *.generated.* -and -not -name *.pb.h -and -not -name *.pb.c -and -not -name *.pb.cc`"
+    files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name *.generated.* -and -not -name *.pb.h -and -not -name *.pb.c -and -not -name *.pb.cc`"
   done
 done
 
@@ -54,7 +54,7 @@ if [ -n "$CHANGED_FILES" ]; then
   files=$(comm -12 <(echo $files | tr ' ' '\n' | sort -u) <(echo $CHANGED_FILES | tr ' ' '\n' | sort -u))
 fi
 
-if [ "x$TEST" = "x" ]
+if [ "$TEST" == "" ]
 then
   echo $files | xargs $CLANG_FORMAT -i
 else
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index 6b19ac845b..811384fda1 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -97,17 +97,27 @@ RUN apt-get install -y openjdk-8-jdk
 # ./compile.sh without a local protoc dependency
 # TODO(mattkwong): install dependencies to support latest Bazel version if newer
 # version is needed
-RUN git clone https://github.com/bazelbuild/bazel.git /bazel &&   cd /bazel && git checkout tags/0.4.1 && ./compile.sh
+RUN git clone https://github.com/bazelbuild/bazel.git /bazel && \
+  cd /bazel && git checkout tags/0.4.1 && ./compile.sh
 RUN ln -s /bazel/output/bazel /bin/
 
-#===================
-# Docker "inception"
-# Note this is quite the ugly hack.
-# This makes sure that the docker binary we inject has its dependencies.
-RUN curl https://get.docker.com/ | sh
-RUN apt-get remove --purge -y docker-engine
+RUN apt-get update && apt-get -y install wget
+RUN echo deb http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
+RUN echo deb-src http://llvm.org/apt/wily/ llvm-toolchain-wily-3.8 main >> /etc/apt/sources.list
+RUN wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key| apt-key add -
+RUN apt-get update && apt-get -y install clang-format-3.8
+
+# Prepare ccache
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
 
 RUN mkdir /var/local/jenkins
 
+
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
index c3219c533d..b68ac89121 100755
--- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh
+++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
@@ -77,8 +77,6 @@ docker run \
   -v /tmp/ccache:/tmp/ccache \
   -v /tmp/npm-cache:/tmp/npm-cache \
   -v /tmp/xdg-cache-home:/tmp/xdg-cache-home \
-  -v /var/run/docker.sock:/var/run/docker.sock \
-  -v $(which docker):/bin/docker \
   -w /var/local/git/grpc \
   --name=$CONTAINER_NAME \
   $DOCKER_IMAGE_NAME \
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 1008c6b6cf..924274191e 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -820,8 +820,12 @@ class Sanity(object):
   def test_specs(self):
     import yaml
     with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
+      environ={'TEST': 'true'}
+      if _is_use_docker_child():
+        environ['CLANG_FORMAT_SKIP_DOCKER'] = 'true'
       return [self.config.job_spec(cmd['script'].split(),
-                                   timeout_seconds=30*60, environ={'TEST': 'true'},
+                                   timeout_seconds=30*60,
+                                   environ=environ,
                                    cpu_cost=cmd.get('cpu_cost', 1))
               for cmd in yaml.load(f)]
 
-- 
GitLab


From 346f9e46eb0ba9b13ec8ca2d018a2eab2cfc58b0 Mon Sep 17 00:00:00 2001
From: Matt Kwong <mattkwong@google.com>
Date: Wed, 21 Dec 2016 16:18:57 -0800
Subject: [PATCH 196/344] Fix Python artifact build

---
 .../grpc_artifact_python_manylinux_x64/Dockerfile   | 13 +++++++++++++
 .../grpc_artifact_python_manylinux_x86/Dockerfile   | 13 +++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
index 1d4e8e1a4a..69e624aa41 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
@@ -34,6 +34,19 @@ FROM quay.io/pypa/manylinux1_x86_64
 # Update the package manager
 RUN yum update -y
 
+#############################################################
+# Update Git to allow cloning submodules with --reference arg
+RUN yum remove -y git
+RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc
+RUN cd /usr/src && \
+  wget https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
+  tar xzf git-2.0.5.tar.gz
+RUN cd /usr/src/git-2.0.5 && \
+  make prefix=/usr/local/git all && \
+  make prefix=/usr/local/git install
+ENV PATH /usr/local/git/bin:$PATH
+RUN source /etc/bashrc
+
 ###################################
 # Install Python build requirements
 RUN /opt/python/cp27-cp27m/bin/pip install cython
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
index 810499695e..9af80078ed 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
@@ -34,6 +34,19 @@ FROM quay.io/pypa/manylinux1_i686
 # Update the package manager
 RUN yum update -y
 
+#############################################################
+# Update Git to allow cloning submodules with --reference arg
+RUN yum remove -y git
+RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc
+RUN cd /usr/src && \
+  wget https://kernel.org/pub/software/scm/git/git-2.0.5.tar.gz && \
+  tar xzf git-2.0.5.tar.gz
+RUN cd /usr/src/git-2.0.5 && \
+  make prefix=/usr/local/git all && \
+  make prefix=/usr/local/git install
+ENV PATH /usr/local/git/bin:$PATH
+RUN source /etc/bashrc
+
 ###################################
 # Install Python build requirements
 RUN /opt/python/cp27-cp27m/bin/pip install cython
-- 
GitLab


From c830eb5b6b1581ccd3c6c9d80cb48cddc22bb26b Mon Sep 17 00:00:00 2001
From: Matt Kwong <mattkwong@google.com>
Date: Thu, 22 Dec 2016 12:10:25 -0800
Subject: [PATCH 197/344] Update interop html template location

---
 tools/run_tests/python_utils/report_utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/run_tests/python_utils/report_utils.py b/tools/run_tests/python_utils/report_utils.py
index 5ce2a87cfa..352cf7abe7 100644
--- a/tools/run_tests/python_utils/report_utils.py
+++ b/tools/run_tests/python_utils/report_utils.py
@@ -84,7 +84,7 @@ def render_interop_html_report(
   client_langs, server_langs, test_cases, auth_test_cases, http2_cases,
   resultset, num_failures, cloud_to_prod, prod_servers, http2_interop):
   """Generate HTML report for interop tests."""
-  template_file = 'tools/run_tests/interop_html_report.template'
+  template_file = 'tools/run_tests/interop/interop_html_report.template'
   try:
     mytemplate = Template(filename=template_file, format_exceptions=True)
   except NameError:
-- 
GitLab


From 4cc1c35ad34b136bcfc68e6815b1dcd8a2910bbb Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 27 Dec 2016 08:48:01 -0800
Subject: [PATCH 198/344] Fix merge errors

---
 .../client_channel/client_channel_factory.c   |  6 +-
 .../ext/client_channel/subchannel_index.c     |  2 +-
 .../ext/resolver/dns/native/dns_resolver.c    |  8 +-
 .../chttp2/client/insecure/channel_create.c   |  4 +-
 .../client/secure/secure_channel_create.c     | 14 ++--
 src/core/lib/surface/channel.c                | 78 +++++++++++--------
 .../dns_resolver_connectivity_test.c          |  2 +-
 7 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/src/core/ext/client_channel/client_channel_factory.c b/src/core/ext/client_channel/client_channel_factory.c
index 4eb35dfcf7..d2707a1556 100644
--- a/src/core/ext/client_channel/client_channel_factory.c
+++ b/src/core/ext/client_channel/client_channel_factory.c
@@ -61,12 +61,10 @@ static void* factory_arg_copy(void* factory) {
   return factory;
 }
 
-static void factory_arg_destroy(void* factory) {
+static void factory_arg_destroy(grpc_exec_ctx* exec_ctx, void* factory) {
   // TODO(roth): Remove local exec_ctx when
   // https://github.com/grpc/grpc/pull/8705 is merged.
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_client_channel_factory_unref(&exec_ctx, factory);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_client_channel_factory_unref(exec_ctx, factory);
 }
 
 static int factory_arg_cmp(void* factory1, void* factory2) {
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
index a1ba5e945c..1ebe03ef11 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/client_channel/subchannel_index.c
@@ -128,7 +128,7 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
                                  grpc_subchannel_key *k) {
   grpc_connector_unref(exec_ctx, k->connector);
   gpr_free((grpc_channel_args *)k->args.filters);
-  grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
+  grpc_channel_args_destroy(exec_ctx, (grpc_channel_args *)k->args.args);
   gpr_free(k->args.addr);
   gpr_free(k);
 }
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 2675fa931f..37a2d8dc30 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -182,7 +182,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
     grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
     result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
     grpc_resolved_addresses_destroy(r->addresses);
-    grpc_lb_addresses_destroy(addresses);
+    grpc_lb_addresses_destroy(exec_ctx, addresses);
   } else {
     gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
     gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
@@ -203,7 +203,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
                     now);
   }
   if (r->resolved_result != NULL) {
-    grpc_channel_args_destroy(r->resolved_result);
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
   }
   r->resolved_result = result;
   r->resolved_version++;
@@ -241,12 +241,12 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   dns_resolver *r = (dns_resolver *)gr;
   gpr_mu_destroy(&r->mu);
   if (r->resolved_result != NULL) {
-    grpc_channel_args_destroy(r->resolved_result);
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
   }
   grpc_pollset_set_destroy(r->interested_parties);
   gpr_free(r->name_to_resolve);
   gpr_free(r->default_port);
-  grpc_channel_args_destroy(r->channel_args);
+  grpc_channel_args_destroy(exec_ctx, r->channel_args);
   gpr_free(r);
 }
 
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index a0d0652ce7..1d3592ef06 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -72,7 +72,7 @@ static grpc_channel *client_channel_factory_create_channel(
   grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
   grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
                                               GRPC_CLIENT_CHANNEL, NULL);
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(exec_ctx, new_args);
   return channel;
 }
 
@@ -105,7 +105,7 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
   grpc_channel *channel = client_channel_factory_create_channel(
       &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
   // Clean up.
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(&exec_ctx, new_args);
   grpc_client_channel_factory_unref(&exec_ctx, factory);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel != NULL ? channel : grpc_lame_client_channel_create(
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index f35439cd44..54663ef6a4 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -62,7 +62,7 @@ static void client_channel_factory_unref(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
   client_channel_factory *f = (client_channel_factory *)cc_factory;
   if (gpr_unref(&f->refs)) {
-    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &f->security_connector->base,
                                   "client_channel_factory");
     gpr_free(f);
   }
@@ -97,7 +97,7 @@ static grpc_channel *client_channel_factory_create_channel(
   grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
   grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
                                               GRPC_CLIENT_CHANNEL, NULL);
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(exec_ctx, new_args);
   return channel;
 }
 
@@ -132,8 +132,8 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
   grpc_channel_security_connector *security_connector;
   grpc_channel_args *new_args_from_connector;
   if (grpc_channel_credentials_create_security_connector(
-          creds, target, args, &security_connector, &new_args_from_connector) !=
-      GRPC_SECURITY_OK) {
+          &exec_ctx, creds, target, args, &security_connector,
+          &new_args_from_connector) != GRPC_SECURITY_OK) {
     grpc_exec_ctx_finish(&exec_ctx);
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
@@ -155,15 +155,15 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
       new_args_from_connector != NULL ? new_args_from_connector : args,
       new_args, GPR_ARRAY_SIZE(new_args));
   if (new_args_from_connector != NULL) {
-    grpc_channel_args_destroy(new_args_from_connector);
+    grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
   }
   // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
       &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
   // Clean up.
-  GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+  GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &f->security_connector->base,
                                 "secure_client_channel_factory_create_channel");
-  grpc_channel_args_destroy(args_copy);
+  grpc_channel_args_destroy(&exec_ctx, args_copy);
   grpc_client_channel_factory_unref(&exec_ctx, &f->base);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel; /* may be NULL */
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 9405015c50..b87295786e 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -87,11 +87,12 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport *optional_transport) {
   grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
-  grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
+  grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+                                                   input_args);
   grpc_channel_stack_builder_set_target(builder, target);
   grpc_channel_stack_builder_set_transport(builder, optional_transport);
   if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
-    grpc_channel_stack_builder_destroy(builder);
+    grpc_channel_stack_builder_destroy(exec_ctx, builder);
     return NULL;
   }
   grpc_channel_args *args = grpc_channel_args_copy(
@@ -124,10 +125,10 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
       } else {
         if (channel->default_authority) {
           /* setting this takes precedence over anything else */
-          GRPC_MDELEM_UNREF(channel->default_authority);
+          GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
         }
-        channel->default_authority =
-            grpc_mdelem_from_strings(":authority", args->args[i].value.string);
+        channel->default_authority = grpc_mdelem_from_strings(
+            exec_ctx, ":authority", args->args[i].value.string);
       }
     } else if (0 ==
                strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -142,7 +143,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                   GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
         } else {
           channel->default_authority = grpc_mdelem_from_strings(
-              ":authority", args->args[i].value.string);
+              exec_ctx, ":authority", args->args[i].value.string);
         }
       }
     } else if (0 == strcmp(args->args[i].key,
@@ -169,7 +170,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
   }
 
 done:
-  grpc_channel_args_destroy(args);
+  grpc_channel_args_destroy(exec_ctx, args);
   return channel;
 }
 
@@ -188,10 +189,10 @@ void grpc_channel_get_info(grpc_channel *channel,
 }
 
 static grpc_call *grpc_channel_create_call_internal(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
-    grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
-    gpr_timespec deadline) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_completion_queue *cq,
+    grpc_pollset_set *pollset_set_alternative, grpc_mdelem *path_mdelem,
+    grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
   grpc_mdelem *send_metadata[2];
   size_t num_metadata = 0;
 
@@ -218,7 +219,7 @@ static grpc_call *grpc_channel_create_call_internal(
   args.send_deadline = deadline;
 
   grpc_call *call;
-  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call));
+  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(exec_ctx, &args, &call));
   return call;
 }
 
@@ -239,26 +240,30 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
       (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
        deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq, NULL,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
+      grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 grpc_call *grpc_channel_create_pollset_set_call(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_pollset_set *pollset_set, const char *method, const char *host,
-    gpr_timespec deadline, void *reserved) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_pollset_set *pollset_set,
+    const char *method, const char *host, gpr_timespec deadline,
+    void *reserved) {
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, NULL, pollset_set,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+      exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
+      grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
@@ -271,15 +276,18 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
       "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
       4, (channel, method, host, reserved));
   GPR_ASSERT(!reserved);
-  rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  rc->path = grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                                grpc_mdstr_from_string(method));
-  rc->authority = host ? grpc_mdelem_from_metadata_strings(
-                             GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host))
-                       : NULL;
+  rc->authority =
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
+                                               grpc_mdstr_from_string(host))
+           : NULL;
   gpr_mu_lock(&channel->registered_call_mu);
   rc->next = channel->registered_calls;
   channel->registered_calls = rc;
   gpr_mu_unlock(&channel->registered_call_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   return rc;
 }
 
@@ -299,10 +307,13 @@ grpc_call *grpc_channel_create_registered_call(
           registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
           (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, completion_queue, NULL,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, completion_queue, NULL,
       GRPC_MDELEM_REF(rc->path),
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -328,14 +339,14 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg,
   while (channel->registered_calls) {
     registered_call *rc = channel->registered_calls;
     channel->registered_calls = rc->next;
-    GRPC_MDELEM_UNREF(rc->path);
+    GRPC_MDELEM_UNREF(exec_ctx, rc->path);
     if (rc->authority) {
-      GRPC_MDELEM_UNREF(rc->authority);
+      GRPC_MDELEM_UNREF(exec_ctx, rc->authority);
     }
     gpr_free(rc);
   }
   if (channel->default_authority != NULL) {
-    GRPC_MDELEM_UNREF(channel->default_authority);
+    GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
   }
   gpr_mu_destroy(&channel->registered_call_mu);
   gpr_free(channel->target);
@@ -365,7 +376,8 @@ grpc_compression_options grpc_channel_compression_options(
   return channel->compression_options;
 }
 
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
+grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+                                                 grpc_channel *channel, int i) {
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   switch (i) {
     case 0:
@@ -376,6 +388,6 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
       return GRPC_MDELEM_GRPC_STATUS_2;
   }
   gpr_ltoa(i, tmp);
-  return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS,
+  return grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
                                            grpc_mdstr_from_string(tmp));
 }
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index b421720492..66e55fb01d 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -122,7 +122,7 @@ int main(int argc, char **argv) {
   GPR_ASSERT(wait_loop(30, &ev2));
   GPR_ASSERT(result != NULL);
 
-  grpc_channel_args_destroy(result);
+  grpc_channel_args_destroy(&exec_ctx, result);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test");
   grpc_exec_ctx_finish(&exec_ctx);
 
-- 
GitLab


From 702f93d3645055bd77181935c18f41a9de272c1e Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 27 Dec 2016 08:52:01 -0800
Subject: [PATCH 199/344] Fix merge errors

---
 test/core/client_channel/resolvers/sockaddr_resolver_test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index a9fd85aea1..378307ff67 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -49,7 +49,7 @@ typedef struct on_resolution_arg {
 
 void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   on_resolution_arg *res = arg;
-  grpc_channel_args_destroy(res->resolver_result);
+  grpc_channel_args_destroy(exec_ctx, res->resolver_result);
 }
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
-- 
GitLab


From 25186ae0f1245851bb017fde407ab2a23a645d98 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 27 Dec 2016 09:05:13 -0800
Subject: [PATCH 200/344] Set Python documentation copyright

---
 src/python/grpcio/commands.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index ea3b6f3391..701c6af017 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -62,6 +62,7 @@ napoleon_numpy_docstring = True
 napoleon_include_special_with_doc = True
 
 html_theme = 'sphinx_rtd_theme'
+copyright = "2016, The gRPC Authors"
 """
 
 API_GLOSSARY = """
-- 
GitLab


From db422d7eba8c33af913131b85bb2e9316a3c383f Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Tue, 27 Dec 2016 09:23:52 -0800
Subject: [PATCH 201/344] Provide doc dir even if user interrupts docgen

---
 tools/distrib/python/docgen.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py
index 622317920d..38ffcd6e0e 100755
--- a/tools/distrib/python/docgen.py
+++ b/tools/distrib/python/docgen.py
@@ -94,6 +94,7 @@ if args.submit:
   # specified repository, edit it, and push it. It's up to the user to then go
   # onto GitHub and make a PR against grpc/grpc:gh-pages.
   repo_parent_dir = tempfile.mkdtemp()
+  print('Documentation parent directory: {}'.format(repo_parent_dir))
   repo_dir = os.path.join(repo_parent_dir, 'grpc')
   python_doc_dir = os.path.join(repo_dir, 'python')
   doc_branch = args.doc_branch
-- 
GitLab


From 91031dacb1ff5c57500307044b18c9f929134462 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 28 Dec 2016 15:44:25 -0800
Subject: [PATCH 202/344] Changes to exec_ctx/closure/combiner/workqueue
 interfaces

- make closures know where they should be executed (eg, on a workqueue,
  or a combiner, or on an exec_ctx)
- this allows removal of a large number of trampoline functions that
  were appearing whenever we used combiners, and should allow for a much
  easier interface to combiner locks
---
 src/core/ext/census/grpc_filter.c             |   2 +-
 .../ext/client_channel/channel_connectivity.c |   2 +-
 src/core/ext/client_channel/client_channel.c  |  50 ++---
 .../client_channel/http_connect_handshaker.c  |   8 +-
 src/core/ext/client_channel/subchannel.c      |  13 +-
 src/core/ext/lb_policy/grpclb/grpclb.c        |  41 ++--
 .../ext/lb_policy/pick_first/pick_first.c     |  28 +--
 .../ext/lb_policy/round_robin/round_robin.c   |  22 +-
 .../load_reporting/load_reporting_filter.c    |   2 +-
 .../ext/resolver/dns/native/dns_resolver.c    |  13 +-
 .../ext/resolver/sockaddr/sockaddr_resolver.c |   4 +-
 .../chttp2/client/chttp2_connector.c          |  10 +-
 .../transport/chttp2/server/chttp2_server.c   |   3 +-
 .../chttp2/transport/chttp2_transport.c       | 189 +++++++-----------
 .../transport/chttp2/transport/hpack_parser.c |   9 +-
 .../ext/transport/chttp2/transport/internal.h |   4 -
 .../cronet/transport/cronet_transport.c       |  22 +-
 src/core/lib/channel/channel_stack.c          |   9 +-
 src/core/lib/channel/compress_filter.c        |   6 +-
 src/core/lib/channel/deadline_filter.c        |  11 +-
 src/core/lib/channel/handshaker.c             |   8 +-
 src/core/lib/channel/http_client_filter.c     |  15 +-
 src/core/lib/channel/http_server_filter.c     |   9 +-
 src/core/lib/channel/message_size_filter.c    |   5 +-
 src/core/lib/http/httpcli.c                   |  18 +-
 .../lib/http/httpcli_security_connector.c     |   2 +-
 src/core/lib/iomgr/closure.c                  |  38 +++-
 src/core/lib/iomgr/closure.h                  |  39 +++-
 src/core/lib/iomgr/combiner.c                 | 110 ++++++++--
 src/core/lib/iomgr/combiner.h                 |  14 +-
 src/core/lib/iomgr/ev_epoll_linux.c           |  32 ++-
 src/core/lib/iomgr/ev_poll_posix.c            |  26 +--
 src/core/lib/iomgr/ev_posix.c                 |   5 +-
 src/core/lib/iomgr/ev_posix.h                 |   3 +-
 src/core/lib/iomgr/exec_ctx.c                 | 130 +-----------
 src/core/lib/iomgr/exec_ctx.h                 |  31 +--
 src/core/lib/iomgr/executor.c                 |  12 +-
 src/core/lib/iomgr/executor.h                 |   4 +-
 src/core/lib/iomgr/pollset_uv.c               |   2 +-
 src/core/lib/iomgr/pollset_windows.c          |   4 +-
 src/core/lib/iomgr/resolve_address_posix.c    |  10 +-
 src/core/lib/iomgr/resolve_address_uv.c       |   6 +-
 src/core/lib/iomgr/resolve_address_windows.c  |   4 +-
 src/core/lib/iomgr/resource_quota.c           | 101 +++++-----
 src/core/lib/iomgr/socket_windows.c           |   4 +-
 src/core/lib/iomgr/tcp_client_posix.c         |  11 +-
 src/core/lib/iomgr/tcp_client_uv.c            |   2 +-
 src/core/lib/iomgr/tcp_client_windows.c       |   6 +-
 src/core/lib/iomgr/tcp_posix.c                |  13 +-
 src/core/lib/iomgr/tcp_server_posix.c         |   4 +-
 src/core/lib/iomgr/tcp_server_uv.c            |   4 +-
 src/core/lib/iomgr/tcp_server_windows.c       |   8 +-
 src/core/lib/iomgr/tcp_uv.c                   |  10 +-
 src/core/lib/iomgr/tcp_windows.c              |  20 +-
 src/core/lib/iomgr/timer_generic.c            |  14 +-
 src/core/lib/iomgr/timer_uv.c                 |   8 +-
 src/core/lib/iomgr/udp_server.c               |   2 +-
 src/core/lib/iomgr/workqueue.h                |  11 +-
 src/core/lib/iomgr/workqueue_uv.c             |   5 +-
 src/core/lib/iomgr/workqueue_windows.c        |   5 +-
 .../credentials/fake/fake_credentials.c       |   7 +-
 .../google_default_credentials.c              |   6 +-
 .../security/credentials/jwt/jwt_verifier.c   |   8 +-
 .../credentials/oauth2/oauth2_credentials.c   |  16 +-
 .../lib/security/transport/secure_endpoint.c  |   9 +-
 .../security/transport/security_connector.c   |  10 +-
 .../security/transport/security_handshaker.c  |  18 +-
 .../security/transport/server_auth_filter.c   |  18 +-
 src/core/lib/surface/call.c                   |  29 +--
 src/core/lib/surface/channel_ping.c           |   2 +-
 src/core/lib/surface/completion_queue.c       |   2 +-
 src/core/lib/surface/lame_client.c            |  10 +-
 src/core/lib/surface/server.c                 |  49 +++--
 src/core/lib/transport/connectivity_state.c   |  14 +-
 src/core/lib/transport/transport.c            |  27 ++-
 test/core/bad_client/bad_client.c             |   4 +-
 .../dns_resolver_connectivity_test.c          |  10 +-
 .../resolvers/sockaddr_resolver_test.c        |   4 +-
 .../set_initial_connect_string_test.c         |   2 +-
 test/core/end2end/bad_server_response_test.c  |   4 +-
 test/core/end2end/fake_resolver.c             |   4 +-
 test/core/end2end/fixtures/http_proxy.c       |  26 ++-
 test/core/end2end/fuzzers/api_fuzzer.c        |  14 +-
 test/core/end2end/tests/filter_causes_close.c |   7 +-
 test/core/http/httpcli_test.c                 |  18 +-
 test/core/http/httpscli_test.c                |  18 +-
 test/core/internal_api_canaries/iomgr.c       |   9 +-
 test/core/iomgr/combiner_test.c               |  27 ++-
 test/core/iomgr/endpoint_pair_test.c          |   2 +-
 test/core/iomgr/endpoint_tests.c              |  14 +-
 test/core/iomgr/ev_epoll_linux_test.c         |   2 +-
 test/core/iomgr/fd_posix_test.c               |   2 +-
 test/core/iomgr/resolve_address_test.c        |  45 +++--
 test/core/iomgr/resource_quota_test.c         |   9 +-
 test/core/iomgr/tcp_client_posix_test.c       |   6 +-
 test/core/iomgr/tcp_posix_test.c              |  12 +-
 test/core/iomgr/tcp_server_posix_test.c       |   5 +-
 test/core/iomgr/udp_server_test.c             |   2 +-
 test/core/security/credentials_test.c         |  12 +-
 test/core/security/jwt_verifier_test.c        |  10 +-
 test/core/security/oauth2_utils.c             |   3 +-
 test/core/security/secure_endpoint_test.c     |   4 +-
 .../surface/concurrent_connectivity_test.c    |   6 +-
 test/core/surface/lame_client_test.c          |   4 +-
 test/core/transport/connectivity_state_test.c |   6 +-
 test/core/util/mock_endpoint.c                |  10 +-
 test/core/util/passthru_endpoint.c            |  15 +-
 test/core/util/port_server_client.c           |  22 +-
 test/core/util/test_tcp_server.c              |   4 +-
 109 files changed, 922 insertions(+), 848 deletions(-)

diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 3e8acc85e1..6429ee444e 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -154,7 +154,7 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
   memset(d, 0, sizeof(*d));
   d->start_ts = args->start_time;
   /* TODO(hongyu): call census_tracing_start_op here. */
-  grpc_closure_init(&d->finish_recv, server_on_done_recv, elem);
+  grpc_closure_init(&d->finish_recv, server_on_done_recv, elem, grpc_schedule_on_exec_ctx);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/ext/client_channel/channel_connectivity.c b/src/core/ext/client_channel/channel_connectivity.c
index 9797e66564..4cbd4293df 100644
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ b/src/core/ext/client_channel/channel_connectivity.c
@@ -198,7 +198,7 @@ void grpc_channel_watch_connectivity_state(
   grpc_cq_begin_op(cq, tag);
 
   gpr_mu_init(&w->mu);
-  grpc_closure_init(&w->on_complete, watch_complete, w);
+  grpc_closure_init(&w->on_complete, watch_complete, w, grpc_schedule_on_exec_ctx);
   w->phase = WAITING;
   w->state = last_observed_state;
   w->cq = cq;
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 9d46338428..a762b8917e 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -249,7 +249,8 @@ static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
   GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy");
 
   w->chand = chand;
-  grpc_closure_init(&w->on_changed, on_lb_policy_state_changed, w);
+  grpc_closure_init(&w->on_changed, on_lb_policy_state_changed, w,
+                    grpc_schedule_on_exec_ctx);
   w->state = current_state;
   w->lb_policy = lb_policy;
   grpc_lb_policy_notify_on_state_change(exec_ctx, lb_policy, &w->state,
@@ -361,14 +362,12 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
   }
   chand->method_params_table = method_params_table;
   if (lb_policy != NULL) {
-    grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures,
-                               NULL);
+    grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   } else if (chand->resolver == NULL /* disconnected */) {
     grpc_closure_list_fail_all(
         &chand->waiting_for_config_closures,
         GRPC_ERROR_CREATE_REFERENCING("Channel disconnected", &error, 1));
-    grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures,
-                               NULL);
+    grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
   }
   if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
     GRPC_LB_POLICY_REF(lb_policy, "exit_idle");
@@ -425,7 +424,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
                                   grpc_transport_op *op) {
   channel_data *chand = elem->channel_data;
 
-  grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
 
   GPR_ASSERT(op->set_accept_stream == false);
   if (op->bind_pollset != NULL) {
@@ -444,9 +443,8 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
 
   if (op->send_ping != NULL) {
     if (chand->lb_policy == NULL) {
-      grpc_exec_ctx_sched(exec_ctx, op->send_ping,
-                          GRPC_ERROR_CREATE("Ping with no load balancing"),
-                          NULL);
+      grpc_closure_sched(exec_ctx, op->send_ping,
+                         GRPC_ERROR_CREATE("Ping with no load balancing"));
     } else {
       grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->send_ping);
       op->bind_pollset = NULL;
@@ -465,8 +463,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
       if (!chand->started_resolving) {
         grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
                                    GRPC_ERROR_REF(op->disconnect_with_error));
-        grpc_exec_ctx_enqueue_list(exec_ctx,
-                                   &chand->waiting_for_config_closures, NULL);
+        grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
       }
       if (chand->lb_policy != NULL) {
         grpc_pollset_set_del_pollset_set(exec_ctx,
@@ -511,7 +508,8 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_init(&chand->mu);
   chand->owning_stack = args->channel_stack;
   grpc_closure_init(&chand->on_resolver_result_changed,
-                    on_resolver_result_changed, chand);
+                    on_resolver_result_changed, chand,
+                    grpc_schedule_on_exec_ctx);
   chand->interested_parties = grpc_pollset_set_create();
   grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
                                "client_channel");
@@ -678,8 +676,9 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
   calld->waiting_ops_count = 0;
   calld->waiting_ops_capacity = 0;
   GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
-  grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a),
-                      GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(
+      exec_ctx, grpc_closure_create(retry_ops, a, grpc_schedule_on_exec_ctx),
+      GRPC_ERROR_NONE);
 }
 
 static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
@@ -761,14 +760,14 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
   if (cpa->connected_subchannel == NULL) {
     /* cancelled, do nothing */
   } else if (error != GRPC_ERROR_NONE) {
-    grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error), NULL);
+    grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error));
   } else {
     call_data *calld = cpa->elem->call_data;
     gpr_mu_lock(&calld->mu);
     if (pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
                         cpa->initial_metadata_flags, cpa->connected_subchannel,
                         cpa->on_ready, GRPC_ERROR_NONE)) {
-      grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE, NULL);
+      grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
     }
     gpr_mu_unlock(&calld->mu);
   }
@@ -800,9 +799,9 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
       cpa = closure->cb_arg;
       if (cpa->connected_subchannel == connected_subchannel) {
         cpa->connected_subchannel = NULL;
-        grpc_exec_ctx_sched(
+        grpc_closure_sched(
             exec_ctx, cpa->on_ready,
-            GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1), NULL);
+            GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
       }
     }
     gpr_mu_unlock(&chand->mu);
@@ -853,12 +852,12 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
     cpa->connected_subchannel = connected_subchannel;
     cpa->on_ready = on_ready;
     cpa->elem = elem;
-    grpc_closure_init(&cpa->closure, continue_picking, cpa);
+    grpc_closure_init(&cpa->closure, continue_picking, cpa,
+                      grpc_schedule_on_exec_ctx);
     grpc_closure_list_append(&chand->waiting_for_config_closures, &cpa->closure,
                              GRPC_ERROR_NONE);
   } else {
-    grpc_exec_ctx_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"));
   }
   gpr_mu_unlock(&chand->mu);
 
@@ -943,7 +942,8 @@ retry:
       calld->connected_subchannel == NULL &&
       op->send_initial_metadata != NULL) {
     calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
-    grpc_closure_init(&calld->next_step, subchannel_ready, elem);
+    grpc_closure_init(&calld->next_step, subchannel_ready, elem,
+                      grpc_schedule_on_exec_ctx);
     GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
     /* If a subchannel is not available immediately, the polling entity from
        call_data should be provided to channel_data's interested_parties, so
@@ -1089,7 +1089,8 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
     // 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, elem);
+    grpc_closure_init(&calld->read_service_config, read_service_config, elem,
+                      grpc_schedule_on_exec_ctx);
     grpc_closure_list_append(&chand->waiting_for_config_closures,
                              &calld->read_service_config, GRPC_ERROR_NONE);
     gpr_mu_unlock(&chand->mu);
@@ -1202,7 +1203,8 @@ void grpc_client_channel_watch_connectivity_state(
   w->pollset = pollset;
   w->on_complete = on_complete;
   grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
-  grpc_closure_init(&w->my_closure, on_external_watch_complete, w);
+  grpc_closure_init(&w->my_closure, on_external_watch_complete, w,
+                    grpc_schedule_on_exec_ctx);
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
                          "external_connectivity_watcher");
   gpr_mu_lock(&chand->mu);
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 76c78ee853..a0fc95e7bb 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -131,7 +131,7 @@ static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
     handshaker->shutdown = true;
   }
   // Invoke callback.
-  grpc_exec_ctx_sched(exec_ctx, handshaker->on_handshake_done, error, NULL);
+  grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
 }
 
 // Callback invoked when finished writing HTTP CONNECT request.
@@ -229,7 +229,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
     goto done;
   }
   // Success.  Invoke handshake-done callback.
-  grpc_exec_ctx_sched(exec_ctx, handshaker->on_handshake_done, error, NULL);
+  grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
 done:
   // Set shutdown to true so that subsequent calls to
   // http_connect_handshaker_shutdown() do nothing.
@@ -313,9 +313,9 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) {
   handshaker->proxy_server = gpr_strdup(proxy_server);
   grpc_slice_buffer_init(&handshaker->write_buffer);
   grpc_closure_init(&handshaker->request_done_closure, on_write_done,
-                    handshaker);
+                    handshaker, grpc_schedule_on_exec_ctx);
   grpc_closure_init(&handshaker->response_read_closure, on_read_done,
-                    handshaker);
+                    handshaker, grpc_schedule_on_exec_ctx);
   grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE,
                         &handshaker->http_response);
   return &handshaker->base;
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index f294e69392..87f0ef298a 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -293,8 +293,9 @@ void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx,
   gpr_atm old_refs;
   old_refs = ref_mutate(c, -(gpr_atm)1, 1 REF_MUTATE_PURPOSE("WEAK_UNREF"));
   if (old_refs == 1) {
-    grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(subchannel_destroy, c),
-                        GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, grpc_closure_create(subchannel_destroy, c,
+                                                     grpc_schedule_on_exec_ctx),
+                       GRPC_ERROR_NONE);
   }
 }
 
@@ -330,7 +331,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
   c->args = grpc_channel_args_copy(args->args);
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
-  grpc_closure_init(&c->connected, subchannel_connected, c);
+  grpc_closure_init(&c->connected, subchannel_connected, c,
+                    grpc_schedule_on_exec_ctx);
   grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
                                "subchannel");
   int initial_backoff_ms =
@@ -505,7 +507,8 @@ void grpc_subchannel_notify_on_state_change(
     w->subchannel = c;
     w->pollset_set = interested_parties;
     w->notify = notify;
-    grpc_closure_init(&w->closure, on_external_state_watcher_done, w);
+    grpc_closure_init(&w->closure, on_external_state_watcher_done, w,
+                      grpc_schedule_on_exec_ctx);
     if (interested_parties != NULL) {
       grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
                                        interested_parties);
@@ -626,7 +629,7 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
   sw_subchannel->subchannel = c;
   sw_subchannel->connectivity_state = GRPC_CHANNEL_READY;
   grpc_closure_init(&sw_subchannel->closure, subchannel_on_child_state_changed,
-                    sw_subchannel);
+                    sw_subchannel, grpc_schedule_on_exec_ctx);
 
   if (c->disconnected) {
     gpr_free(sw_subchannel);
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index bed5e6c901..bb0ee9d95c 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -180,8 +180,7 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
   wrapped_rr_closure_arg *wc_arg = arg;
 
   GPR_ASSERT(wc_arg->wrapped_closure != NULL);
-  grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error),
-                      NULL);
+  grpc_closure_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error));
 
   if (wc_arg->rr_policy != NULL) {
     /* if *target is NULL, no pick has been made by the RR policy (eg, all
@@ -248,7 +247,8 @@ static void add_pending_pick(pending_pick **root,
       pick_args->lb_token_mdelem_storage;
   pp->wrapped_on_complete_arg.free_when_done = pp;
   grpc_closure_init(&pp->wrapped_on_complete_arg.wrapper_closure,
-                    wrapped_rr_closure, &pp->wrapped_on_complete_arg);
+                    wrapped_rr_closure, &pp->wrapped_on_complete_arg,
+                    grpc_schedule_on_exec_ctx);
   *root = pp;
 }
 
@@ -268,7 +268,8 @@ static void add_pending_ping(pending_ping **root, grpc_closure *notify) {
   pping->wrapped_notify_arg.free_when_done = pping;
   pping->next = *root;
   grpc_closure_init(&pping->wrapped_notify_arg.wrapper_closure,
-                    wrapped_rr_closure, &pping->wrapped_notify_arg);
+                    wrapped_rr_closure, &pping->wrapped_notify_arg,
+                    grpc_schedule_on_exec_ctx);
   *root = pping;
 }
 
@@ -667,7 +668,7 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
       gpr_malloc(sizeof(rr_connectivity_data));
   memset(rr_connectivity, 0, sizeof(rr_connectivity_data));
   grpc_closure_init(&rr_connectivity->on_change, glb_rr_connectivity_changed,
-                    rr_connectivity);
+                    rr_connectivity, grpc_schedule_on_exec_ctx);
   rr_connectivity->glb_policy = glb_policy;
   rr_connectivity->state = new_rr_state;
 
@@ -908,15 +909,15 @@ static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   while (pp != NULL) {
     pending_pick *next = pp->next;
     *pp->target = NULL;
-    grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-                        GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
+                       GRPC_ERROR_NONE);
     pp = next;
   }
 
   while (pping != NULL) {
     pending_ping *next = pping->next;
-    grpc_exec_ctx_sched(exec_ctx, &pping->wrapped_notify_arg.wrapper_closure,
-                        GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &pping->wrapped_notify_arg.wrapper_closure,
+                       GRPC_ERROR_NONE);
     pping = next;
   }
 }
@@ -932,9 +933,9 @@ static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -957,9 +958,9 @@ static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if ((pp->pick_args.initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -994,11 +995,10 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
                     grpc_closure *on_complete) {
   if (pick_args->lb_token_mdelem_storage == NULL) {
     *target = NULL;
-    grpc_exec_ctx_sched(
+    grpc_closure_sched(
         exec_ctx, on_complete,
         GRPC_ERROR_CREATE("No mdelem storage for the LB token. Load reporting "
-                          "won't work without it. Failing"),
-        NULL);
+                          "won't work without it. Failing"));
     return 0;
   }
 
@@ -1017,7 +1017,8 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     wrapped_rr_closure_arg *wc_arg = gpr_malloc(sizeof(wrapped_rr_closure_arg));
     memset(wc_arg, 0, sizeof(wrapped_rr_closure_arg));
 
-    grpc_closure_init(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg);
+    grpc_closure_init(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg,
+                      grpc_schedule_on_exec_ctx);
     wc_arg->rr_policy = glb_policy->rr_policy;
     wc_arg->target = target;
     wc_arg->wrapped_closure = on_complete;
@@ -1117,9 +1118,11 @@ static void lb_call_init_locked(glb_lb_policy *glb_policy) {
   glb_policy->lb_call_status_details_capacity = 0;
 
   grpc_closure_init(&glb_policy->lb_on_server_status_received,
-                    lb_on_server_status_received, glb_policy);
+                    lb_on_server_status_received, glb_policy,
+                    grpc_schedule_on_exec_ctx);
   grpc_closure_init(&glb_policy->lb_on_response_received,
-                    lb_on_response_received, glb_policy);
+                    lb_on_response_received, glb_policy,
+                    grpc_schedule_on_exec_ctx);
 
   gpr_backoff_init(&glb_policy->lb_call_backoff_state,
                    GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS,
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index b9cfe6b5c0..821becff69 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -120,7 +120,7 @@ static void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   while (pp != NULL) {
     pending_pick *next = pp->next;
     *pp->target = NULL;
-    grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
     gpr_free(pp);
     pp = next;
   }
@@ -138,9 +138,9 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -165,9 +165,9 @@ static void pf_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -306,14 +306,15 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
         /* drop the pick list: we are connected now */
         GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels");
         gpr_atm_rel_store(&p->selected, (gpr_atm)selected);
-        grpc_exec_ctx_sched(exec_ctx,
-                            grpc_closure_create(destroy_subchannels, p),
-                            GRPC_ERROR_NONE, NULL);
+        grpc_closure_sched(exec_ctx,
+                           grpc_closure_create(destroy_subchannels, p,
+                                               grpc_schedule_on_exec_ctx),
+                           GRPC_ERROR_NONE);
         /* update any calls that were waiting for a pick */
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
           *pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(selected, "picked");
-          grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
+          grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
           gpr_free(pp);
         }
         grpc_connected_subchannel_notify_on_state_change(
@@ -366,8 +367,7 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
           while ((pp = p->pending_picks)) {
             p->pending_picks = pp->next;
             *pp->target = NULL;
-            grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE,
-                                NULL);
+            grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
             gpr_free(pp);
           }
           GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base,
@@ -419,8 +419,7 @@ static void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
   if (selected) {
     grpc_connected_subchannel_ping(exec_ctx, selected, closure);
   } else {
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CREATE("Not connected"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("Not connected"));
   }
 }
 
@@ -485,7 +484,8 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
   p->num_subchannels = subchannel_idx;
 
   grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable);
-  grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed, p);
+  grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed, p,
+                    grpc_schedule_on_exec_ctx);
   gpr_mu_init(&p->mu);
   return &p->base;
 }
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index f0305473d2..47f20a1904 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -321,8 +321,8 @@ static void rr_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   while ((pp = p->pending_picks)) {
     p->pending_picks = pp->next;
     *pp->target = NULL;
-    grpc_exec_ctx_sched(exec_ctx, pp->on_complete,
-                        GRPC_ERROR_CREATE("Channel Shutdown"), NULL);
+    grpc_closure_sched(exec_ctx, pp->on_complete,
+                       GRPC_ERROR_CREATE("Channel Shutdown"));
     gpr_free(pp);
   }
   grpc_connectivity_state_set(
@@ -348,9 +348,9 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     if (pp->target == target) {
       *target = NULL;
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -376,9 +376,9 @@ static void rr_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
       *pp->target = NULL;
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, pp->on_complete,
-          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1), NULL);
+          GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
       gpr_free(pp);
     } else {
       pp->next = p->pending_picks;
@@ -581,7 +581,7 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
                   "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
                   (void *)selected->subchannel, (void *)selected);
         }
-        grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
+        grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
         gpr_free(pp);
       }
       update_lb_connectivity_status(exec_ctx, sd, error);
@@ -634,7 +634,7 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
           *pp->target = NULL;
-          grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
+          grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
           gpr_free(pp);
         }
       }
@@ -684,8 +684,8 @@ static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
   } else {
     gpr_mu_unlock(&p->mu);
-    grpc_exec_ctx_sched(exec_ctx, closure,
-                        GRPC_ERROR_CREATE("Round Robin not connected"), NULL);
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE("Round Robin not connected"));
   }
 }
 
@@ -749,7 +749,7 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
       }
       ++subchannel_idx;
       grpc_closure_init(&sd->connectivity_changed_closure,
-                        rr_connectivity_changed, sd);
+                        rr_connectivity_changed, sd, grpc_schedule_on_exec_ctx);
     }
   }
   if (subchannel_idx == 0) {
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index 18bb826948..df72686446 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -114,7 +114,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   memset(calld, 0, sizeof(call_data));
 
   calld->id = (intptr_t)args->call_stack;
-  grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem);
+  grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem, grpc_schedule_on_exec_ctx);
 
   /* TODO(dgq): do something with the data
   channel_data *chand = elem->channel_data;
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 2675fa931f..efbb2be4e1 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -112,8 +112,8 @@ static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
   }
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion,
-                        GRPC_ERROR_CREATE("Resolver Shutdown"), NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion,
+                       GRPC_ERROR_CREATE("Resolver Shutdown"));
     r->next_completion = NULL;
   }
   gpr_mu_unlock(&r->mu);
@@ -219,9 +219,10 @@ static void dns_start_resolving_locked(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(!r->resolving);
   r->resolving = true;
   r->addresses = NULL;
-  grpc_resolve_address(exec_ctx, r->name_to_resolve, r->default_port,
-                       r->interested_parties,
-                       grpc_closure_create(dns_on_resolved, r), &r->addresses);
+  grpc_resolve_address(
+      exec_ctx, r->name_to_resolve, r->default_port, r->interested_parties,
+      grpc_closure_create(dns_on_resolved, r, grpc_schedule_on_exec_ctx),
+      &r->addresses);
 }
 
 static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
@@ -231,7 +232,7 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
     *r->target_result = r->resolved_result == NULL
                             ? NULL
                             : grpc_channel_args_copy(r->resolved_result);
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
     r->published_version = r->resolved_version;
   }
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 88808c674f..55ea502c9e 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -89,7 +89,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx,
   gpr_mu_lock(&r->mu);
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
   }
   gpr_mu_unlock(&r->mu);
@@ -123,7 +123,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
     grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
     *r->target_result =
         grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
   }
 }
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 114bb07222..c807342ebc 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -141,7 +141,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
   }
   grpc_closure *notify = c->notify;
   c->notify = NULL;
-  grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+  grpc_closure_sched(exec_ctx, notify, error);
   grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
   c->handshake_mgr = NULL;
   gpr_mu_unlock(&c->mu);
@@ -180,7 +180,7 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
     memset(c->result, 0, sizeof(*c->result));
     grpc_closure *notify = c->notify;
     c->notify = NULL;
-    grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+    grpc_closure_sched(exec_ctx, notify, error);
     gpr_mu_unlock(&c->mu);
     chttp2_connector_unref(exec_ctx, arg);
   } else {
@@ -203,7 +203,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     memset(c->result, 0, sizeof(*c->result));
     grpc_closure *notify = c->notify;
     c->notify = NULL;
-    grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+    grpc_closure_sched(exec_ctx, notify, error);
     if (c->endpoint != NULL) grpc_endpoint_shutdown(exec_ctx, c->endpoint);
     gpr_mu_unlock(&c->mu);
     chttp2_connector_unref(exec_ctx, arg);
@@ -211,7 +211,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     GPR_ASSERT(c->endpoint != NULL);
     if (!GRPC_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
       grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
-                        c);
+                        c, grpc_schedule_on_exec_ctx);
       grpc_slice_buffer_init(&c->initial_string_buffer);
       grpc_slice_buffer_add(&c->initial_string_buffer,
                             c->args.initial_connect_string);
@@ -237,7 +237,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
   c->result = result;
   GPR_ASSERT(c->endpoint == NULL);
   chttp2_connector_ref(con);  // Ref taken for callback.
-  grpc_closure_init(&c->connected, connected, c);
+  grpc_closure_init(&c->connected, connected, c, grpc_schedule_on_exec_ctx);
   GPR_ASSERT(!c->connecting);
   c->connecting = true;
   grpc_tcp_client_connect(exec_ctx, &c->connected, &c->endpoint,
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index f0857714fc..9af62d372e 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -281,7 +281,8 @@ grpc_error *grpc_chttp2_server_add_port(
   state = gpr_malloc(sizeof(*state));
   memset(state, 0, sizeof(*state));
   grpc_closure_init(&state->tcp_server_shutdown_complete,
-                    tcp_server_shutdown_complete, state);
+                    tcp_server_shutdown_complete, state,
+                    grpc_schedule_on_exec_ctx);
   err = grpc_tcp_server_create(exec_ctx, &state->tcp_server_shutdown_complete,
                                args, &tcp_server);
   if (err != GRPC_ERROR_NONE) {
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 6bc054866b..488c3b93cc 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -73,20 +73,14 @@ static const grpc_transport_vtable vtable;
 static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *t,
                                       grpc_error *error);
 static void write_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
-static void write_action_end(grpc_exec_ctx *exec_ctx, void *t,
-                             grpc_error *error);
 static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *t,
                                     grpc_error *error);
 
-static void read_action_begin(grpc_exec_ctx *exec_ctx, void *t,
-                              grpc_error *error);
 static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t,
                                grpc_error *error);
 
 static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
                                   grpc_error *error);
-static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs,
-                           grpc_error *error);
 /** Set a transport level setting, and push it to our peer */
 static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                          grpc_chttp2_setting_id id, uint32_t value);
@@ -112,12 +106,8 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
                                                 void *byte_stream,
                                                 grpc_error *error_ignored);
 
-static void benign_reclaimer(grpc_exec_ctx *exec_ctx, void *t,
-                             grpc_error *error);
 static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
                                     grpc_error *error);
-static void destructive_reclaimer(grpc_exec_ctx *exec_ctx, void *t,
-                                  grpc_error *error);
 static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *t,
                                          grpc_error *error);
 
@@ -166,8 +156,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
      and maybe they hold resources that need to be freed */
   while (t->pings.next != &t->pings) {
     grpc_chttp2_outstanding_ping *ping = t->pings.next;
-    grpc_exec_ctx_sched(exec_ctx, ping->on_recv,
-                        GRPC_ERROR_CREATE("Transport closed"), NULL);
+    grpc_closure_sched(exec_ctx, ping->on_recv,
+                       GRPC_ERROR_CREATE("Transport closed"));
     ping->next->prev = ping->prev;
     ping->prev->next = ping->next;
     gpr_free(ping);
@@ -246,18 +236,15 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   grpc_slice_buffer_init(&t->outbuf);
   grpc_chttp2_hpack_compressor_init(&t->hpack_compressor);
 
-  grpc_closure_init(&t->write_action_begin_locked, write_action_begin_locked,
-                    t);
-  grpc_closure_init(&t->write_action, write_action, t);
-  grpc_closure_init(&t->write_action_end, write_action_end, t);
-  grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t);
-  grpc_closure_init(&t->read_action_begin, read_action_begin, t);
-  grpc_closure_init(&t->read_action_locked, read_action_locked, t);
-  grpc_closure_init(&t->benign_reclaimer, benign_reclaimer, t);
-  grpc_closure_init(&t->destructive_reclaimer, destructive_reclaimer, t);
-  grpc_closure_init(&t->benign_reclaimer_locked, benign_reclaimer_locked, t);
+  grpc_closure_init(&t->write_action, write_action, t,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&t->read_action_locked, read_action_locked, t,
+                    grpc_combiner_scheduler(t->combiner, false));
+  grpc_closure_init(&t->benign_reclaimer_locked, benign_reclaimer_locked, t,
+                    grpc_combiner_scheduler(t->combiner, false));
   grpc_closure_init(&t->destructive_reclaimer_locked,
-                    destructive_reclaimer_locked, t);
+                    destructive_reclaimer_locked, t,
+                    grpc_combiner_scheduler(t->combiner, false));
 
   grpc_chttp2_goaway_parser_init(&t->goaway_parser);
   grpc_chttp2_hpack_parser_init(&t->hpack_parser);
@@ -395,9 +382,10 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp,
 
 static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
-  grpc_combiner_execute(exec_ctx, t->combiner,
-                        grpc_closure_create(destroy_transport_locked, t),
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(exec_ctx, grpc_closure_create(
+                                   destroy_transport_locked, t,
+                                   grpc_combiner_scheduler(t->combiner, false)),
+                     GRPC_ERROR_NONE);
 }
 
 static void close_transport_locked(grpc_exec_ctx *exec_ctx,
@@ -471,8 +459,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   grpc_chttp2_data_parser_init(&s->data_parser);
   grpc_slice_buffer_init(&s->flow_controlled_buffer);
   s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
-  grpc_closure_init(&s->complete_fetch, complete_fetch, s);
-  grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s);
+  grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s,
+                    grpc_schedule_on_exec_ctx);
 
   GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
 
@@ -547,9 +535,10 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
 
   s->destroy_stream_arg = and_free_memory;
-  grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s);
-  grpc_combiner_execute(exec_ctx, t->combiner, &s->destroy_stream,
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(
+      exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s,
+                                  grpc_combiner_scheduler(t->combiner, false)),
+      GRPC_ERROR_NONE);
   GPR_TIMER_END("destroy_stream", 0);
 }
 
@@ -600,7 +589,7 @@ static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                                  write_state_name(st), reason));
   t->write_state = st;
   if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) {
-    grpc_exec_ctx_enqueue_list(exec_ctx, &t->run_after_write, NULL);
+    grpc_closure_list_sched(exec_ctx, &t->run_after_write);
     if (t->close_transport_on_writes_finished != NULL) {
       grpc_error *err = t->close_transport_on_writes_finished;
       t->close_transport_on_writes_finished = NULL;
@@ -618,9 +607,12 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
     case GRPC_CHTTP2_WRITE_STATE_IDLE:
       set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason);
       GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
-      grpc_combiner_execute_finally(exec_ctx, t->combiner,
-                                    &t->write_action_begin_locked,
-                                    GRPC_ERROR_NONE, covered_by_poller);
+      grpc_closure_sched(
+          exec_ctx,
+          grpc_closure_init(
+              &t->write_action_begin_locked, write_action_begin_locked, t,
+              grpc_combiner_finally_scheduler(t->combiner, covered_by_poller)),
+          GRPC_ERROR_NONE);
       break;
     case GRPC_CHTTP2_WRITE_STATE_WRITING:
       set_write_state(
@@ -662,7 +654,7 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt,
   if (!t->closed && grpc_chttp2_begin_write(exec_ctx, t)) {
     set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
                     "begin writing");
-    grpc_exec_ctx_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
   } else {
     set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE,
                     "begin writing nothing");
@@ -674,19 +666,13 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt,
 static void write_action(grpc_exec_ctx *exec_ctx, void *gt, grpc_error *error) {
   grpc_chttp2_transport *t = gt;
   GPR_TIMER_BEGIN("write_action", 0);
-  grpc_endpoint_write(exec_ctx, t->ep, &t->outbuf, &t->write_action_end);
+  grpc_endpoint_write(
+      exec_ctx, t->ep, &t->outbuf,
+      grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t,
+                        grpc_combiner_scheduler(t->combiner, false)));
   GPR_TIMER_END("write_action", 0);
 }
 
-static void write_action_end(grpc_exec_ctx *exec_ctx, void *gt,
-                             grpc_error *error) {
-  grpc_chttp2_transport *t = gt;
-  GPR_TIMER_BEGIN("write_action_end", 0);
-  grpc_combiner_execute(exec_ctx, t->combiner, &t->write_action_end_locked,
-                        GRPC_ERROR_REF(error), false);
-  GPR_TIMER_END("write_action_end", 0);
-}
-
 static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
                                     grpc_error *error) {
   GPR_TIMER_BEGIN("terminate_writing_with_lock", 0);
@@ -716,18 +702,24 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
       set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
                       "continue writing [!covered]");
       GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
-      grpc_combiner_execute_finally(exec_ctx, t->combiner,
-                                    &t->write_action_begin_locked,
-                                    GRPC_ERROR_NONE, false);
+      grpc_closure_run(
+          exec_ctx,
+          grpc_closure_init(
+              &t->write_action_begin_locked, write_action_begin_locked, t,
+              grpc_combiner_finally_scheduler(t->combiner, false)),
+          GRPC_ERROR_NONE);
       break;
     case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
       GPR_TIMER_MARK("state=writing_stale_with_poller", 0);
       set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
                       "continue writing [covered]");
       GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
-      grpc_combiner_execute_finally(exec_ctx, t->combiner,
-                                    &t->write_action_begin_locked,
-                                    GRPC_ERROR_NONE, true);
+      grpc_closure_run(
+          exec_ctx,
+          grpc_closure_init(&t->write_action_begin_locked,
+                            write_action_begin_locked, t,
+                            grpc_combiner_finally_scheduler(t->combiner, true)),
+          GRPC_ERROR_NONE);
       break;
   }
 
@@ -965,15 +957,6 @@ static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
   }
 }
 
-static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs,
-                           grpc_error *error) {
-  grpc_chttp2_stream *s = gs;
-  grpc_chttp2_transport *t = s->t;
-  grpc_combiner_execute(exec_ctx, t->combiner, &s->complete_fetch_locked,
-                        GRPC_ERROR_REF(error),
-                        s->complete_fetch_covered_by_poller);
-}
-
 static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
 
 static void log_metadata(const grpc_metadata_batch *md_batch, uint32_t id,
@@ -1009,7 +992,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
 
   grpc_closure *on_complete = op->on_complete;
   if (on_complete == NULL) {
-    on_complete = grpc_closure_create(do_nothing, NULL);
+    on_complete =
+        grpc_closure_create(do_nothing, NULL, grpc_schedule_on_exec_ctx);
   }
 
   /* use final_data as a barrier until enqueue time; the inital counter is
@@ -1212,13 +1196,15 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
     gpr_free(str);
   }
 
-  grpc_closure_init(&op->transport_private.closure, perform_stream_op_locked,
-                    op);
   op->transport_private.args[0] = gt;
   op->transport_private.args[1] = gs;
   GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
-  grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure,
-                        GRPC_ERROR_NONE, op->covered_by_poller);
+  grpc_closure_sched(
+      exec_ctx,
+      grpc_closure_init(
+          &op->transport_private.closure, perform_stream_op_locked, op,
+          grpc_combiner_scheduler(t->combiner, op->covered_by_poller)),
+      GRPC_ERROR_NONE);
   GPR_TIMER_END("perform_stream_op", 0);
 }
 
@@ -1247,7 +1233,7 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
   grpc_chttp2_outstanding_ping *ping;
   for (ping = t->pings.next; ping != &t->pings; ping = ping->next) {
     if (0 == memcmp(opaque_8bytes, ping->id, 8)) {
-      grpc_exec_ctx_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE, NULL);
+      grpc_closure_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE);
       ping->next->prev = ping->prev;
       ping->prev->next = ping->next;
       gpr_free(ping);
@@ -1321,11 +1307,12 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
   char *msg = grpc_transport_op_string(op);
   gpr_free(msg);
   op->transport_private.args[0] = gt;
-  grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked,
-                    op);
   GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op");
-  grpc_combiner_execute(exec_ctx, t->combiner, &op->transport_private.closure,
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(
+      exec_ctx, grpc_closure_init(&op->transport_private.closure,
+                                  perform_transport_op_locked, op,
+                                  grpc_combiner_scheduler(t->combiner, false)),
+      GRPC_ERROR_NONE);
 }
 
 /*******************************************************************************
@@ -1801,19 +1788,6 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
  * INPUT PROCESSING - PARSING
  */
 
-static void read_action_begin(grpc_exec_ctx *exec_ctx, void *tp,
-                              grpc_error *error) {
-  /* Control flow:
-     reading_action_locked ->
-       (parse_unlocked -> post_parse_locked)? ->
-       post_reading_action_locked */
-  GPR_TIMER_BEGIN("reading_action", 0);
-  grpc_chttp2_transport *t = tp;
-  grpc_combiner_execute(exec_ctx, t->combiner, &t->read_action_locked,
-                        GRPC_ERROR_REF(error), false);
-  GPR_TIMER_END("reading_action", 0);
-}
-
 static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
                                     grpc_chttp2_transport *t) {
   grpc_http_parser parser;
@@ -1913,7 +1887,8 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
   grpc_slice_buffer_reset_and_unref(&t->read_buffer);
 
   if (keep_reading) {
-    grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin);
+    grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
+                       &t->read_action_locked);
     GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
   } else {
     GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action");
@@ -2050,10 +2025,12 @@ static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
   bs->next_action.slice = slice;
   bs->next_action.max_size_hint = max_size_hint;
   bs->next_action.on_complete = on_complete;
-  grpc_closure_init(&bs->next_action.closure, incoming_byte_stream_next_locked,
-                    bs);
-  grpc_combiner_execute(exec_ctx, bs->transport->combiner,
-                        &bs->next_action.closure, GRPC_ERROR_NONE, false);
+  grpc_closure_sched(
+      exec_ctx,
+      grpc_closure_init(
+          &bs->next_action.closure, incoming_byte_stream_next_locked, bs,
+          grpc_combiner_scheduler(bs->transport->combiner, false)),
+      GRPC_ERROR_NONE);
   GPR_TIMER_END("incoming_byte_stream_next", 0);
   return 0;
 }
@@ -2075,10 +2052,12 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
   GPR_TIMER_BEGIN("incoming_byte_stream_destroy", 0);
   grpc_chttp2_incoming_byte_stream *bs =
       (grpc_chttp2_incoming_byte_stream *)byte_stream;
-  grpc_closure_init(&bs->destroy_action, incoming_byte_stream_destroy_locked,
-                    bs);
-  grpc_combiner_execute(exec_ctx, bs->transport->combiner, &bs->destroy_action,
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(
+      exec_ctx,
+      grpc_closure_init(
+          &bs->destroy_action, incoming_byte_stream_destroy_locked, bs,
+          grpc_combiner_scheduler(bs->transport->combiner, false)),
+      GRPC_ERROR_NONE);
   GPR_TIMER_END("incoming_byte_stream_destroy", 0);
 }
 
@@ -2086,7 +2065,7 @@ static void incoming_byte_stream_publish_error(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
     grpc_error *error) {
   GPR_ASSERT(error != GRPC_ERROR_NONE);
-  grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL);
+  grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error));
   bs->on_next = NULL;
   GRPC_ERROR_UNREF(bs->error);
   bs->error = error;
@@ -2103,7 +2082,7 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
     bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice);
     if (bs->on_next != NULL) {
       *bs->next = slice;
-      grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL);
+      grpc_closure_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE);
       bs->on_next = NULL;
     } else {
       grpc_slice_buffer_add(&bs->slices, slice);
@@ -2171,7 +2150,7 @@ static void post_benign_reclaimer(grpc_exec_ctx *exec_ctx,
     GRPC_CHTTP2_REF_TRANSPORT(t, "benign_reclaimer");
     grpc_resource_user_post_reclaimer(exec_ctx,
                                       grpc_endpoint_get_resource_user(t->ep),
-                                      false, &t->benign_reclaimer);
+                                      false, &t->benign_reclaimer_locked);
   }
 }
 
@@ -2182,24 +2161,10 @@ static void post_destructive_reclaimer(grpc_exec_ctx *exec_ctx,
     GRPC_CHTTP2_REF_TRANSPORT(t, "destructive_reclaimer");
     grpc_resource_user_post_reclaimer(exec_ctx,
                                       grpc_endpoint_get_resource_user(t->ep),
-                                      true, &t->destructive_reclaimer);
+                                      true, &t->destructive_reclaimer_locked);
   }
 }
 
-static void benign_reclaimer(grpc_exec_ctx *exec_ctx, void *arg,
-                             grpc_error *error) {
-  grpc_chttp2_transport *t = arg;
-  grpc_combiner_execute(exec_ctx, t->combiner, &t->benign_reclaimer_locked,
-                        GRPC_ERROR_REF(error), false);
-}
-
-static void destructive_reclaimer(grpc_exec_ctx *exec_ctx, void *arg,
-                                  grpc_error *error) {
-  grpc_chttp2_transport *t = arg;
-  grpc_combiner_execute(exec_ctx, t->combiner, &t->destructive_reclaimer_locked,
-                        GRPC_ERROR_REF(error), false);
-}
-
 static void benign_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
                                     grpc_error *error) {
   grpc_chttp2_transport *t = arg;
@@ -2380,5 +2345,5 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
     grpc_slice_buffer_move_into(read_buffer, &t->read_buffer);
     gpr_free(read_buffer);
   }
-  read_action_begin(exec_ctx, t, GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx, &t->read_action_locked, GRPC_ERROR_NONE);
 }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 6a9200b8db..64ce07b2f7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -1634,10 +1634,11 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
              however -- it might be that we receive a RST_STREAM following this
              and can avoid the extra write */
           GRPC_CHTTP2_STREAM_REF(s, "final_rst");
-          grpc_combiner_execute_finally(
-              exec_ctx, t->combiner,
-              grpc_closure_create(force_client_rst_stream, s), GRPC_ERROR_NONE,
-              false);
+          grpc_closure_sched(
+              exec_ctx, grpc_closure_create(force_client_rst_stream, s,
+                                            grpc_combiner_finally_scheduler(
+                                                t->combiner, false)),
+              GRPC_ERROR_NONE);
         }
         grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false,
                                        GRPC_ERROR_NONE);
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index b727965d43..a52acbacdb 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -212,10 +212,8 @@ struct grpc_chttp2_transport {
 
   grpc_closure write_action_begin_locked;
   grpc_closure write_action;
-  grpc_closure write_action_end;
   grpc_closure write_action_end_locked;
 
-  grpc_closure read_action_begin;
   grpc_closure read_action_locked;
 
   /** incoming read bytes */
@@ -336,10 +334,8 @@ struct grpc_chttp2_transport {
   /** have we scheduled a destructive cleanup? */
   bool destructive_reclaimer_registered;
   /** benign cleanup closure */
-  grpc_closure benign_reclaimer;
   grpc_closure benign_reclaimer_locked;
   /** destructive cleanup closure */
-  grpc_closure destructive_reclaimer;
   grpc_closure destructive_reclaimer_locked;
 };
 
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index afc59f4b12..6f94ccbc87 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -849,16 +849,16 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                            OP_RECV_INITIAL_METADATA)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_INITIAL_METADATA", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
+      grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
                           GRPC_ERROR_CANCELLED, NULL);
     } else if (stream_state->state_callback_received[OP_FAILED]) {
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, stream_op->recv_initial_metadata_ready,
           make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
     } else {
       grpc_chttp2_incoming_metadata_buffer_publish(
           &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata);
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
+      grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
                           GRPC_ERROR_NONE, NULL);
     }
     stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true;
@@ -910,13 +910,13 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_MESSAGE", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
       CRONET_LOG(GPR_DEBUG, "Stream is cancelled.");
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
                           GRPC_ERROR_CANCELLED, NULL);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->state_callback_received[OP_FAILED]) {
       CRONET_LOG(GPR_DEBUG, "Stream failed.");
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, stream_op->recv_message_ready,
           make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@@ -924,7 +924,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     } else if (stream_state->rs.read_stream_closed == true) {
       /* No more data will be received */
       CRONET_LOG(GPR_DEBUG, "read stream closed");
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
                           GRPC_ERROR_NONE, NULL);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
@@ -958,7 +958,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                                         &stream_state->rs.read_slice_buffer, 0);
           *((grpc_byte_buffer **)stream_op->recv_message) =
               (grpc_byte_buffer *)&stream_state->rs.sbs;
-          grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+          grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
                               GRPC_ERROR_NONE, NULL);
           stream_state->state_op_done[OP_RECV_MESSAGE] = true;
           oas->state.state_op_done[OP_RECV_MESSAGE] = true;
@@ -993,7 +993,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                                     &stream_state->rs.read_slice_buffer, 0);
       *((grpc_byte_buffer **)stream_op->recv_message) =
           (grpc_byte_buffer *)&stream_state->rs.sbs;
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+      grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
                           GRPC_ERROR_NONE, NULL);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
@@ -1055,17 +1055,17 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
                            OP_ON_COMPLETE)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_ON_COMPLETE", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
-      grpc_exec_ctx_sched(exec_ctx, stream_op->on_complete,
+      grpc_closure_sched(exec_ctx, stream_op->on_complete,
                           GRPC_ERROR_REF(stream_state->cancel_error), NULL);
     } else if (stream_state->state_callback_received[OP_FAILED]) {
-      grpc_exec_ctx_sched(
+      grpc_closure_sched(
           exec_ctx, stream_op->on_complete,
           make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
     } else {
       /* All actions in this stream_op are complete. Call the on_complete
        * callback
        */
-      grpc_exec_ctx_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE,
+      grpc_closure_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE,
                           NULL);
     }
     oas->state.state_op_done[OP_ON_COMPLETE] = true;
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 1d0b7d4f31..cddd84fcca 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -297,7 +297,8 @@ void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx,
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
   op->cancel_error = GRPC_ERROR_CANCELLED;
-  op->on_complete = grpc_closure_create(destroy_op, op);
+  op->on_complete =
+      grpc_closure_create(destroy_op, op, grpc_schedule_on_exec_ctx);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
 
@@ -307,7 +308,8 @@ void grpc_call_element_send_cancel_with_message(grpc_exec_ctx *exec_ctx,
                                                 grpc_slice *optional_message) {
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
-  op->on_complete = grpc_closure_create(destroy_op, op);
+  op->on_complete =
+      grpc_closure_create(destroy_op, op, grpc_schedule_on_exec_ctx);
   grpc_transport_stream_op_add_cancellation_with_message(op, status,
                                                          optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
@@ -319,7 +321,8 @@ void grpc_call_element_send_close_with_message(grpc_exec_ctx *exec_ctx,
                                                grpc_slice *optional_message) {
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
-  op->on_complete = grpc_closure_create(destroy_op, op);
+  op->on_complete =
+      grpc_closure_create(destroy_op, op, grpc_schedule_on_exec_ctx);
   grpc_transport_stream_op_add_close(op, status, optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 0e336dc330..35455d4908 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -269,8 +269,10 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   /* initialize members */
   grpc_slice_buffer_init(&calld->slices);
   calld->has_compression_algorithm = 0;
-  grpc_closure_init(&calld->got_slice, got_slice, elem);
-  grpc_closure_init(&calld->send_done, send_done, elem);
+  grpc_closure_init(&calld->got_slice, got_slice, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->send_done, send_done, elem,
+                    grpc_schedule_on_exec_ctx);
 
   return GRPC_ERROR_NONE;
 }
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 470ccfea57..902ebf1955 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -123,7 +123,8 @@ static void on_complete(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
 static void inject_on_complete_cb(grpc_deadline_state* deadline_state,
                                   grpc_transport_stream_op* op) {
   deadline_state->next_on_complete = op->on_complete;
-  grpc_closure_init(&deadline_state->on_complete, on_complete, deadline_state);
+  grpc_closure_init(&deadline_state->on_complete, on_complete, deadline_state,
+                    grpc_schedule_on_exec_ctx);
   op->on_complete = &deadline_state->on_complete;
 }
 
@@ -172,8 +173,9 @@ void grpc_deadline_state_start(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
     struct start_timer_after_init_state* state = gpr_malloc(sizeof(*state));
     state->elem = elem;
     state->deadline = deadline;
-    grpc_closure_init(&state->closure, start_timer_after_init, state);
-    grpc_exec_ctx_sched(exec_ctx, &state->closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_init(&state->closure, start_timer_after_init, state,
+                      grpc_schedule_on_exec_ctx);
+    grpc_closure_sched(exec_ctx, &state->closure, GRPC_ERROR_NONE);
   }
 }
 
@@ -290,7 +292,8 @@ static void server_start_transport_stream_op(grpc_exec_ctx* exec_ctx,
       calld->next_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
       calld->recv_initial_metadata = op->recv_initial_metadata;
       grpc_closure_init(&calld->recv_initial_metadata_ready,
-                        recv_initial_metadata_ready, elem);
+                        recv_initial_metadata_ready, elem,
+                        grpc_schedule_on_exec_ctx);
       op->recv_initial_metadata_ready = &calld->recv_initial_metadata_ready;
     }
     // Make sure we know when the call is complete, so that we can cancel
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index 23edc826ca..ff827527b3 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -165,7 +165,7 @@ static bool call_next_handshaker_locked(grpc_exec_ctx* exec_ctx,
     // Cancel deadline timer, since we're invoking the on_handshake_done
     // callback now.
     grpc_timer_cancel(exec_ctx, &mgr->deadline_timer);
-    grpc_exec_ctx_sched(exec_ctx, &mgr->on_handshake_done, error, NULL);
+    grpc_closure_sched(exec_ctx, &mgr->on_handshake_done, error);
     mgr->shutdown = true;
   } else {
     grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index],
@@ -218,8 +218,10 @@ void grpc_handshake_manager_do_handshake(
   grpc_slice_buffer_init(mgr->args.read_buffer);
   // Initialize state needed for calling handshakers.
   mgr->acceptor = acceptor;
-  grpc_closure_init(&mgr->call_next_handshaker, call_next_handshaker, mgr);
-  grpc_closure_init(&mgr->on_handshake_done, on_handshake_done, &mgr->args);
+  grpc_closure_init(&mgr->call_next_handshaker, call_next_handshaker, mgr,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&mgr->on_handshake_done, on_handshake_done, &mgr->args,
+                    grpc_schedule_on_exec_ctx);
   // Start deadline timer, which owns a ref.
   gpr_ref(&mgr->refs);
   grpc_timer_init(exec_ctx, &mgr->deadline_timer,
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 1a2d08dda5..c37cab3939 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -352,12 +352,17 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   calld->send_message_blocked = false;
   grpc_slice_buffer_init(&calld->slices);
   grpc_closure_init(&calld->hc_on_recv_initial_metadata,
-                    hc_on_recv_initial_metadata, elem);
+                    hc_on_recv_initial_metadata, elem,
+                    grpc_schedule_on_exec_ctx);
   grpc_closure_init(&calld->hc_on_recv_trailing_metadata,
-                    hc_on_recv_trailing_metadata, elem);
-  grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem);
-  grpc_closure_init(&calld->got_slice, got_slice, elem);
-  grpc_closure_init(&calld->send_done, send_done, elem);
+                    hc_on_recv_trailing_metadata, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->got_slice, got_slice, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->send_done, send_done, elem,
+                    grpc_schedule_on_exec_ctx);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index a5134ee21b..a6d720530a 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -334,9 +334,12 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   call_data *calld = elem->call_data;
   /* initialize members */
   memset(calld, 0, sizeof(*calld));
-  grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem);
-  grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem);
-  grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem);
+  grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem,
+                    grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&calld->read_slice_buffer);
   return GRPC_ERROR_NONE;
 }
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index f05c789010..b5e882de52 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -124,7 +124,7 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
     gpr_free(message_string);
   }
   // Invoke the next callback.
-  grpc_exec_ctx_sched(exec_ctx, calld->next_recv_message_ready, error, NULL);
+  grpc_closure_sched(exec_ctx, calld->next_recv_message_ready, error);
 }
 
 // Start transport stream op.
@@ -160,7 +160,8 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
   channel_data* chand = elem->channel_data;
   call_data* calld = elem->call_data;
   calld->next_recv_message_ready = NULL;
-  grpc_closure_init(&calld->recv_message_ready, recv_message_ready, elem);
+  grpc_closure_init(&calld->recv_message_ready, recv_message_ready, elem,
+                    grpc_schedule_on_exec_ctx);
   // Get max sizes from channel data, then merge in per-method config values.
   // Note: Per-method config is only available on the client, so we
   // apply the max request size to the send limit and the max response
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index 1035f31109..581a74b73f 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -103,7 +103,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
                    grpc_error *error) {
   grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
                                            req->context->pollset_set);
-  grpc_exec_ctx_sched(exec_ctx, req->on_done, error, NULL);
+  grpc_closure_sched(exec_ctx, req->on_done, error);
   grpc_http_parser_destroy(&req->parser);
   if (req->addresses != NULL) {
     grpc_resolved_addresses_destroy(req->addresses);
@@ -224,7 +224,8 @@ static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req,
     return;
   }
   addr = &req->addresses->addrs[req->next_address++];
-  grpc_closure_init(&req->connected, on_connected, req);
+  grpc_closure_init(&req->connected, on_connected, req,
+                    grpc_schedule_on_exec_ctx);
   grpc_arg arg;
   arg.key = GRPC_ARG_RESOURCE_QUOTA;
   arg.type = GRPC_ARG_POINTER;
@@ -266,8 +267,9 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
   req->pollent = pollent;
   req->overall_error = GRPC_ERROR_NONE;
   req->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
-  grpc_closure_init(&req->on_read, on_read, req);
-  grpc_closure_init(&req->done_write, done_write, req);
+  grpc_closure_init(&req->on_read, on_read, req, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&req->done_write, done_write, req,
+                    grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&req->incoming);
   grpc_slice_buffer_init(&req->outgoing);
   grpc_iomgr_register_object(&req->iomgr_obj, name);
@@ -277,9 +279,11 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(pollent);
   grpc_polling_entity_add_to_pollset_set(exec_ctx, req->pollent,
                                          req->context->pollset_set);
-  grpc_resolve_address(exec_ctx, request->host, req->handshaker->default_port,
-                       req->context->pollset_set,
-                       grpc_closure_create(on_resolved, req), &req->addresses);
+  grpc_resolve_address(
+      exec_ctx, request->host, req->handshaker->default_port,
+      req->context->pollset_set,
+      grpc_closure_create(on_resolved, req, grpc_schedule_on_exec_ctx),
+      &req->addresses);
 }
 
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 14cdb1dab3..6b197c2e35 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -96,7 +96,7 @@ static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
     error = GRPC_ERROR_CREATE(msg);
     gpr_free(msg);
   }
-  grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
+  grpc_closure_sched(exec_ctx, on_peer_checked, error);
   tsi_peer_destruct(&peer);
 }
 
diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c
index c6ddc76732..da0ec878a3 100644
--- a/src/core/lib/iomgr/closure.c
+++ b/src/core/lib/iomgr/closure.c
@@ -37,10 +37,13 @@
 
 #include "src/core/lib/profiling/timers.h"
 
-void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
-                       void *cb_arg) {
+grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
+                                void *cb_arg,
+                                grpc_closure_scheduler *scheduler) {
   closure->cb = cb;
   closure->cb_arg = cb_arg;
+  closure->scheduler = scheduler;
+  return closure;
 }
 
 void grpc_closure_list_init(grpc_closure_list *closure_list) {
@@ -105,11 +108,12 @@ static void closure_wrapper(grpc_exec_ctx *exec_ctx, void *arg,
   cb(exec_ctx, cb_arg, error);
 }
 
-grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) {
+grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
+                                  grpc_closure_scheduler *scheduler) {
   wrapped_closure *wc = gpr_malloc(sizeof(*wc));
   wc->cb = cb;
   wc->cb_arg = cb_arg;
-  grpc_closure_init(&wc->wrapper, closure_wrapper, wc);
+  grpc_closure_init(&wc->wrapper, closure_wrapper, wc, scheduler);
   return &wc->wrapper;
 }
 
@@ -117,8 +121,30 @@ void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c,
                       grpc_error *error) {
   GPR_TIMER_BEGIN("grpc_closure_run", 0);
   if (c != NULL) {
-    c->cb(exec_ctx, c->cb_arg, error);
+    c->scheduler->vtable->run(exec_ctx, c, error);
+  } else {
+    GRPC_ERROR_UNREF(error);
   }
-  GRPC_ERROR_UNREF(error);
   GPR_TIMER_END("grpc_closure_run", 0);
 }
+
+void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
+                        grpc_error *error) {
+  GPR_TIMER_BEGIN("grpc_closure_sched", 0);
+  if (c != NULL) {
+    c->scheduler->vtable->sched(exec_ctx, c, error);
+  } else {
+    GRPC_ERROR_UNREF(error);
+  }
+  GPR_TIMER_END("grpc_closure_sched", 0);
+}
+
+void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
+  grpc_closure *c = list->head;
+  while (c != NULL) {
+    grpc_closure *next = c->next_data.next;
+    c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);
+    c = next;
+  }
+  list->head = list->tail = NULL;
+}
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2b4b271eaa..1b5d9b20a0 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -59,6 +59,22 @@ typedef struct grpc_closure_list {
 typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg,
                                    grpc_error *error);
 
+typedef struct grpc_closure_scheduler grpc_closure_scheduler;
+
+typedef struct grpc_closure_scheduler_vtable {
+  /* NOTE: for all these functions, closure->scheduler == the scheduler that was
+           used to find this vtable */
+  void (*run)(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+              grpc_error *error);
+  void (*sched)(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                grpc_error *error);
+} grpc_closure_scheduler_vtable;
+
+/** Abstract type that can schedule closures for execution */
+struct grpc_closure_scheduler {
+  const grpc_closure_scheduler_vtable *vtable;
+};
+
 /** A closure over a grpc_iomgr_cb_func. */
 struct grpc_closure {
   /** Once queued, next indicates the next queued closure; before then, scratch
@@ -75,6 +91,10 @@ struct grpc_closure {
   /** Arguments to be passed to "cb". */
   void *cb_arg;
 
+  /** Scheduler to schedule against: NULL to schedule against current execution
+      context */
+  grpc_closure_scheduler *scheduler;
+
   /** Once queued, the result of the closure. Before then: scratch space */
   union {
     grpc_error *error;
@@ -82,12 +102,14 @@ struct grpc_closure {
   } error_data;
 };
 
-/** Initializes \a closure with \a cb and \a cb_arg. */
-void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
-                       void *cb_arg);
+/** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
+grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
+                                void *cb_arg,
+                                grpc_closure_scheduler *scheduler);
 
 /* Create a heap allocated closure: try to avoid except for very rare events */
-grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg);
+grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
+                                  grpc_closure_scheduler *scheduler);
 
 #define GRPC_CLOSURE_LIST_INIT \
   { NULL, NULL }
@@ -115,4 +137,13 @@ bool grpc_closure_list_empty(grpc_closure_list list);
 void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                       grpc_error *error);
 
+/** Schedule a closure to be run. Does not need to be run from a safe point. */
+void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                        grpc_error *error);
+
+/** Schedule all closures in a list to be run. Does not need to be run from a
+ * safe point. */
+void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx,
+                             grpc_closure_list *closure_list);
+
 #endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index cfc67020ae..c26a73b2b7 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -56,6 +56,10 @@ int grpc_combiner_trace = 0;
 struct grpc_combiner {
   grpc_combiner *next_combiner_on_this_exec_ctx;
   grpc_workqueue *optional_workqueue;
+  grpc_closure_scheduler uncovered_scheduler;
+  grpc_closure_scheduler covered_scheduler;
+  grpc_closure_scheduler uncovered_finally_scheduler;
+  grpc_closure_scheduler covered_finally_scheduler;
   gpr_mpscq queue;
   // state is:
   // lower bit - zero if orphaned (STATE_UNORPHANED)
@@ -70,6 +74,26 @@ struct grpc_combiner {
   grpc_closure offload;
 };
 
+static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx,
+                                    grpc_closure *closure, grpc_error *error);
+static void combiner_exec_covered(grpc_exec_ctx *exec_ctx,
+                                  grpc_closure *closure, grpc_error *error);
+static void combiner_finally_exec_uncovered(grpc_exec_ctx *exec_ctx,
+                                            grpc_closure *closure,
+                                            grpc_error *error);
+static void combiner_finally_exec_covered(grpc_exec_ctx *exec_ctx,
+                                          grpc_closure *closure,
+                                          grpc_error *error);
+
+static const grpc_closure_scheduler_vtable scheduler_uncovered = {
+    combiner_exec_uncovered, combiner_exec_uncovered};
+static const grpc_closure_scheduler_vtable scheduler_covered = {
+    combiner_exec_covered, combiner_exec_covered};
+static const grpc_closure_scheduler_vtable finally_scheduler_uncovered = {
+    combiner_finally_exec_uncovered, combiner_finally_exec_uncovered};
+static const grpc_closure_scheduler_vtable finally_scheduler_covered = {
+    combiner_finally_exec_covered, combiner_finally_exec_covered};
+
 static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
 
 typedef struct {
@@ -102,11 +126,16 @@ grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) {
   lock->time_to_execute_final_list = false;
   lock->optional_workqueue = optional_workqueue;
   lock->final_list_covered_by_poller = false;
+  lock->uncovered_scheduler.vtable = &scheduler_uncovered;
+  lock->covered_scheduler.vtable = &scheduler_covered;
+  lock->uncovered_finally_scheduler.vtable = &finally_scheduler_uncovered;
+  lock->covered_finally_scheduler.vtable = &finally_scheduler_covered;
   gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED);
   gpr_atm_no_barrier_store(&lock->elements_covered_by_poller, 0);
   gpr_mpscq_init(&lock->queue);
   grpc_closure_list_init(&lock->final_list);
-  grpc_closure_init(&lock->offload, offload, lock);
+  grpc_closure_init(&lock->offload, offload, lock,
+                    grpc_workqueue_scheduler(lock->optional_workqueue));
   GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p create", lock));
   return lock;
 }
@@ -148,9 +177,9 @@ static void push_first_on_exec_ctx(grpc_exec_ctx *exec_ctx,
   }
 }
 
-void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
-                           grpc_closure *cl, grpc_error *error,
-                           bool covered_by_poller) {
+static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
+                          grpc_closure *cl, grpc_error *error,
+                          bool covered_by_poller) {
   GPR_TIMER_BEGIN("combiner.execute", 0);
   gpr_atm last = gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT);
   GRPC_COMBINER_TRACE(gpr_log(
@@ -171,6 +200,24 @@ void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
   GPR_TIMER_END("combiner.execute", 0);
 }
 
+#define COMBINER_FROM_CLOSURE_SCHEDULER(closure, scheduler_name) \
+  ((grpc_combiner *)(((char *)((closure)->scheduler)) -          \
+                     offsetof(grpc_combiner, scheduler_name)))
+
+static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
+                                    grpc_error *error) {
+  combiner_exec(exec_ctx,
+                COMBINER_FROM_CLOSURE_SCHEDULER(cl, uncovered_scheduler), cl,
+                error, false);
+}
+
+static void combiner_exec_covered(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
+                                  grpc_error *error) {
+  combiner_exec(exec_ctx,
+                COMBINER_FROM_CLOSURE_SCHEDULER(cl, covered_scheduler), cl,
+                error, true);
+}
+
 static void move_next(grpc_exec_ctx *exec_ctx) {
   exec_ctx->active_combiner =
       exec_ctx->active_combiner->next_combiner_on_this_exec_ctx;
@@ -188,8 +235,7 @@ static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
   move_next(exec_ctx);
   GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload --> %p", lock,
                               lock->optional_workqueue));
-  grpc_workqueue_enqueue(exec_ctx, lock->optional_workqueue, &lock->offload,
-                         GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx, &lock->offload, GRPC_ERROR_NONE);
 }
 
 bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
@@ -312,23 +358,22 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
 }
 
 static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure,
-                            grpc_error *error) {
-  grpc_combiner_execute_finally(exec_ctx, exec_ctx->active_combiner, closure,
-                                GRPC_ERROR_REF(error), false);
-}
+                            grpc_error *error);
 
-void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
-                                   grpc_closure *closure, grpc_error *error,
-                                   bool covered_by_poller) {
+static void combiner_execute_finally(grpc_exec_ctx *exec_ctx,
+                                     grpc_combiner *lock, grpc_closure *closure,
+                                     grpc_error *error,
+                                     bool covered_by_poller) {
   GRPC_COMBINER_TRACE(gpr_log(
       GPR_DEBUG, "C:%p grpc_combiner_execute_finally c=%p; ac=%p; cov=%d", lock,
       closure, exec_ctx->active_combiner, covered_by_poller));
   GPR_TIMER_BEGIN("combiner.execute_finally", 0);
   if (exec_ctx->active_combiner != lock) {
     GPR_TIMER_MARK("slowpath", 0);
-    grpc_combiner_execute(exec_ctx, lock,
-                          grpc_closure_create(enqueue_finally, closure), error,
-                          false);
+    grpc_closure_sched(
+        exec_ctx, grpc_closure_create(enqueue_finally, closure,
+                                      grpc_combiner_scheduler(lock, false)),
+        error);
     GPR_TIMER_END("combiner.execute_finally", 0);
     return;
   }
@@ -342,3 +387,36 @@ void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
   grpc_closure_list_append(&lock->final_list, closure, error);
   GPR_TIMER_END("combiner.execute_finally", 0);
 }
+
+static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure,
+                            grpc_error *error) {
+  combiner_execute_finally(exec_ctx, exec_ctx->active_combiner, closure,
+                           GRPC_ERROR_REF(error), false);
+}
+
+static void combiner_finally_exec_uncovered(grpc_exec_ctx *exec_ctx,
+                                            grpc_closure *cl,
+                                            grpc_error *error) {
+  combiner_execute_finally(exec_ctx, COMBINER_FROM_CLOSURE_SCHEDULER(
+                                         cl, uncovered_finally_scheduler),
+                           cl, error, false);
+}
+
+static void combiner_finally_exec_covered(grpc_exec_ctx *exec_ctx,
+                                          grpc_closure *cl, grpc_error *error) {
+  combiner_execute_finally(
+      exec_ctx, COMBINER_FROM_CLOSURE_SCHEDULER(cl, covered_finally_scheduler),
+      cl, error, true);
+}
+
+grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *combiner,
+                                                bool covered_by_poller) {
+  return covered_by_poller ? &combiner->covered_scheduler
+                           : &combiner->uncovered_scheduler;
+}
+
+grpc_closure_scheduler *grpc_combiner_finally_scheduler(
+    grpc_combiner *combiner, bool covered_by_poller) {
+  return covered_by_poller ? &combiner->covered_finally_scheduler
+                           : &combiner->uncovered_finally_scheduler;
+}
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index d04eeed83a..81dff85d40 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -50,14 +50,12 @@
 grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue);
 // Destroy the lock
 void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock);
-// Execute \a action within the lock.
-void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
-                           grpc_closure *closure, grpc_error *error,
-                           bool covered_by_poller);
-// Execute \a action within the lock just prior to unlocking.
-void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
-                                   grpc_closure *closure, grpc_error *error,
-                                   bool covered_by_poller);
+// Fetch a scheduler to schedule closures against
+grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *lock,
+                                                bool covered_by_poller);
+// Scheduler to execute \a action within the lock just prior to unlocking.
+grpc_closure_scheduler *grpc_combiner_finally_scheduler(grpc_combiner *lock,
+                                                        bool covered_by_poller);
 
 bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx);
 
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 1b15e0eb4f..ac94d2e634 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -202,6 +202,8 @@ static void fd_global_shutdown(void);
 
 /* This is also used as grpc_workqueue (by directly casing it) */
 typedef struct polling_island {
+  grpc_closure_scheduler workqueue_scheduler;
+
   gpr_mu mu;
   /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement
      the refcount.
@@ -305,6 +307,8 @@ static __thread polling_island *g_current_thread_polling_island;
 
 /* Forward declaration */
 static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi);
+static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                              grpc_error *error);
 
 #ifdef GRPC_TSAN
 /* Currently TSAN may incorrectly flag data races between epoll_ctl and
@@ -317,6 +321,9 @@ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi);
 gpr_atm g_epoll_sync;
 #endif /* defined(GRPC_TSAN) */
 
+static const grpc_closure_scheduler_vtable workqueue_scheduler_vtable = {
+    workqueue_enqueue, workqueue_enqueue};
+
 static void pi_add_ref(polling_island *pi);
 static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi);
 
@@ -529,6 +536,7 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
   *error = GRPC_ERROR_NONE;
 
   pi = gpr_malloc(sizeof(*pi));
+  pi->workqueue_scheduler.vtable = &workqueue_scheduler_vtable;
   gpr_mu_init(&pi->mu);
   pi->fd_cnt = 0;
   pi->fd_capacity = 0;
@@ -800,10 +808,10 @@ static polling_island *polling_island_merge(polling_island *p,
   return q;
 }
 
-static void workqueue_enqueue(grpc_exec_ctx *exec_ctx,
-                              grpc_workqueue *workqueue, grpc_closure *closure,
+static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                               grpc_error *error) {
   GPR_TIMER_BEGIN("workqueue.enqueue", 0);
+  grpc_workqueue *workqueue = (grpc_workqueue *)closure->scheduler;
   /* take a ref to the workqueue: otherwise it can happen that whatever events
    * this kicks off ends up destroying the workqueue before this function
    * completes */
@@ -820,6 +828,11 @@ static void workqueue_enqueue(grpc_exec_ctx *exec_ctx,
   GPR_TIMER_END("workqueue.enqueue", 0);
 }
 
+static grpc_closure_scheduler *workqueue_scheduler(grpc_workqueue *workqueue) {
+  polling_island *pi = (polling_island *)workqueue;
+  return &pi->workqueue_scheduler;
+}
+
 static grpc_error *polling_island_global_init() {
   grpc_error *error = GRPC_ERROR_NONE;
 
@@ -1030,8 +1043,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
     fd->po.pi = NULL;
   }
 
-  grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error),
-                      NULL);
+  grpc_closure_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error));
 
   gpr_mu_unlock(&fd->po.mu);
   UNREF_BY(fd, 2, reason); /* Drop the reference */
@@ -1057,16 +1069,14 @@ static grpc_error *fd_shutdown_error(bool shutdown) {
 static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                              grpc_closure **st, grpc_closure *closure) {
   if (fd->shutdown) {
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
   } else if (*st == CLOSURE_NOT_READY) {
     /* not ready ==> switch to a waiting state by setting the closure */
     *st = closure;
   } else if (*st == CLOSURE_READY) {
     /* already ready ==> queue the closure to run immediately */
     *st = CLOSURE_NOT_READY;
-    grpc_exec_ctx_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown));
   } else {
     /* upcallptr was set to a different closure.  This is an error! */
     gpr_log(GPR_ERROR,
@@ -1088,7 +1098,7 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
     return 0;
   } else {
     /* waiting ==> queue closure */
-    grpc_exec_ctx_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown), NULL);
+    grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown));
     *st = CLOSURE_NOT_READY;
     return 1;
   }
@@ -1359,7 +1369,7 @@ static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
 
   /* Release the ref and set pollset->po.pi to NULL */
   pollset_release_polling_island(exec_ctx, pollset, "ps_shutdown");
-  grpc_exec_ctx_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE);
 }
 
 /* pollset->po.mu lock must be held by the caller before calling this */
@@ -1959,7 +1969,7 @@ static const grpc_event_engine_vtable vtable = {
 
     .workqueue_ref = workqueue_ref,
     .workqueue_unref = workqueue_unref,
-    .workqueue_enqueue = workqueue_enqueue,
+    .workqueue_scheduler = workqueue_scheduler,
 
     .shutdown_engine = shutdown_engine,
 };
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 21b28e5554..5bc5621443 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -397,7 +397,7 @@ static void close_fd_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
   if (!fd->released) {
     close(fd->fd);
   }
-  grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_NONE);
 }
 
 static int fd_wrapped_fd(grpc_fd *fd) {
@@ -457,16 +457,14 @@ static grpc_error *fd_shutdown_error(bool shutdown) {
 static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                              grpc_closure **st, grpc_closure *closure) {
   if (fd->shutdown) {
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
   } else if (*st == CLOSURE_NOT_READY) {
     /* not ready ==> switch to a waiting state by setting the closure */
     *st = closure;
   } else if (*st == CLOSURE_READY) {
     /* already ready ==> queue the closure to run immediately */
     *st = CLOSURE_NOT_READY;
-    grpc_exec_ctx_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown));
     maybe_wake_one_watcher_locked(fd);
   } else {
     /* upcallptr was set to a different closure.  This is an error! */
@@ -489,7 +487,7 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
     return 0;
   } else {
     /* waiting ==> queue closure */
-    grpc_exec_ctx_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown), NULL);
+    grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown));
     *st = CLOSURE_NOT_READY;
     return 1;
   }
@@ -852,7 +850,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
     GRPC_FD_UNREF(pollset->fds[i], "multipoller");
   }
   pollset->fd_count = 0;
-  grpc_exec_ctx_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE);
 }
 
 static void work_combine_error(grpc_error **composite, grpc_error *error) {
@@ -901,7 +899,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
   if (!pollset_has_workers(pollset) &&
       !grpc_closure_list_empty(pollset->idle_jobs)) {
     GPR_TIMER_MARK("pollset_work.idle_jobs", 0);
-    grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+    grpc_closure_list_sched(exec_ctx, &pollset->idle_jobs);
     goto done;
   }
   /* If we're shutting down then we don't execute any extended work */
@@ -1081,7 +1079,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
        * TODO(dklempner): Can we refactor the shutdown logic to avoid this? */
       gpr_mu_lock(&pollset->mu);
     } else if (!grpc_closure_list_empty(pollset->idle_jobs)) {
-      grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+      grpc_closure_list_sched(exec_ctx, &pollset->idle_jobs);
       gpr_mu_unlock(&pollset->mu);
       grpc_exec_ctx_flush(exec_ctx);
       gpr_mu_lock(&pollset->mu);
@@ -1100,7 +1098,7 @@ static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
   pollset->shutdown_done = closure;
   pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
   if (!pollset_has_workers(pollset)) {
-    grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+    grpc_closure_list_sched(exec_ctx, &pollset->idle_jobs);
   }
   if (!pollset->called_shutdown && !pollset_has_workers(pollset)) {
     pollset->called_shutdown = 1;
@@ -1288,10 +1286,8 @@ static void workqueue_unref(grpc_exec_ctx *exec_ctx,
                             grpc_workqueue *workqueue) {}
 #endif
 
-static void workqueue_enqueue(grpc_exec_ctx *exec_ctx,
-                              grpc_workqueue *workqueue, grpc_closure *closure,
-                              grpc_error *error) {
-  grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+static grpc_closure_scheduler *workqueue_scheduler(grpc_workqueue *workqueue) {
+  return grpc_schedule_on_exec_ctx;
 }
 
 /*******************************************************************************
@@ -1534,7 +1530,7 @@ static const grpc_event_engine_vtable vtable = {
 
     .workqueue_ref = workqueue_ref,
     .workqueue_unref = workqueue_unref,
-    .workqueue_enqueue = workqueue_enqueue,
+    .workqueue_scheduler = workqueue_scheduler,
 
     .shutdown_engine = shutdown_engine,
 };
diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c
index ab139895fd..2975d619e1 100644
--- a/src/core/lib/iomgr/ev_posix.c
+++ b/src/core/lib/iomgr/ev_posix.c
@@ -275,9 +275,8 @@ void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {
 }
 #endif
 
-void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
-                            grpc_closure *closure, grpc_error *error) {
-  g_event_engine->workqueue_enqueue(exec_ctx, workqueue, closure, error);
+grpc_closure_scheduler *grpc_workqueue_scheduler(grpc_workqueue *workqueue) {
+  return g_event_engine->workqueue_scheduler(workqueue);
 }
 
 #endif  // GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index cb5832539d..1068a4bad5 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -106,8 +106,7 @@ typedef struct grpc_event_engine_vtable {
   grpc_workqueue *(*workqueue_ref)(grpc_workqueue *workqueue);
   void (*workqueue_unref)(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue);
 #endif
-  void (*workqueue_enqueue)(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
-                            grpc_closure *closure, grpc_error *error);
+  grpc_closure_scheduler *(*workqueue_scheduler)(grpc_workqueue *workqueue);
 } grpc_event_engine_vtable;
 
 void grpc_event_engine_init(void);
diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c
index 604713e578..c243bc803f 100644
--- a/src/core/lib/iomgr/exec_ctx.c
+++ b/src/core/lib/iomgr/exec_ctx.c
@@ -57,7 +57,6 @@ bool grpc_always_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored) {
   return true;
 }
 
-#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
 bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
   bool did_something = 0;
   GPR_TIMER_BEGIN("grpc_exec_ctx_flush", 0);
@@ -76,30 +75,6 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
     }
   }
   GPR_ASSERT(exec_ctx->active_combiner == NULL);
-  if (exec_ctx->stealing_from_workqueue != NULL) {
-    if (grpc_exec_ctx_ready_to_finish(exec_ctx)) {
-      grpc_workqueue_enqueue(exec_ctx, exec_ctx->stealing_from_workqueue,
-                             exec_ctx->stolen_closure,
-                             exec_ctx->stolen_closure->error_data.error);
-      GRPC_WORKQUEUE_UNREF(exec_ctx, exec_ctx->stealing_from_workqueue,
-                           "exec_ctx_sched");
-      exec_ctx->stealing_from_workqueue = NULL;
-      exec_ctx->stolen_closure = NULL;
-    } else {
-      grpc_closure *c = exec_ctx->stolen_closure;
-      GRPC_WORKQUEUE_UNREF(exec_ctx, exec_ctx->stealing_from_workqueue,
-                           "exec_ctx_sched");
-      exec_ctx->stealing_from_workqueue = NULL;
-      exec_ctx->stolen_closure = NULL;
-      grpc_error *error = c->error_data.error;
-      GPR_TIMER_BEGIN("grpc_exec_ctx_flush.stolen_cb", 0);
-      c->cb(exec_ctx, c->cb_arg, error);
-      GRPC_ERROR_UNREF(error);
-      GPR_TIMER_END("grpc_exec_ctx_flush.stolen_cb", 0);
-      grpc_exec_ctx_flush(exec_ctx);
-      did_something = true;
-    }
-  }
   GPR_TIMER_END("grpc_exec_ctx_flush", 0);
   return did_something;
 }
@@ -109,104 +84,21 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {
   grpc_exec_ctx_flush(exec_ctx);
 }
 
-void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
-                         grpc_error *error,
-                         grpc_workqueue *offload_target_or_null) {
-  GPR_TIMER_BEGIN("grpc_exec_ctx_sched", 0);
-  if (offload_target_or_null == NULL) {
-    grpc_closure_list_append(&exec_ctx->closure_list, closure, error);
-  } else if (exec_ctx->stealing_from_workqueue == NULL) {
-    exec_ctx->stealing_from_workqueue = offload_target_or_null;
-    closure->error_data.error = error;
-    exec_ctx->stolen_closure = closure;
-  } else if (exec_ctx->stealing_from_workqueue != offload_target_or_null) {
-    grpc_workqueue_enqueue(exec_ctx, offload_target_or_null, closure, error);
-    GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched");
-  } else { /* stealing_from_workqueue == offload_target_or_null */
-    grpc_workqueue_enqueue(exec_ctx, offload_target_or_null,
-                           exec_ctx->stolen_closure,
-                           exec_ctx->stolen_closure->error_data.error);
-    closure->error_data.error = error;
-    exec_ctx->stolen_closure = closure;
-    GRPC_WORKQUEUE_UNREF(exec_ctx, offload_target_or_null, "exec_ctx_sched");
-  }
-  GPR_TIMER_END("grpc_exec_ctx_sched", 0);
+static void exec_ctx_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                         grpc_error *error) {
+  closure->cb(exec_ctx, closure->cb_arg, error);
+  GRPC_ERROR_UNREF(error);
 }
 
-void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx,
-                                grpc_closure_list *list,
-                                grpc_workqueue *offload_target_or_null) {
-  grpc_closure_list_move(list, &exec_ctx->closure_list);
+static void exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                           grpc_error *error) {
+  grpc_closure_list_append(&exec_ctx->closure_list, closure, error);
 }
 
 void grpc_exec_ctx_global_init(void) {}
 void grpc_exec_ctx_global_shutdown(void) {}
-#else
-static gpr_mu g_mu;
-static gpr_cv g_cv;
-static int g_threads = 0;
-
-static void run_closure(void *arg) {
-  grpc_closure *closure = arg;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  closure->cb(&exec_ctx, closure->cb_arg, (closure->final_data & 1) != 0);
-  grpc_exec_ctx_finish(&exec_ctx);
-  gpr_mu_lock(&g_mu);
-  if (--g_threads == 0) {
-    gpr_cv_signal(&g_cv);
-  }
-  gpr_mu_unlock(&g_mu);
-}
-
-static void start_closure(grpc_closure *closure) {
-  gpr_thd_id id;
-  gpr_mu_lock(&g_mu);
-  g_threads++;
-  gpr_mu_unlock(&g_mu);
-  gpr_thd_new(&id, run_closure, closure, NULL);
-}
-
-bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { return false; }
-
-void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {}
 
-void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
-                           bool success,
-                           grpc_workqueue *offload_target_or_null) {
-  GPR_ASSERT(offload_target_or_null == NULL);
-  if (closure == NULL) return;
-  closure->final_data = success;
-  start_closure(closure);
-}
-
-void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx,
-                                grpc_closure_list *list,
-                                grpc_workqueue *offload_target_or_null) {
-  GPR_ASSERT(offload_target_or_null == NULL);
-  if (list == NULL) return;
-  grpc_closure *p = list->head;
-  while (p) {
-    grpc_closure *start = p;
-    p = grpc_closure_next(start);
-    start_closure(start);
-  }
-  grpc_closure_list r = GRPC_CLOSURE_LIST_INIT;
-  *list = r;
-}
-
-void grpc_exec_ctx_global_init(void) {
-  gpr_mu_init(&g_mu);
-  gpr_cv_init(&g_cv);
-}
-
-void grpc_exec_ctx_global_shutdown(void) {
-  gpr_mu_lock(&g_mu);
-  while (g_threads != 0) {
-    gpr_cv_wait(&g_cv, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
-  }
-  gpr_mu_unlock(&g_mu);
-
-  gpr_mu_destroy(&g_mu);
-  gpr_cv_destroy(&g_cv);
-}
-#endif
+static const grpc_closure_scheduler_vtable exec_ctx_scheduler_vtable = {
+    exec_ctx_run, exec_ctx_sched};
+static grpc_closure_scheduler exec_ctx_scheduler = {&exec_ctx_scheduler_vtable};
+grpc_closure_scheduler *grpc_schedule_on_exec_ctx = &exec_ctx_scheduler;
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index 7e50cb9825..e566f1b3e8 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -66,17 +66,6 @@ typedef struct grpc_combiner grpc_combiner;
 #ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
 struct grpc_exec_ctx {
   grpc_closure_list closure_list;
-  /** The workqueue we're stealing work from.
-      As items are queued to the execution context, we try to steal one
-      workqueue item and execute it inline (assuming the exec_ctx is not
-      finished) - doing so does not invalidate the workqueue's contract, and
-      provides a small latency win in cases where we get a hit */
-  grpc_workqueue *stealing_from_workqueue;
-  /** The workqueue item that was stolen from the workqueue above. When new
-      items are scheduled to be offloaded to that workqueue, we need to update
-      this like a 1-deep fifo to maintain the invariant that workqueue items
-      queued by one thread are started in order */
-  grpc_closure *stolen_closure;
   /** currently active combiner: updated only via combiner.c */
   grpc_combiner *active_combiner;
   /** last active combiner in the active combiner list */
@@ -89,10 +78,7 @@ struct grpc_exec_ctx {
 /* initializer for grpc_exec_ctx:
    prefer to use GRPC_EXEC_CTX_INIT whenever possible */
 #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \
-  {                                                                          \
-    GRPC_CLOSURE_LIST_INIT, NULL, NULL, NULL, NULL, false, finish_check_arg, \
-        finish_check                                                         \
-  }
+  { GRPC_CLOSURE_LIST_INIT, NULL, NULL, false, finish_check_arg, finish_check }
 #else
 struct grpc_exec_ctx {
   bool cached_ready_to_finish;
@@ -108,6 +94,8 @@ struct grpc_exec_ctx {
 #define GRPC_EXEC_CTX_INIT \
   GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(grpc_always_ready_to_finish, NULL)
 
+extern grpc_closure_scheduler *grpc_schedule_on_exec_ctx;
+
 /** Flush any work that has been enqueued onto this grpc_exec_ctx.
  *  Caller must guarantee that no interfering locks are held.
  *  Returns true if work was performed, false otherwise. */
@@ -115,14 +103,6 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx);
 /** Finish any pending work for a grpc_exec_ctx. Must be called before
  *  the instance is destroyed, or work may be lost. */
 void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx);
-/** Add a closure to be executed in the future.
-    If \a offload_target_or_null is NULL, the closure will be executed at the
-    next exec_ctx.{finish,flush} point.
-    If \a offload_target_or_null is non-NULL, the closure will be scheduled
-    against the workqueue, and a reference to the workqueue will be consumed. */
-void grpc_exec_ctx_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
-                         grpc_error *error,
-                         grpc_workqueue *offload_target_or_null);
 /** Returns true if we'd like to leave this execution context as soon as
     possible: useful for deciding whether to do something more or not depending
     on outside context */
@@ -131,11 +111,6 @@ bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx *exec_ctx);
 bool grpc_never_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored);
 /** A finish check that is always ready to finish */
 bool grpc_always_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored);
-/** Add a list of closures to be executed at the next flush/finish point.
- *  Leaves \a list empty. */
-void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx,
-                                grpc_closure_list *list,
-                                grpc_workqueue *offload_target_or_null);
 
 void grpc_exec_ctx_global_init(void);
 
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 8d7535d6fe..37a7142792 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -77,7 +77,7 @@ static void closure_exec_thread_func(void *ignored) {
       gpr_mu_unlock(&g_executor.mu);
       break;
     } else {
-      grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
+      grpc_closure_list_sched(&exec_ctx, &g_executor.closures);
     }
     gpr_mu_unlock(&g_executor.mu);
     grpc_exec_ctx_flush(&exec_ctx);
@@ -112,7 +112,8 @@ static void maybe_spawn_locked() {
   g_executor.pending_join = 1;
 }
 
-void grpc_executor_push(grpc_closure *closure, grpc_error *error) {
+static void executor_push(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                          grpc_error *error) {
   gpr_mu_lock(&g_executor.mu);
   if (g_executor.shutting_down == 0) {
     grpc_closure_list_append(&g_executor.closures, closure, error);
@@ -133,7 +134,7 @@ void grpc_executor_shutdown() {
    * list below because we aren't accepting new work */
 
   /* Execute pending callbacks, some may be performing cleanups */
-  grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
+  grpc_closure_list_sched(&exec_ctx, &g_executor.closures);
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
   if (pending_join) {
@@ -141,3 +142,8 @@ void grpc_executor_shutdown() {
   }
   gpr_mu_destroy(&g_executor.mu);
 }
+
+static const grpc_closure_scheduler_vtable executor_vtable = {executor_push,
+                                                              executor_push};
+static grpc_closure_scheduler executor_scheduler = {&executor_vtable};
+grpc_closure_scheduler *grpc_executor_scheduler = &executor_scheduler;
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index da9dcd07d0..53f3b6d441 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -43,9 +43,7 @@
  * non-blocking solution available. */
 void grpc_executor_init();
 
-/** Enqueue \a closure for its eventual execution of \a f(arg) on a separate
- * thread */
-void grpc_executor_push(grpc_closure *closure, grpc_error *error);
+extern grpc_closure_scheduler *grpc_executor_scheduler;
 
 /** Shutdown the executor, running all pending work as part of the call */
 void grpc_executor_shutdown();
diff --git a/src/core/lib/iomgr/pollset_uv.c b/src/core/lib/iomgr/pollset_uv.c
index 3a74b842b6..ed3edeee94 100644
--- a/src/core/lib/iomgr/pollset_uv.c
+++ b/src/core/lib/iomgr/pollset_uv.c
@@ -83,7 +83,7 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
     // Drain any pending UV callbacks without blocking
     uv_run(uv_default_loop(), UV_RUN_NOWAIT);
   }
-  grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
 }
 
 void grpc_pollset_destroy(grpc_pollset *pollset) {
diff --git a/src/core/lib/iomgr/pollset_windows.c b/src/core/lib/iomgr/pollset_windows.c
index 5540303e49..6714d8d51d 100644
--- a/src/core/lib/iomgr/pollset_windows.c
+++ b/src/core/lib/iomgr/pollset_windows.c
@@ -109,7 +109,7 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
   pollset->shutting_down = 1;
   grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
   if (!pollset->is_iocp_worker) {
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
   } else {
     pollset->on_shutdown = closure;
   }
@@ -167,7 +167,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
       }
 
       if (pollset->shutting_down && pollset->on_shutdown != NULL) {
-        grpc_exec_ctx_sched(exec_ctx, pollset->on_shutdown, GRPC_ERROR_NONE,
+        grpc_closure_sched(exec_ctx, pollset->on_shutdown, GRPC_ERROR_NONE,
                             NULL);
         pollset->on_shutdown = NULL;
       }
diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c
index 821932e562..50e470d149 100644
--- a/src/core/lib/iomgr/resolve_address_posix.c
+++ b/src/core/lib/iomgr/resolve_address_posix.c
@@ -163,10 +163,9 @@ typedef struct {
 static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp,
                               grpc_error *error) {
   request *r = rp;
-  grpc_exec_ctx_sched(
+  grpc_closure_sched(
       exec_ctx, r->on_done,
-      grpc_blocking_resolve_address(r->name, r->default_port, r->addrs_out),
-      NULL);
+      grpc_blocking_resolve_address(r->name, r->default_port, r->addrs_out));
   gpr_free(r->name);
   gpr_free(r->default_port);
   gpr_free(r);
@@ -185,12 +184,13 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addrs) {
   request *r = gpr_malloc(sizeof(request));
-  grpc_closure_init(&r->request_closure, do_request_thread, r);
+  grpc_closure_init(&r->request_closure, do_request_thread, r,
+                    grpc_executor_scheduler);
   r->name = gpr_strdup(name);
   r->default_port = gpr_strdup(default_port);
   r->on_done = on_done;
   r->addrs_out = addrs;
-  grpc_executor_push(&r->request_closure, GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx, &r->request_closure, GRPC_ERROR_NONE);
 }
 
 void (*grpc_resolve_address)(
diff --git a/src/core/lib/iomgr/resolve_address_uv.c b/src/core/lib/iomgr/resolve_address_uv.c
index 3269c4f09f..9b5f3209f0 100644
--- a/src/core/lib/iomgr/resolve_address_uv.c
+++ b/src/core/lib/iomgr/resolve_address_uv.c
@@ -98,7 +98,7 @@ static void getaddrinfo_callback(uv_getaddrinfo_t *req, int status,
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_error *error;
   error = handle_addrinfo_result(status, res, r->addresses);
-  grpc_exec_ctx_sched(&exec_ctx, r->on_done, error, NULL);
+  grpc_closure_sched(&exec_ctx, r->on_done, error);
   grpc_exec_ctx_finish(&exec_ctx);
 
   gpr_free(r->hints);
@@ -193,7 +193,7 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
   int s;
   err = try_split_host_port(name, default_port, &host, &port);
   if (err != GRPC_ERROR_NONE) {
-    grpc_exec_ctx_sched(exec_ctx, on_done, err, NULL);
+    grpc_closure_sched(exec_ctx, on_done, err);
     return;
   }
   r = gpr_malloc(sizeof(request));
@@ -217,7 +217,7 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
     *addrs = NULL;
     err = GRPC_ERROR_CREATE("getaddrinfo failed");
     err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR, uv_strerror(s));
-    grpc_exec_ctx_sched(exec_ctx, on_done, err, NULL);
+    grpc_closure_sched(exec_ctx, on_done, err);
     gpr_free(r);
     gpr_free(req);
     gpr_free(hints);
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index fada5ecbe8..bda7f77f9c 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -154,7 +154,7 @@ static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp,
   } else {
     GRPC_ERROR_REF(error);
   }
-  grpc_exec_ctx_sched(exec_ctx, r->on_done, error, NULL);
+  grpc_closure_sched(exec_ctx, r->on_done, error);
   gpr_free(r->name);
   gpr_free(r->default_port);
   gpr_free(r);
@@ -173,7 +173,7 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addresses) {
   request *r = gpr_malloc(sizeof(request));
-  grpc_closure_init(&r->request_closure, do_request_thread, r);
+  grpc_closure_init(&r->request_closure, do_request_thread, r, grpc_schedule_on_exec_ctx);
   r->name = gpr_strdup(name);
   r->default_port = gpr_strdup(default_port);
   r->on_done = on_done;
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 213d29600c..8db539edfb 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -265,9 +265,8 @@ static void rq_step_sched(grpc_exec_ctx *exec_ctx,
   if (resource_quota->step_scheduled) return;
   resource_quota->step_scheduled = true;
   grpc_resource_quota_internal_ref(resource_quota);
-  grpc_combiner_execute_finally(exec_ctx, resource_quota->combiner,
-                                &resource_quota->rq_step_closure,
-                                GRPC_ERROR_NONE, false);
+  grpc_closure_sched(exec_ctx, &resource_quota->rq_step_closure,
+                     GRPC_ERROR_NONE);
 }
 
 /* returns true if all allocations are completed */
@@ -294,7 +293,7 @@ static bool rq_alloc(grpc_exec_ctx *exec_ctx,
     }
     if (resource_user->free_pool >= 0) {
       resource_user->allocating = false;
-      grpc_exec_ctx_enqueue_list(exec_ctx, &resource_user->on_allocated, NULL);
+      grpc_closure_list_sched(exec_ctx, &resource_user->on_allocated);
       gpr_mu_unlock(&resource_user->mu);
     } else {
       rulist_add_head(resource_user, GRPC_RULIST_AWAITING_ALLOCATION);
@@ -439,7 +438,7 @@ static bool ru_post_reclaimer(grpc_exec_ctx *exec_ctx,
   resource_user->new_reclaimers[destructive] = NULL;
   GPR_ASSERT(resource_user->reclaimers[destructive] == NULL);
   if (gpr_atm_acq_load(&resource_user->shutdown) > 0) {
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CANCELLED, NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CANCELLED);
     return false;
   }
   resource_user->reclaimers[destructive] = closure;
@@ -480,10 +479,10 @@ static void ru_post_destructive_reclaimer(grpc_exec_ctx *exec_ctx, void *ru,
 
 static void ru_shutdown(grpc_exec_ctx *exec_ctx, void *ru, grpc_error *error) {
   grpc_resource_user *resource_user = ru;
-  grpc_exec_ctx_sched(exec_ctx, resource_user->reclaimers[0],
-                      GRPC_ERROR_CANCELLED, NULL);
-  grpc_exec_ctx_sched(exec_ctx, resource_user->reclaimers[1],
-                      GRPC_ERROR_CANCELLED, NULL);
+  grpc_closure_sched(exec_ctx, resource_user->reclaimers[0],
+                     GRPC_ERROR_CANCELLED);
+  grpc_closure_sched(exec_ctx, resource_user->reclaimers[1],
+                     GRPC_ERROR_CANCELLED);
   resource_user->reclaimers[0] = NULL;
   resource_user->reclaimers[1] = NULL;
   rulist_remove(resource_user, GRPC_RULIST_RECLAIMER_BENIGN);
@@ -496,10 +495,10 @@ static void ru_destroy(grpc_exec_ctx *exec_ctx, void *ru, grpc_error *error) {
   for (int i = 0; i < GRPC_RULIST_COUNT; i++) {
     rulist_remove(resource_user, (grpc_rulist)i);
   }
-  grpc_exec_ctx_sched(exec_ctx, resource_user->reclaimers[0],
-                      GRPC_ERROR_CANCELLED, NULL);
-  grpc_exec_ctx_sched(exec_ctx, resource_user->reclaimers[1],
-                      GRPC_ERROR_CANCELLED, NULL);
+  grpc_closure_sched(exec_ctx, resource_user->reclaimers[0],
+                     GRPC_ERROR_CANCELLED);
+  grpc_closure_sched(exec_ctx, resource_user->reclaimers[1],
+                     GRPC_ERROR_CANCELLED);
   if (resource_user->free_pool != 0) {
     resource_user->resource_quota->free_pool += resource_user->free_pool;
     rq_step_sched(exec_ctx, resource_user->resource_quota);
@@ -571,9 +570,12 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
     gpr_asprintf(&resource_quota->name, "anonymous_pool_%" PRIxPTR,
                  (intptr_t)resource_quota);
   }
-  grpc_closure_init(&resource_quota->rq_step_closure, rq_step, resource_quota);
+  grpc_closure_init(
+      &resource_quota->rq_step_closure, rq_step, resource_quota,
+      grpc_combiner_finally_scheduler(resource_quota->combiner, true));
   grpc_closure_init(&resource_quota->rq_reclamation_done_closure,
-                    rq_reclamation_done, resource_quota);
+                    rq_reclamation_done, resource_quota,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
   for (int i = 0; i < GRPC_RULIST_COUNT; i++) {
     resource_quota->roots[i] = NULL;
   }
@@ -614,9 +616,8 @@ void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
   rq_resize_args *a = gpr_malloc(sizeof(*a));
   a->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
   a->size = (int64_t)size;
-  grpc_closure_init(&a->closure, rq_resize, a);
-  grpc_combiner_execute(&exec_ctx, resource_quota->combiner, &a->closure,
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_init(&a->closure, rq_resize, a, grpc_schedule_on_exec_ctx);
+  grpc_closure_sched(&exec_ctx, &a->closure, GRPC_ERROR_NONE);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -663,15 +664,19 @@ grpc_resource_user *grpc_resource_user_create(
   resource_user->resource_quota =
       grpc_resource_quota_internal_ref(resource_quota);
   grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
-                    resource_user);
+                    resource_user,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
   grpc_closure_init(&resource_user->add_to_free_pool_closure,
-                    &ru_add_to_free_pool, resource_user);
+                    &ru_add_to_free_pool, resource_user,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
   grpc_closure_init(&resource_user->post_reclaimer_closure[0],
-                    &ru_post_benign_reclaimer, resource_user);
+                    &ru_post_benign_reclaimer, resource_user,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
   grpc_closure_init(&resource_user->post_reclaimer_closure[1],
-                    &ru_post_destructive_reclaimer, resource_user);
-  grpc_closure_init(&resource_user->destroy_closure, &ru_destroy,
-                    resource_user);
+                    &ru_post_destructive_reclaimer, resource_user,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
+  grpc_closure_init(&resource_user->destroy_closure, &ru_destroy, resource_user,
+                    grpc_combiner_scheduler(resource_quota->combiner, false));
   gpr_mu_init(&resource_user->mu);
   gpr_atm_rel_store(&resource_user->refs, 1);
   gpr_atm_rel_store(&resource_user->shutdown, 0);
@@ -706,9 +711,8 @@ static void ru_unref_by(grpc_exec_ctx *exec_ctx,
   gpr_atm old = gpr_atm_full_fetch_add(&resource_user->refs, -amount);
   GPR_ASSERT(old >= amount);
   if (old == amount) {
-    grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
-                          &resource_user->destroy_closure, GRPC_ERROR_NONE,
-                          false);
+    grpc_closure_sched(exec_ctx, &resource_user->destroy_closure,
+                       GRPC_ERROR_NONE);
   }
 }
 
@@ -724,9 +728,12 @@ void grpc_resource_user_unref(grpc_exec_ctx *exec_ctx,
 void grpc_resource_user_shutdown(grpc_exec_ctx *exec_ctx,
                                  grpc_resource_user *resource_user) {
   if (gpr_atm_full_fetch_add(&resource_user->shutdown, 1) == 0) {
-    grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
-                          grpc_closure_create(ru_shutdown, resource_user),
-                          GRPC_ERROR_NONE, false);
+    grpc_closure_sched(exec_ctx,
+                       grpc_closure_create(
+                           ru_shutdown, resource_user,
+                           grpc_combiner_scheduler(
+                               resource_user->resource_quota->combiner, false)),
+                       GRPC_ERROR_NONE);
   }
 }
 
@@ -746,12 +753,11 @@ void grpc_resource_user_alloc(grpc_exec_ctx *exec_ctx,
                              GRPC_ERROR_NONE);
     if (!resource_user->allocating) {
       resource_user->allocating = true;
-      grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
-                            &resource_user->allocate_closure, GRPC_ERROR_NONE,
-                            false);
+      grpc_closure_sched(exec_ctx, &resource_user->allocate_closure,
+                         GRPC_ERROR_NONE);
     }
   } else {
-    grpc_exec_ctx_sched(exec_ctx, optional_on_done, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, optional_on_done, GRPC_ERROR_NONE);
   }
   gpr_mu_unlock(&resource_user->mu);
 }
@@ -770,9 +776,8 @@ void grpc_resource_user_free(grpc_exec_ctx *exec_ctx,
   if (is_bigger_than_zero && was_zero_or_negative &&
       !resource_user->added_to_free_pool) {
     resource_user->added_to_free_pool = true;
-    grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
-                          &resource_user->add_to_free_pool_closure,
-                          GRPC_ERROR_NONE, false);
+    grpc_closure_sched(exec_ctx, &resource_user->add_to_free_pool_closure,
+                       GRPC_ERROR_NONE);
   }
   gpr_mu_unlock(&resource_user->mu);
   ru_unref_by(exec_ctx, resource_user, (gpr_atm)size);
@@ -784,9 +789,9 @@ void grpc_resource_user_post_reclaimer(grpc_exec_ctx *exec_ctx,
                                        grpc_closure *closure) {
   GPR_ASSERT(resource_user->new_reclaimers[destructive] == NULL);
   resource_user->new_reclaimers[destructive] = closure;
-  grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
-                        &resource_user->post_reclaimer_closure[destructive],
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(exec_ctx,
+                     &resource_user->post_reclaimer_closure[destructive],
+                     GRPC_ERROR_NONE);
 }
 
 void grpc_resource_user_finish_reclamation(grpc_exec_ctx *exec_ctx,
@@ -795,18 +800,20 @@ void grpc_resource_user_finish_reclamation(grpc_exec_ctx *exec_ctx,
     gpr_log(GPR_DEBUG, "RQ %s %s: reclamation complete",
             resource_user->resource_quota->name, resource_user->name);
   }
-  grpc_combiner_execute(
-      exec_ctx, resource_user->resource_quota->combiner,
-      &resource_user->resource_quota->rq_reclamation_done_closure,
-      GRPC_ERROR_NONE, false);
+  grpc_closure_sched(
+      exec_ctx, &resource_user->resource_quota->rq_reclamation_done_closure,
+      GRPC_ERROR_NONE);
 }
 
 void grpc_resource_user_slice_allocator_init(
     grpc_resource_user_slice_allocator *slice_allocator,
     grpc_resource_user *resource_user, grpc_iomgr_cb_func cb, void *p) {
-  grpc_closure_init(&slice_allocator->on_allocated, ru_allocated_slices,
-                    slice_allocator);
-  grpc_closure_init(&slice_allocator->on_done, cb, p);
+  grpc_closure_init(
+      &slice_allocator->on_allocated, ru_allocated_slices, slice_allocator,
+      grpc_combiner_scheduler(resource_user->resource_quota->combiner, false));
+  grpc_closure_init(
+      &slice_allocator->on_done, cb, p,
+      grpc_combiner_scheduler(resource_user->resource_quota->combiner, false));
   slice_allocator->resource_user = resource_user;
 }
 
diff --git a/src/core/lib/iomgr/socket_windows.c b/src/core/lib/iomgr/socket_windows.c
index 54911e0e31..2f2e02f715 100644
--- a/src/core/lib/iomgr/socket_windows.c
+++ b/src/core/lib/iomgr/socket_windows.c
@@ -131,7 +131,7 @@ static void socket_notify_on_iocp(grpc_exec_ctx *exec_ctx,
   gpr_mu_lock(&socket->state_mu);
   if (info->has_pending_iocp) {
     info->has_pending_iocp = 0;
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
   } else {
     info->closure = closure;
   }
@@ -154,7 +154,7 @@ void grpc_socket_become_ready(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket,
   GPR_ASSERT(!info->has_pending_iocp);
   gpr_mu_lock(&socket->state_mu);
   if (info->closure) {
-    grpc_exec_ctx_sched(exec_ctx, info->closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, info->closure, GRPC_ERROR_NONE);
     info->closure = NULL;
   } else {
     info->has_pending_iocp = 1;
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index a3a70a8ed7..be7b695ad6 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -265,7 +265,7 @@ finish:
     grpc_channel_args_destroy(ac->channel_args);
     gpr_free(ac);
   }
-  grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+  grpc_closure_sched(exec_ctx, closure, error);
 }
 
 static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
@@ -294,7 +294,7 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
 
   error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
   if (error != GRPC_ERROR_NONE) {
-    grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+    grpc_closure_sched(exec_ctx, closure, error);
     return;
   }
   if (dsmode == GRPC_DSMODE_IPV4) {
@@ -303,7 +303,7 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
     addr = &addr4_copy;
   }
   if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
-    grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+    grpc_closure_sched(exec_ctx, closure, error);
     return;
   }
 
@@ -321,14 +321,13 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
   if (err >= 0) {
     *ep =
         grpc_tcp_client_create_from_fd(exec_ctx, fdobj, channel_args, addr_str);
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
     goto done;
   }
 
   if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
     grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
-    grpc_exec_ctx_sched(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"));
     goto done;
   }
 
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index b07f9ceffa..b1664b85fd 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -110,7 +110,7 @@ static void uv_tc_on_connect(uv_connect_t *req, int status) {
   if (done) {
     uv_tcp_connect_cleanup(&exec_ctx, connect);
   }
-  grpc_exec_ctx_sched(&exec_ctx, closure, error, NULL);
+  grpc_closure_sched(&exec_ctx, closure, error);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 1127588ebc..692252bbe0 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -129,7 +129,7 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
   async_connect_unlock_and_cleanup(exec_ctx, ac, socket);
   /* If the connection was aborted, the callback was already called when
      the deadline was met. */
-  grpc_exec_ctx_sched(exec_ctx, on_done, error, NULL);
+  grpc_closure_sched(exec_ctx, on_done, error);
 }
 
 /* Tries to issue one async connection, then schedules both an IOCP
@@ -227,7 +227,7 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
   ac->addr_name = grpc_sockaddr_to_uri(addr);
   ac->endpoint = endpoint;
   ac->resource_quota = resource_quota;
-  grpc_closure_init(&ac->on_connect, on_connect, ac);
+  grpc_closure_init(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx);
 
   grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac,
                   gpr_now(GPR_CLOCK_MONOTONIC));
@@ -247,7 +247,7 @@ failure:
     closesocket(sock);
   }
   grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-  grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
+  grpc_closure_sched(exec_ctx, on_done, final_error);
 }
 
 #endif /* GRPC_WINSOCK_SOCKET */
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 540305e4fa..1000776d61 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -316,7 +316,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     tcp->finished_edge = false;
     grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
   } else {
-    grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE);
   }
 }
 
@@ -460,11 +460,10 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (buf->length == 0) {
     GPR_TIMER_END("tcp_write", 0);
-    grpc_exec_ctx_sched(exec_ctx, cb,
-                        grpc_fd_is_shutdown(tcp->em_fd)
-                            ? tcp_annotate_error(GRPC_ERROR_CREATE("EOF"), tcp)
-                            : GRPC_ERROR_NONE,
-                        NULL);
+    grpc_closure_sched(exec_ctx, cb,
+                       grpc_fd_is_shutdown(tcp->em_fd)
+                           ? tcp_annotate_error(GRPC_ERROR_CREATE("EOF"), tcp)
+                           : GRPC_ERROR_NONE);
     return;
   }
   tcp->outgoing_buffer = buf;
@@ -484,7 +483,7 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
       gpr_log(GPR_DEBUG, "write: %s", str);
       grpc_error_free_string(str);
     }
-    grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+    grpc_closure_sched(exec_ctx, cb, error);
   }
 
   GPR_TIMER_END("tcp_write", 0);
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index 179f47ef76..e7eae19cf3 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -208,7 +208,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   GPR_ASSERT(s->shutdown);
   gpr_mu_unlock(&s->mu);
   if (s->shutdown_complete != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
   gpr_mu_destroy(&s->mu);
@@ -760,7 +760,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
     grpc_tcp_server_shutdown_listeners(exec_ctx, s);
     gpr_mu_lock(&s->mu);
-    grpc_exec_ctx_enqueue_list(exec_ctx, &s->shutdown_starting, NULL);
+    grpc_closure_list_sched(exec_ctx, &s->shutdown_starting);
     gpr_mu_unlock(&s->mu);
     tcp_server_destroy(exec_ctx, s);
   }
diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index e1a174cfa2..89624b447c 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -126,7 +126,7 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
 
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (s->shutdown_complete != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
   while (s->head) {
@@ -170,7 +170,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
     /* Complete shutdown_starting work before destroying. */
     grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL);
+    grpc_closure_list_sched(&local_exec_ctx, &s->shutdown_starting, NULL);
     if (exec_ctx == NULL) {
       grpc_exec_ctx_flush(&local_exec_ctx);
       tcp_server_destroy(&local_exec_ctx, s);
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index b0c8586bac..2a54949354 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -162,10 +162,10 @@ static void destroy_server(grpc_exec_ctx *exec_ctx, void *arg,
 static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
                                    grpc_tcp_server *s) {
   if (s->shutdown_complete != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
-  grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(destroy_server, s),
+  grpc_closure_sched(exec_ctx, grpc_closure_create(destroy_server, s),
                       GRPC_ERROR_NONE, NULL);
 }
 
@@ -204,7 +204,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
     grpc_tcp_server_shutdown_listeners(exec_ctx, s);
     gpr_mu_lock(&s->mu);
-    grpc_exec_ctx_enqueue_list(exec_ctx, &s->shutdown_starting, NULL);
+    grpc_closure_list_sched(exec_ctx, &s->shutdown_starting, NULL);
     gpr_mu_unlock(&s->mu);
     tcp_server_destroy(exec_ctx, s);
   }
@@ -465,7 +465,7 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
   sp->new_socket = INVALID_SOCKET;
   sp->port = port;
   sp->port_index = port_index;
-  grpc_closure_init(&sp->on_accept, on_accept, sp);
+  grpc_closure_init(&sp->on_accept, on_accept, sp, grpc_schedule_on_exec_ctx);
   GPR_ASSERT(sp->socket);
   gpr_mu_unlock(&s->mu);
   *listener = sp;
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 6e2ad1dbe9..f97ca885b4 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -169,7 +169,7 @@ static void read_callback(uv_stream_t *stream, ssize_t nread,
     // nread < 0: Error
     error = GRPC_ERROR_CREATE("TCP Read failed");
   }
-  grpc_exec_ctx_sched(&exec_ctx, cb, error, NULL);
+  grpc_closure_sched(&exec_ctx, cb, error);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -190,7 +190,7 @@ static void uv_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     error = GRPC_ERROR_CREATE("TCP Read failed at start");
     error =
         grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status));
-    grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+    grpc_closure_sched(exec_ctx, cb, error);
   }
   if (grpc_tcp_trace) {
     const char *str = grpc_error_string(error);
@@ -217,7 +217,7 @@ static void write_callback(uv_write_t *req, int status) {
   gpr_free(tcp->write_buffers);
   grpc_resource_user_free(&exec_ctx, tcp->resource_user,
                           sizeof(uv_buf_t) * tcp->write_slices->count);
-  grpc_exec_ctx_sched(&exec_ctx, cb, error, NULL);
+  grpc_closure_sched(&exec_ctx, cb, error);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -243,7 +243,7 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   }
 
   if (tcp->shutting_down) {
-    grpc_exec_ctx_sched(exec_ctx, cb,
+    grpc_closure_sched(exec_ctx, cb,
                         GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
     return;
   }
@@ -254,7 +254,7 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   if (tcp->write_slices->count == 0) {
     // No slices means we don't have to do anything,
     // and libuv doesn't like empty writes
-    grpc_exec_ctx_sched(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
     return;
   }
 
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index d4613b674e..b84a448a81 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -188,7 +188,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
 
   tcp->read_cb = NULL;
   TCP_UNREF(exec_ctx, tcp, "read");
-  grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+  grpc_closure_sched(exec_ctx, cb, error);
 }
 
 static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -202,7 +202,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   WSABUF buffer;
 
   if (tcp->shutting_down) {
-    grpc_exec_ctx_sched(exec_ctx, cb,
+    grpc_closure_sched(exec_ctx, cb,
                         GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
     return;
   }
@@ -227,7 +227,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   /* Did we get data immediately ? Yay. */
   if (info->wsa_error != WSAEWOULDBLOCK) {
     info->bytes_transfered = bytes_read;
-    grpc_exec_ctx_sched(exec_ctx, &tcp->on_read, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &tcp->on_read, GRPC_ERROR_NONE);
     return;
   }
 
@@ -240,7 +240,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     int wsa_error = WSAGetLastError();
     if (wsa_error != WSA_IO_PENDING) {
       info->wsa_error = wsa_error;
-      grpc_exec_ctx_sched(exec_ctx, &tcp->on_read,
+      grpc_closure_sched(exec_ctx, &tcp->on_read,
                           GRPC_WSA_ERROR(info->wsa_error, "WSARecv"), NULL);
       return;
     }
@@ -272,7 +272,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
   }
 
   TCP_UNREF(exec_ctx, tcp, "write");
-  grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+  grpc_closure_sched(exec_ctx, cb, error);
 }
 
 /* Initiates a write. */
@@ -290,7 +290,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   size_t len;
 
   if (tcp->shutting_down) {
-    grpc_exec_ctx_sched(exec_ctx, cb,
+    grpc_closure_sched(exec_ctx, cb,
                         GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
     return;
   }
@@ -322,7 +322,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     grpc_error *error = status == 0
                             ? GRPC_ERROR_NONE
                             : GRPC_WSA_ERROR(info->wsa_error, "WSASend");
-    grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+    grpc_closure_sched(exec_ctx, cb, error);
     if (allocated) gpr_free(allocated);
     return;
   }
@@ -340,7 +340,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     int wsa_error = WSAGetLastError();
     if (wsa_error != WSA_IO_PENDING) {
       TCP_UNREF(exec_ctx, tcp, "write");
-      grpc_exec_ctx_sched(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend"),
+      grpc_closure_sched(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend"),
                           NULL);
       return;
     }
@@ -424,8 +424,8 @@ grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket,
   tcp->socket = socket;
   gpr_mu_init(&tcp->mu);
   gpr_ref_init(&tcp->refcount, 1);
-  grpc_closure_init(&tcp->on_read, on_read, tcp);
-  grpc_closure_init(&tcp->on_write, on_write, tcp);
+  grpc_closure_init(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx);
   tcp->peer_string = gpr_strdup(peer_string);
   tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string);
   /* Tell network status tracking code about the new endpoint */
diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c
index 00058f9d86..ecd3b284dc 100644
--- a/src/core/lib/iomgr/timer_generic.c
+++ b/src/core/lib/iomgr/timer_generic.c
@@ -184,22 +184,22 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
   shard_type *shard = &g_shards[shard_idx(timer)];
   GPR_ASSERT(deadline.clock_type == g_clock_type);
   GPR_ASSERT(now.clock_type == g_clock_type);
-  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg);
+  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
+                    grpc_schedule_on_exec_ctx);
   timer->deadline = deadline;
   timer->triggered = 0;
 
   if (!g_initialized) {
     timer->triggered = 1;
-    grpc_exec_ctx_sched(
+    grpc_closure_sched(
         exec_ctx, &timer->closure,
-        GRPC_ERROR_CREATE("Attempt to create timer before initialization"),
-        NULL);
+        GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
     return;
   }
 
   if (gpr_time_cmp(deadline, now) <= 0) {
     timer->triggered = 1;
-    grpc_exec_ctx_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
     return;
   }
 
@@ -251,7 +251,7 @@ void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
   shard_type *shard = &g_shards[shard_idx(timer)];
   gpr_mu_lock(&shard->mu);
   if (!timer->triggered) {
-    grpc_exec_ctx_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED, NULL);
+    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
     timer->triggered = 1;
     if (timer->heap_index == INVALID_HEAP_INDEX) {
       list_remove(timer);
@@ -317,7 +317,7 @@ static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
   grpc_timer *timer;
   gpr_mu_lock(&shard->mu);
   while ((timer = pop_one(shard, now))) {
-    grpc_exec_ctx_sched(exec_ctx, &timer->closure, GRPC_ERROR_REF(error), NULL);
+    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_REF(error));
     n++;
   }
   *new_min_deadline = compute_min_deadline(shard);
diff --git a/src/core/lib/iomgr/timer_uv.c b/src/core/lib/iomgr/timer_uv.c
index cfcb89268b..7153535a85 100644
--- a/src/core/lib/iomgr/timer_uv.c
+++ b/src/core/lib/iomgr/timer_uv.c
@@ -55,7 +55,7 @@ void run_expired_timer(uv_timer_t *handle) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GPR_ASSERT(!timer->triggered);
   timer->triggered = 1;
-  grpc_exec_ctx_sched(&exec_ctx, &timer->closure, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(&exec_ctx, &timer->closure, GRPC_ERROR_NONE);
   stop_uv_timer(handle);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -65,10 +65,10 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
                      void *timer_cb_arg, gpr_timespec now) {
   uint64_t timeout;
   uv_timer_t *uv_timer;
-  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg);
+  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg, grpc_schedule_on_exec_ctx);
   if (gpr_time_cmp(deadline, now) <= 0) {
     timer->triggered = 1;
-    grpc_exec_ctx_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
     return;
   }
   timer->triggered = 0;
@@ -83,7 +83,7 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
 void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
   if (!timer->triggered) {
     timer->triggered = 1;
-    grpc_exec_ctx_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED, NULL);
+    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
     stop_uv_timer((uv_timer_t *)timer->uv_timer);
   }
 }
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 3c24ea9afa..69812e2804 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -126,7 +126,7 @@ grpc_udp_server *grpc_udp_server_create(void) {
 
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
   if (s->shutdown_complete != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
   gpr_mu_destroy(&s->mu);
diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h
index 73d9849843..371b0f55dc 100644
--- a/src/core/lib/iomgr/workqueue.h
+++ b/src/core/lib/iomgr/workqueue.h
@@ -72,17 +72,16 @@ grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue);
 void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue);
 #endif
 
-/** Add a work item to a workqueue. Items added to a work queue will be started
-    in approximately the order they were enqueued, on some thread that may or
-    may not be the current thread. Successive closures enqueued onto a workqueue
-    MAY be executed concurrently.
+/** Fetch the workqueue closure scheduler. Items added to a work queue will be
+    started in approximately the order they were enqueued, on some thread that
+    may or may not be the current thread. Successive closures enqueued onto a
+    workqueue MAY be executed concurrently.
 
     It is generally more expensive to add a closure to a workqueue than to the
     execution context, both in terms of CPU work and in execution latency.
 
     Use work queues when it's important that other threads be given a chance to
     tackle some workload. */
-void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
-                            grpc_closure *closure, grpc_error *error);
+grpc_closure_scheduler *grpc_workqueue_scheduler(grpc_workqueue *workqueue);
 
 #endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_H */
diff --git a/src/core/lib/iomgr/workqueue_uv.c b/src/core/lib/iomgr/workqueue_uv.c
index e58ca476cc..4d61b40912 100644
--- a/src/core/lib/iomgr/workqueue_uv.c
+++ b/src/core/lib/iomgr/workqueue_uv.c
@@ -58,9 +58,8 @@ grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) {
 void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {}
 #endif
 
-void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
-                            grpc_closure *closure, grpc_error *error) {
-  grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+grpc_closure_scheduler *grpc_workqueue_scheduler(grpc_workqueue *workqueue) {
+  return grpc_schedule_on_exec_ctx;
 }
 
 #endif /* GPR_UV */
diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c
index 5c93d3c59e..234b47cdf5 100644
--- a/src/core/lib/iomgr/workqueue_windows.c
+++ b/src/core/lib/iomgr/workqueue_windows.c
@@ -56,9 +56,8 @@ grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue) {
 void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {}
 #endif
 
-void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
-                            grpc_closure *closure, grpc_error *error) {
-  grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
+grpc_closure_scheduler *grpc_workqueue_scheduler(grpc_workqueue *workqueue) {
+  return grpc_schedule_on_exec_ctx;
 }
 
 #endif /* GPR_WINDOWS */
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index ea4cb76fb9..1cf142fa9a 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -113,9 +113,10 @@ static void md_only_test_get_request_metadata(
   if (c->is_async) {
     grpc_credentials_metadata_request *cb_arg =
         grpc_credentials_metadata_request_create(creds, cb, user_data);
-    grpc_executor_push(
-        grpc_closure_create(on_simulated_token_fetch_done, cb_arg),
-        GRPC_ERROR_NONE);
+    grpc_closure_sched(exec_ctx,
+                       grpc_closure_create(on_simulated_token_fetch_done,
+                                           cb_arg, grpc_executor_scheduler),
+                       GRPC_ERROR_NONE);
   } else {
     cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK, NULL);
   }
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index afe0e3d357..caf57c856b 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -130,7 +130,8 @@ static int is_stack_running_on_compute_engine(void) {
   grpc_httpcli_get(
       &exec_ctx, &context, &detector.pollent, resource_quota, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
-      grpc_closure_create(on_compute_engine_detection_http_response, &detector),
+      grpc_closure_create(on_compute_engine_detection_http_response, &detector,
+                          grpc_schedule_on_exec_ctx),
       &detector.response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
 
@@ -155,7 +156,8 @@ static int is_stack_running_on_compute_engine(void) {
 
   grpc_httpcli_context_destroy(&context);
   grpc_closure_init(&destroy_closure, destroy_pollset,
-                    grpc_polling_entity_pollset(&detector.pollent));
+                    grpc_polling_entity_pollset(&detector.pollent),
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx,
                         grpc_polling_entity_pollset(&detector.pollent),
                         &destroy_closure);
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 03097a57c0..8c75098612 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -677,7 +677,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
   grpc_httpcli_get(
       exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
-      grpc_closure_create(on_keys_retrieved, ctx),
+      grpc_closure_create(on_keys_retrieved, ctx, grpc_schedule_on_exec_ctx),
       &ctx->responses[HTTP_RESPONSE_KEYS]);
   grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
   grpc_json_destroy(json);
@@ -778,7 +778,8 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
       *(path_prefix++) = '\0';
       gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss);
     }
-    http_cb = grpc_closure_create(on_keys_retrieved, ctx);
+    http_cb =
+        grpc_closure_create(on_keys_retrieved, ctx, grpc_schedule_on_exec_ctx);
     rsp_idx = HTTP_RESPONSE_KEYS;
   } else {
     req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss);
@@ -790,7 +791,8 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
       gpr_asprintf(&req.http.path, "/%s%s", path_prefix,
                    GRPC_OPENID_CONFIG_URL_SUFFIX);
     }
-    http_cb = grpc_closure_create(on_openid_config_retrieved, ctx);
+    http_cb = grpc_closure_create(on_openid_config_retrieved, ctx,
+                                  grpc_schedule_on_exec_ctx);
     rsp_idx = HTTP_RESPONSE_OPENID;
   }
 
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index b3625b22c0..9aa7863977 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -312,9 +312,10 @@ static void compute_engine_fetch_oauth2(
      extreme memory pressure. */
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("oauth2_credentials");
-  grpc_httpcli_get(exec_ctx, httpcli_context, pollent, resource_quota, &request,
-                   deadline, grpc_closure_create(response_cb, metadata_req),
-                   &metadata_req->response);
+  grpc_httpcli_get(
+      exec_ctx, httpcli_context, pollent, resource_quota, &request, deadline,
+      grpc_closure_create(response_cb, metadata_req, grpc_schedule_on_exec_ctx),
+      &metadata_req->response);
   grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
 }
 
@@ -368,10 +369,11 @@ static void refresh_token_fetch_oauth2(
      extreme memory pressure. */
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("oauth2_credentials_refresh");
-  grpc_httpcli_post(exec_ctx, httpcli_context, pollent, resource_quota,
-                    &request, body, strlen(body), deadline,
-                    grpc_closure_create(response_cb, metadata_req),
-                    &metadata_req->response);
+  grpc_httpcli_post(
+      exec_ctx, httpcli_context, pollent, resource_quota, &request, body,
+      strlen(body), deadline,
+      grpc_closure_create(response_cb, metadata_req, grpc_schedule_on_exec_ctx),
+      &metadata_req->response);
   grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
   gpr_free(body);
 }
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 331a8f1835..750c3675b1 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -146,7 +146,7 @@ static void call_read_cb(grpc_exec_ctx *exec_ctx, secure_endpoint *ep,
     }
   }
   ep->read_buffer = NULL;
-  grpc_exec_ctx_sched(exec_ctx, ep->read_cb, error, NULL);
+  grpc_closure_sched(exec_ctx, ep->read_cb, error);
   SECURE_ENDPOINT_UNREF(exec_ctx, ep, "read");
 }
 
@@ -329,10 +329,9 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
   if (result != TSI_OK) {
     /* TODO(yangg) do different things according to the error type? */
     grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
-    grpc_exec_ctx_sched(
+    grpc_closure_sched(
         exec_ctx, cb,
-        grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result),
-        NULL);
+        grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result));
     GPR_TIMER_END("secure_endpoint.endpoint_write", 0);
     return;
   }
@@ -417,7 +416,7 @@ grpc_endpoint *grpc_secure_endpoint_create(
   grpc_slice_buffer_init(&ep->output_buffer);
   grpc_slice_buffer_init(&ep->source_buffer);
   ep->read_buffer = NULL;
-  grpc_closure_init(&ep->on_read, on_read, ep);
+  grpc_closure_init(&ep->on_read, on_read, ep, grpc_schedule_on_exec_ctx);
   gpr_mu_init(&ep->protector_mu);
   gpr_ref_init(&ep->ref, 1);
   return &ep->base;
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index 5b088aa58d..17ad681c82 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -134,9 +134,9 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
                                         grpc_auth_context **auth_context,
                                         grpc_closure *on_peer_checked) {
   if (sc == NULL) {
-    grpc_exec_ctx_sched(
+    grpc_closure_sched(
         exec_ctx, on_peer_checked,
-        GRPC_ERROR_CREATE("cannot check peer -- no security connector"), NULL);
+        GRPC_ERROR_CREATE("cannot check peer -- no security connector"));
     tsi_peer_destruct(&peer);
   } else {
     sc->vtable->check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
@@ -273,7 +273,7 @@ static void fake_check_peer(grpc_exec_ctx *exec_ctx,
       GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
 
 end:
-  grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
+  grpc_closure_sched(exec_ctx, on_peer_checked, error);
   tsi_peer_destruct(&peer);
 }
 
@@ -508,7 +508,7 @@ static void ssl_channel_check_peer(grpc_exec_ctx *exec_ctx,
                                              ? c->overridden_target_name
                                              : c->target_name,
                                      &peer, auth_context);
-  grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
+  grpc_closure_sched(exec_ctx, on_peer_checked, error);
   tsi_peer_destruct(&peer);
 }
 
@@ -518,7 +518,7 @@ static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx,
                                   grpc_closure *on_peer_checked) {
   grpc_error *error = ssl_check_peer(sc, NULL, &peer, auth_context);
   tsi_peer_destruct(&peer);
-  grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
+  grpc_closure_sched(exec_ctx, on_peer_checked, error);
 }
 
 static void add_shallow_auth_property_to_peer(tsi_peer *peer,
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 41a775db85..748bf4a432 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -136,7 +136,7 @@ static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx,
     h->shutdown = true;
   }
   // Invoke callback.
-  grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, error, NULL);
+  grpc_closure_sched(exec_ctx, h->on_handshake_done, error);
 }
 
 static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
@@ -173,7 +173,7 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
       grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1);
   grpc_channel_args_destroy(tmp_args);
   // Invoke callback.
-  grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE);
   // Set shutdown to true so that subsequent calls to
   // security_handshaker_shutdown() do nothing.
   h->shutdown = true;
@@ -392,10 +392,13 @@ static grpc_handshaker *security_handshaker_create(
   h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
   h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
   grpc_closure_init(&h->on_handshake_data_sent_to_peer,
-                    on_handshake_data_sent_to_peer, h);
+                    on_handshake_data_sent_to_peer, h,
+                    grpc_schedule_on_exec_ctx);
   grpc_closure_init(&h->on_handshake_data_received_from_peer,
-                    on_handshake_data_received_from_peer, h);
-  grpc_closure_init(&h->on_peer_checked, on_peer_checked, h);
+                    on_handshake_data_received_from_peer, h,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&h->on_peer_checked, on_peer_checked, h,
+                    grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&h->left_overs);
   grpc_slice_buffer_init(&h->outgoing);
   return &h->base;
@@ -418,9 +421,8 @@ static void fail_handshaker_do_handshake(grpc_exec_ctx *exec_ctx,
                                          grpc_tcp_server_acceptor *acceptor,
                                          grpc_closure *on_handshake_done,
                                          grpc_handshaker_args *args) {
-  grpc_exec_ctx_sched(exec_ctx, on_handshake_done,
-                      GRPC_ERROR_CREATE("Failed to create security handshaker"),
-                      NULL);
+  grpc_closure_sched(exec_ctx, on_handshake_done,
+                     GRPC_ERROR_CREATE("Failed to create security handshaker"));
 }
 
 static const grpc_handshaker_vtable fail_handshaker_vtable = {
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index e6a242e68f..5b4adc4661 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -132,7 +132,7 @@ static void on_md_processing_done(
     grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md,
                                elem);
     grpc_metadata_array_destroy(&calld->md);
-    grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE);
   } else {
     grpc_slice message;
     grpc_transport_stream_op *close_op = gpr_malloc(sizeof(*close_op));
@@ -148,13 +148,13 @@ static void on_md_processing_done(
       calld->transport_op->send_message = NULL;
     }
     calld->transport_op->send_trailing_metadata = NULL;
-    close_op->on_complete = grpc_closure_create(destroy_op, close_op);
+    close_op->on_complete =
+        grpc_closure_create(destroy_op, close_op, grpc_schedule_on_exec_ctx);
     grpc_transport_stream_op_add_close(close_op, status, &message);
     grpc_call_next_op(&exec_ctx, elem, close_op);
-    grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv,
-                        grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
-                                           GRPC_ERROR_INT_GRPC_STATUS, status),
-                        NULL);
+    grpc_closure_sched(&exec_ctx, calld->on_done_recv,
+                       grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
+                                          GRPC_ERROR_INT_GRPC_STATUS, status));
   }
 
   grpc_exec_ctx_finish(&exec_ctx);
@@ -174,8 +174,7 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
       return;
     }
   }
-  grpc_exec_ctx_sched(exec_ctx, calld->on_done_recv, GRPC_ERROR_REF(error),
-                      NULL);
+  grpc_closure_sched(exec_ctx, calld->on_done_recv, GRPC_ERROR_REF(error));
 }
 
 static void set_recv_ops_md_callbacks(grpc_call_element *elem,
@@ -214,7 +213,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
 
   /* initialize members */
   memset(calld, 0, sizeof(*calld));
-  grpc_closure_init(&calld->auth_on_recv, auth_on_recv, elem);
+  grpc_closure_init(&calld->auth_on_recv, auth_on_recv, elem,
+                    grpc_schedule_on_exec_ctx);
 
   if (args->context[GRPC_CONTEXT_SECURITY].value != NULL) {
     args->context[GRPC_CONTEXT_SECURITY].destroy(
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 8ca3cab9d5..b20801005a 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -794,7 +794,8 @@ static void send_cancel(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
   memset(&tc->op, 0, sizeof(tc->op));
   tc->op.cancel_error = tc->error;
   /* reuse closure to catch completion */
-  grpc_closure_init(&tc->closure, done_termination, tc);
+  grpc_closure_init(&tc->closure, done_termination, tc,
+                    grpc_schedule_on_exec_ctx);
   tc->op.on_complete = &tc->closure;
   execute_op(exec_ctx, tc->call, &tc->op);
 }
@@ -804,7 +805,8 @@ static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
   memset(&tc->op, 0, sizeof(tc->op));
   tc->op.close_error = tc->error;
   /* reuse closure to catch completion */
-  grpc_closure_init(&tc->closure, done_termination, tc);
+  grpc_closure_init(&tc->closure, done_termination, tc,
+                    grpc_schedule_on_exec_ctx);
   tc->op.on_complete = &tc->closure;
   execute_op(exec_ctx, tc->call, &tc->op);
 }
@@ -814,13 +816,13 @@ static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
   set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
 
   if (tc->type == TC_CANCEL) {
-    grpc_closure_init(&tc->closure, send_cancel, tc);
+    grpc_closure_init(&tc->closure, send_cancel, tc, grpc_schedule_on_exec_ctx);
     GRPC_CALL_INTERNAL_REF(tc->call, "cancel");
   } else if (tc->type == TC_CLOSE) {
-    grpc_closure_init(&tc->closure, send_close, tc);
+    grpc_closure_init(&tc->closure, send_close, tc, grpc_schedule_on_exec_ctx);
     GRPC_CALL_INTERNAL_REF(tc->call, "close");
   }
-  grpc_exec_ctx_sched(exec_ctx, &tc->closure, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, &tc->closure, GRPC_ERROR_NONE);
   return GRPC_CALL_OK;
 }
 
@@ -1138,8 +1140,8 @@ static void process_data_after_md(grpc_exec_ctx *exec_ctx,
     } else {
       *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
     }
-    grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready,
-                      bctl);
+    grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready, bctl,
+                      grpc_schedule_on_exec_ctx);
     continue_receiving_slices(exec_ctx, bctl);
   }
 }
@@ -1251,9 +1253,10 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
   call->has_initial_md_been_received = true;
   if (call->saved_receiving_stream_ready_bctlp != NULL) {
     grpc_closure *saved_rsr_closure = grpc_closure_create(
-        receiving_stream_ready, call->saved_receiving_stream_ready_bctlp);
+        receiving_stream_ready, call->saved_receiving_stream_ready_bctlp,
+        grpc_schedule_on_exec_ctx);
     call->saved_receiving_stream_ready_bctlp = NULL;
-    grpc_exec_ctx_sched(exec_ctx, saved_rsr_closure, error, NULL);
+    grpc_closure_sched(exec_ctx, saved_rsr_closure, error);
   }
 
   gpr_mu_unlock(&call->mu);
@@ -1558,7 +1561,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         call->received_initial_metadata = 1;
         call->buffered_metadata[0] = op->data.recv_initial_metadata;
         grpc_closure_init(&call->receiving_initial_metadata_ready,
-                          receiving_initial_metadata_ready, bctl);
+                          receiving_initial_metadata_ready, bctl,
+                          grpc_schedule_on_exec_ctx);
         bctl->recv_initial_metadata = 1;
         stream_op->recv_initial_metadata =
             &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
@@ -1581,7 +1585,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
         call->receiving_buffer = op->data.recv_message;
         stream_op->recv_message = &call->receiving_stream;
         grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready,
-                          bctl);
+                          bctl, grpc_schedule_on_exec_ctx);
         stream_op->recv_message_ready = &call->receiving_stream_ready;
         num_completion_callbacks_needed++;
         break;
@@ -1646,7 +1650,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
   gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed);
 
   stream_op->context = call->context;
-  grpc_closure_init(&bctl->finish_batch, finish_batch, bctl);
+  grpc_closure_init(&bctl->finish_batch, finish_batch, bctl,
+                    grpc_schedule_on_exec_ctx);
   stream_op->on_complete = &bctl->finish_batch;
   gpr_mu_unlock(&call->mu);
 
diff --git a/src/core/lib/surface/channel_ping.c b/src/core/lib/surface/channel_ping.c
index 0d2f01a649..e68febdddf 100644
--- a/src/core/lib/surface/channel_ping.c
+++ b/src/core/lib/surface/channel_ping.c
@@ -71,7 +71,7 @@ void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
   GPR_ASSERT(reserved == NULL);
   pr->tag = tag;
   pr->cq = cq;
-  grpc_closure_init(&pr->closure, ping_done, pr);
+  grpc_closure_init(&pr->closure, ping_done, pr, grpc_schedule_on_exec_ctx);
   op->send_ping = &pr->closure;
   op->bind_pollset = grpc_cq_pollset(cq);
   grpc_cq_begin_op(cq, tag);
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index 184c1a1a16..aefdd39547 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -168,7 +168,7 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
 #ifndef NDEBUG
   cc->outstanding_tag_count = 0;
 #endif
-  grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc);
+  grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc, grpc_schedule_on_exec_ctx);
 
   GPR_TIMER_END("grpc_completion_queue_create", 0);
 
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index 57da94ac1e..f1ad13711a 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -98,16 +98,16 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
   if (op->on_connectivity_state_change) {
     GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_SHUTDOWN);
     *op->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
-    grpc_exec_ctx_sched(exec_ctx, op->on_connectivity_state_change,
-                        GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, op->on_connectivity_state_change,
+                       GRPC_ERROR_NONE);
   }
   if (op->send_ping != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, op->send_ping,
-                        GRPC_ERROR_CREATE("lame client channel"), NULL);
+    grpc_closure_sched(exec_ctx, op->send_ping,
+                       GRPC_ERROR_CREATE("lame client channel"));
   }
   GRPC_ERROR_UNREF(op->disconnect_with_error);
   if (op->on_consumed != NULL) {
-    grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
   }
 }
 
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 62d7afc8da..d143ad9607 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -278,7 +278,8 @@ static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
 static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
                           int send_goaway, grpc_error *send_disconnect) {
   struct shutdown_cleanup_args *sc = gpr_malloc(sizeof(*sc));
-  grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
+  grpc_closure_init(&sc->closure, shutdown_cleanup, sc,
+                    grpc_schedule_on_exec_ctx);
   grpc_transport_op *op = grpc_make_transport_op(&sc->closure);
   grpc_channel_element *elem;
 
@@ -346,9 +347,9 @@ static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
     gpr_mu_unlock(&calld->mu_state);
     grpc_closure_init(
         &calld->kill_zombie_closure, kill_zombie,
-        grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
-    grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE,
-                        NULL);
+        grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
+        grpc_schedule_on_exec_ctx);
+    grpc_closure_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE);
   }
 }
 
@@ -545,8 +546,9 @@ static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg,
     gpr_mu_unlock(&calld->mu_state);
     grpc_closure_init(
         &calld->kill_zombie_closure, kill_zombie,
-        grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
-    grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, error, NULL);
+        grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
+        grpc_schedule_on_exec_ctx);
+    grpc_closure_sched(exec_ctx, &calld->kill_zombie_closure, error);
     return;
   }
 
@@ -590,9 +592,9 @@ static void finish_start_new_rpc(
     gpr_mu_lock(&calld->mu_state);
     calld->state = ZOMBIED;
     gpr_mu_unlock(&calld->mu_state);
-    grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
-    grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE,
-                        NULL);
+    grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem,
+                      grpc_schedule_on_exec_ctx);
+    grpc_closure_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE);
     return;
   }
 
@@ -607,7 +609,8 @@ static void finish_start_new_rpc(
       memset(&op, 0, sizeof(op));
       op.op = GRPC_OP_RECV_MESSAGE;
       op.data.recv_message = &calld->payload;
-      grpc_closure_init(&calld->publish, publish_new_rpc, elem);
+      grpc_closure_init(&calld->publish, publish_new_rpc, elem,
+                        grpc_schedule_on_exec_ctx);
       grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1,
                                         &calld->publish);
       break;
@@ -813,9 +816,10 @@ static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
     if (calld->state == NOT_STARTED) {
       calld->state = ZOMBIED;
       gpr_mu_unlock(&calld->mu_state);
-      grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
-      grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure,
-                          GRPC_ERROR_NONE, NULL);
+      grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem,
+                        grpc_schedule_on_exec_ctx);
+      grpc_closure_sched(exec_ctx, &calld->kill_zombie_closure,
+                         GRPC_ERROR_NONE);
     } else if (calld->state == PENDING) {
       calld->state = ZOMBIED;
       gpr_mu_unlock(&calld->mu_state);
@@ -851,7 +855,8 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
   memset(&op, 0, sizeof(op));
   op.op = GRPC_OP_RECV_INITIAL_METADATA;
   op.data.recv_initial_metadata = &calld->initial_metadata;
-  grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
+  grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem,
+                    grpc_schedule_on_exec_ctx);
   grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
                                     &calld->got_initial_metadata);
 }
@@ -887,7 +892,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_init(&calld->mu_state);
 
   grpc_closure_init(&calld->server_on_recv_initial_metadata,
-                    server_on_recv_initial_metadata, elem);
+                    server_on_recv_initial_metadata, elem,
+                    grpc_schedule_on_exec_ctx);
 
   server_ref(chand->server);
   return GRPC_ERROR_NONE;
@@ -926,7 +932,8 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->registered_methods = NULL;
   chand->connectivity_state = GRPC_CHANNEL_IDLE;
   grpc_closure_init(&chand->channel_connectivity_changed,
-                    channel_connectivity_changed, chand);
+                    channel_connectivity_changed, chand,
+                    grpc_schedule_on_exec_ctx);
   return GRPC_ERROR_NONE;
 }
 
@@ -1278,7 +1285,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
 
   /* Shutdown listeners */
   for (l = server->listeners; l; l = l->next) {
-    grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
+    grpc_closure_init(&l->destroy_done, listener_destroy_done, server,
+                      grpc_schedule_on_exec_ctx);
     l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
   }
 
@@ -1384,9 +1392,10 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
         gpr_mu_unlock(&calld->mu_state);
         grpc_closure_init(
             &calld->kill_zombie_closure, kill_zombie,
-            grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
-        grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure,
-                            GRPC_ERROR_NONE, NULL);
+            grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
+            grpc_schedule_on_exec_ctx);
+        grpc_closure_sched(exec_ctx, &calld->kill_zombie_closure,
+                           GRPC_ERROR_NONE);
       } else {
         GPR_ASSERT(calld->state == PENDING);
         calld->state = ACTIVATED;
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index 4f49d7cf7d..c656d93740 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -81,7 +81,7 @@ void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx,
     } else {
       error = GRPC_ERROR_CREATE("Shutdown connectivity owner");
     }
-    grpc_exec_ctx_sched(exec_ctx, w->notify, error, NULL);
+    grpc_closure_sched(exec_ctx, w->notify, error);
     gpr_free(w);
   }
   GRPC_ERROR_UNREF(tracker->current_error);
@@ -121,7 +121,7 @@ bool grpc_connectivity_state_notify_on_state_change(
   if (current == NULL) {
     grpc_connectivity_state_watcher *w = tracker->watchers;
     if (w != NULL && w->notify == notify) {
-      grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED, NULL);
+      grpc_closure_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED);
       tracker->watchers = w->next;
       gpr_free(w);
       return false;
@@ -129,7 +129,7 @@ bool grpc_connectivity_state_notify_on_state_change(
     while (w != NULL) {
       grpc_connectivity_state_watcher *rm_candidate = w->next;
       if (rm_candidate != NULL && rm_candidate->notify == notify) {
-        grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED, NULL);
+        grpc_closure_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED);
         w->next = w->next->next;
         gpr_free(rm_candidate);
         return false;
@@ -140,8 +140,8 @@ bool grpc_connectivity_state_notify_on_state_change(
   } else {
     if (tracker->current_state != *current) {
       *current = tracker->current_state;
-      grpc_exec_ctx_sched(exec_ctx, notify,
-                          GRPC_ERROR_REF(tracker->current_error), NULL);
+      grpc_closure_sched(exec_ctx, notify,
+                         GRPC_ERROR_REF(tracker->current_error));
     } else {
       grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w));
       w->current = current;
@@ -191,8 +191,8 @@ void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx,
       gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name,
               w->notify);
     }
-    grpc_exec_ctx_sched(exec_ctx, w->notify,
-                        GRPC_ERROR_REF(tracker->current_error), NULL);
+    grpc_closure_sched(exec_ctx, w->notify,
+                       GRPC_ERROR_REF(tracker->current_error));
     gpr_free(w);
   }
 }
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index b448126da8..0d24062c1e 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -68,7 +68,7 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx,
                        grpc_stream_refcount *refcount) {
 #endif
   if (gpr_unref(&refcount->refs)) {
-    grpc_exec_ctx_sched(exec_ctx, &refcount->destroy, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, &refcount->destroy, GRPC_ERROR_NONE);
   }
 }
 
@@ -82,7 +82,7 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
                           grpc_iomgr_cb_func cb, void *cb_arg) {
 #endif
   gpr_ref_init(&refcount->refs, initial_refs);
-  grpc_closure_init(&refcount->destroy, cb, cb_arg);
+  grpc_closure_init(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx);
 }
 
 static void move64(uint64_t *from, uint64_t *to) {
@@ -168,11 +168,10 @@ grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
 void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx,
                                                   grpc_transport_stream_op *op,
                                                   grpc_error *error) {
-  grpc_exec_ctx_sched(exec_ctx, op->recv_message_ready, GRPC_ERROR_REF(error),
-                      NULL);
-  grpc_exec_ctx_sched(exec_ctx, op->recv_initial_metadata_ready,
-                      GRPC_ERROR_REF(error), NULL);
-  grpc_exec_ctx_sched(exec_ctx, op->on_complete, error, NULL);
+  grpc_closure_sched(exec_ctx, op->recv_message_ready, GRPC_ERROR_REF(error));
+  grpc_closure_sched(exec_ctx, op->recv_initial_metadata_ready,
+                     GRPC_ERROR_REF(error));
+  grpc_closure_sched(exec_ctx, op->on_complete, error);
 }
 
 typedef struct {
@@ -196,7 +195,8 @@ static void add_error(grpc_transport_stream_op *op, grpc_error **which,
   cmd = gpr_malloc(sizeof(*cmd));
   cmd->error = error;
   cmd->then_call = op->on_complete;
-  grpc_closure_init(&cmd->closure, free_message, cmd);
+  grpc_closure_init(&cmd->closure, free_message, cmd,
+                    grpc_schedule_on_exec_ctx);
   op->on_complete = &cmd->closure;
   *which = error;
 }
@@ -269,14 +269,14 @@ typedef struct {
 static void destroy_made_transport_op(grpc_exec_ctx *exec_ctx, void *arg,
                                       grpc_error *error) {
   made_transport_op *op = arg;
-  grpc_exec_ctx_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error),
-                      NULL);
+  grpc_closure_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error));
   gpr_free(op);
 }
 
 grpc_transport_op *grpc_make_transport_op(grpc_closure *on_complete) {
   made_transport_op *op = gpr_malloc(sizeof(*op));
-  grpc_closure_init(&op->outer_on_complete, destroy_made_transport_op, op);
+  grpc_closure_init(&op->outer_on_complete, destroy_made_transport_op, op,
+                    grpc_schedule_on_exec_ctx);
   op->inner_on_complete = on_complete;
   memset(&op->op, 0, sizeof(op->op));
   op->op.on_consumed = &op->outer_on_complete;
@@ -292,8 +292,7 @@ typedef struct {
 static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg,
                                              grpc_error *error) {
   made_transport_stream_op *op = arg;
-  grpc_exec_ctx_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error),
-                      NULL);
+  grpc_closure_sched(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error));
   gpr_free(op);
 }
 
@@ -301,7 +300,7 @@ grpc_transport_stream_op *grpc_make_transport_stream_op(
     grpc_closure *on_complete) {
   made_transport_stream_op *op = gpr_malloc(sizeof(*op));
   grpc_closure_init(&op->outer_on_complete, destroy_made_transport_stream_op,
-                    op);
+                    op, grpc_schedule_on_exec_ctx);
   op->inner_on_complete = on_complete;
   memset(&op->op, 0, sizeof(op->op));
   op->op.on_complete = &op->outer_on_complete;
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 07fcd995d7..4d8f10860e 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -148,7 +148,7 @@ void grpc_run_bad_client_test(
 
   grpc_slice_buffer_init(&outgoing);
   grpc_slice_buffer_add(&outgoing, slice);
-  grpc_closure_init(&done_write_closure, done_write, &a);
+  grpc_closure_init(&done_write_closure, done_write, &a, grpc_schedule_on_exec_ctx);
 
   /* Write data */
   grpc_endpoint_write(&exec_ctx, sfd.client, &outgoing, &done_write_closure);
@@ -175,7 +175,7 @@ void grpc_run_bad_client_test(
       grpc_slice_buffer_init(&args.incoming);
       gpr_event_init(&args.read_done);
       grpc_closure read_done_closure;
-      grpc_closure_init(&read_done_closure, read_done, &args);
+      grpc_closure_init(&read_done_closure, read_done, &args, grpc_schedule_on_exec_ctx);
       grpc_endpoint_read(&exec_ctx, sfd.client, &args.incoming,
                          &read_done_closure);
       grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index b421720492..169323e0f7 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -108,16 +108,18 @@ int main(int argc, char **argv) {
   grpc_resolver *resolver = create_resolver(&exec_ctx, "dns:test");
   gpr_event ev1;
   gpr_event_init(&ev1);
-  grpc_resolver_next(&exec_ctx, resolver, &result,
-                     grpc_closure_create(on_done, &ev1));
+  grpc_resolver_next(
+      &exec_ctx, resolver, &result,
+      grpc_closure_create(on_done, &ev1, grpc_schedule_on_exec_ctx));
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(wait_loop(5, &ev1));
   GPR_ASSERT(result == NULL);
 
   gpr_event ev2;
   gpr_event_init(&ev2);
-  grpc_resolver_next(&exec_ctx, resolver, &result,
-                     grpc_closure_create(on_done, &ev2));
+  grpc_resolver_next(
+      &exec_ctx, resolver, &result,
+      grpc_closure_create(on_done, &ev2, grpc_schedule_on_exec_ctx));
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(wait_loop(30, &ev2));
   GPR_ASSERT(result != NULL);
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index a9fd85aea1..d6c8920ad0 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -68,8 +68,8 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   on_resolution_arg on_res_arg;
   memset(&on_res_arg, 0, sizeof(on_res_arg));
   on_res_arg.expected_server_name = uri->path;
-  grpc_closure *on_resolution =
-      grpc_closure_create(on_resolution_cb, &on_res_arg);
+  grpc_closure *on_resolution = grpc_closure_create(
+      on_resolution_cb, &on_res_arg, grpc_schedule_on_exec_ctx);
 
   grpc_resolver_next(&exec_ctx, resolver, &on_res_arg.resolver_result,
                      on_resolution);
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
index 11e57439d5..2082f65458 100644
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ b/test/core/client_channel/set_initial_connect_string_test.c
@@ -94,7 +94,7 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_tcp_server_acceptor *acceptor) {
   gpr_free(acceptor);
   test_tcp_server *server = arg;
-  grpc_closure_init(&on_read, handle_read, NULL);
+  grpc_closure_init(&on_read, handle_read, NULL, grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&state.incoming_buffer);
   grpc_slice_buffer_init(&state.temp_incoming_buffer);
   state.tcp = tcp;
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 30468558e8..f6a9cbeef9 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -147,8 +147,8 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_tcp_server_acceptor *acceptor) {
   gpr_free(acceptor);
   test_tcp_server *server = arg;
-  grpc_closure_init(&on_read, handle_read, NULL);
-  grpc_closure_init(&on_write, done_write, NULL);
+  grpc_closure_init(&on_read, handle_read, NULL, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&on_write, done_write, NULL, grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&state.temp_incoming_buffer);
   grpc_slice_buffer_init(&state.outgoing_buffer);
   state.tcp = tcp;
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index ed85030797..45d48720c6 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -87,7 +87,7 @@ static void fake_resolver_shutdown(grpc_exec_ctx* exec_ctx,
   gpr_mu_lock(&r->mu);
   if (r->next_completion != NULL) {
     *r->target_result = NULL;
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
   }
   gpr_mu_unlock(&r->mu);
@@ -100,7 +100,7 @@ static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
     grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
     *r->target_result =
         grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
-    grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
     r->next_completion = NULL;
   }
 }
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c
index 80865fc7a6..ca7d9e9f9a 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy.c
@@ -376,15 +376,20 @@ static void on_accept(grpc_exec_ctx* exec_ctx, void* arg,
   gpr_ref_init(&conn->refcount, 1);
   conn->pollset_set = grpc_pollset_set_create();
   grpc_pollset_set_add_pollset(exec_ctx, conn->pollset_set, proxy->pollset);
-  grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn);
-  grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done,
-                    conn);
-  grpc_closure_init(&conn->on_write_response_done, on_write_response_done,
-                    conn);
-  grpc_closure_init(&conn->on_client_read_done, on_client_read_done, conn);
-  grpc_closure_init(&conn->on_client_write_done, on_client_write_done, conn);
-  grpc_closure_init(&conn->on_server_read_done, on_server_read_done, conn);
-  grpc_closure_init(&conn->on_server_write_done, on_server_write_done, conn);
+  grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_write_response_done, on_write_response_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_client_read_done, on_client_read_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_client_write_done, on_client_write_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_server_read_done, on_server_read_done, conn,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&conn->on_server_write_done, on_server_write_done, conn,
+                    grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&conn->client_read_buffer);
   grpc_slice_buffer_init(&conn->client_deferred_write_buffer);
   grpc_slice_buffer_init(&conn->client_write_buffer);
@@ -471,7 +476,8 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
   gpr_free(proxy->proxy_name);
   grpc_channel_args_destroy(proxy->channel_args);
   grpc_closure destroyed;
-  grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
   gpr_free(proxy);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 746134c85b..8136f9312c 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -349,11 +349,11 @@ static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg,
     addrs->addrs = gpr_malloc(sizeof(*addrs->addrs));
     addrs->addrs[0].len = 0;
     *r->addrs = addrs;
-    grpc_exec_ctx_sched(exec_ctx, r->on_done, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, r->on_done, GRPC_ERROR_NONE);
   } else {
-    grpc_exec_ctx_sched(
+    grpc_closure_sched(
         exec_ctx, r->on_done,
-        GRPC_ERROR_CREATE_REFERENCING("Resolution failed", &error, 1), NULL);
+        GRPC_ERROR_CREATE_REFERENCING("Resolution failed", &error, 1));
   }
 
   gpr_free(r->addr);
@@ -398,7 +398,7 @@ static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   future_connect *fc = arg;
   if (error != GRPC_ERROR_NONE) {
     *fc->ep = NULL;
-    grpc_exec_ctx_sched(exec_ctx, fc->closure, GRPC_ERROR_REF(error), NULL);
+    grpc_closure_sched(exec_ctx, fc->closure, GRPC_ERROR_REF(error));
   } else if (g_server != NULL) {
     grpc_endpoint *client;
     grpc_endpoint *server;
@@ -410,7 +410,7 @@ static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
     grpc_server_setup_transport(exec_ctx, g_server, transport, NULL, NULL);
     grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
 
-    grpc_exec_ctx_sched(exec_ctx, fc->closure, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, fc->closure, GRPC_ERROR_NONE);
   } else {
     sched_connect(exec_ctx, fc->closure, fc->ep, fc->deadline);
   }
@@ -421,8 +421,8 @@ static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                           grpc_endpoint **ep, gpr_timespec deadline) {
   if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
     *ep = NULL;
-    grpc_exec_ctx_sched(exec_ctx, closure,
-                        GRPC_ERROR_CREATE("Connect deadline exceeded"), NULL);
+    grpc_closure_sched(exec_ctx, closure,
+                       GRPC_ERROR_CREATE("Connect deadline exceeded"));
     return;
   }
 
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index 21905b98fa..7a7129ceb1 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -217,9 +217,9 @@ static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg,
                                        &message);
     grpc_call_next_op(exec_ctx, elem, op);
   }
-  grpc_exec_ctx_sched(
+  grpc_closure_sched(
       exec_ctx, calld->recv_im_ready,
-      GRPC_ERROR_CREATE_REFERENCING("Forced call to close", &error, 1), NULL);
+      GRPC_ERROR_CREATE_REFERENCING("Forced call to close", &error, 1));
 }
 
 static void start_transport_stream_op(grpc_exec_ctx *exec_ctx,
@@ -228,7 +228,8 @@ static void start_transport_stream_op(grpc_exec_ctx *exec_ctx,
   call_data *calld = elem->call_data;
   if (op->recv_initial_metadata != NULL) {
     calld->recv_im_ready = op->recv_initial_metadata_ready;
-    op->recv_initial_metadata_ready = grpc_closure_create(recv_im_ready, elem);
+    op->recv_initial_metadata_ready =
+        grpc_closure_create(recv_im_ready, elem, grpc_schedule_on_exec_ctx);
   }
   grpc_call_next_op(exec_ctx, elem, op);
 }
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index 3e312c1dde..4f00cad205 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -90,9 +90,10 @@ static void test_get(int port) {
   grpc_http_response response;
   memset(&response, 0, sizeof(response));
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("test_get");
-  grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
-                   n_seconds_time(15),
-                   grpc_closure_create(on_finish, &response), &response);
+  grpc_httpcli_get(
+      &exec_ctx, &g_context, &g_pops, resource_quota, &req, n_seconds_time(15),
+      grpc_closure_create(on_finish, &response, grpc_schedule_on_exec_ctx),
+      &response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
@@ -130,9 +131,11 @@ static void test_post(int port) {
   grpc_http_response response;
   memset(&response, 0, sizeof(response));
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("test_post");
-  grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
-                    "hello", 5, n_seconds_time(15),
-                    grpc_closure_create(on_finish, &response), &response);
+  grpc_httpcli_post(
+      &exec_ctx, &g_context, &g_pops, resource_quota, &req, "hello", 5,
+      n_seconds_time(15),
+      grpc_closure_create(on_finish, &response, grpc_schedule_on_exec_ctx),
+      &response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
@@ -207,7 +210,8 @@ int main(int argc, char **argv) {
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pops, &g_pops);
+  grpc_closure_init(&destroyed, destroy_pops, &g_pops,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                         &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index d06035149e..53b26b645f 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -91,9 +91,10 @@ static void test_get(int port) {
   grpc_http_response response;
   memset(&response, 0, sizeof(response));
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("test_get");
-  grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
-                   n_seconds_time(15),
-                   grpc_closure_create(on_finish, &response), &response);
+  grpc_httpcli_get(
+      &exec_ctx, &g_context, &g_pops, resource_quota, &req, n_seconds_time(15),
+      grpc_closure_create(on_finish, &response, grpc_schedule_on_exec_ctx),
+      &response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
@@ -132,9 +133,11 @@ static void test_post(int port) {
   grpc_http_response response;
   memset(&response, 0, sizeof(response));
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("test_post");
-  grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
-                    "hello", 5, n_seconds_time(15),
-                    grpc_closure_create(on_finish, &response), &response);
+  grpc_httpcli_post(
+      &exec_ctx, &g_context, &g_pops, resource_quota, &req, "hello", 5,
+      n_seconds_time(15),
+      grpc_closure_create(on_finish, &response, grpc_schedule_on_exec_ctx),
+      &response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
@@ -210,7 +213,8 @@ int main(int argc, char **argv) {
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pops, &g_pops);
+  grpc_closure_init(&destroyed, destroy_pops, &g_pops,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
                         &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
index de03c47c13..773ef602b2 100644
--- a/test/core/internal_api_canaries/iomgr.c
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -60,9 +60,9 @@ static void test_code(void) {
   closure_list.head = NULL;
   closure_list.tail = NULL;
 
-  grpc_closure_init(&closure, NULL, NULL);
+  grpc_closure_init(&closure, NULL, NULL, grpc_schedule_on_exec_ctx);
 
-  grpc_closure_create(NULL, NULL);
+  grpc_closure_create(NULL, NULL, grpc_schedule_on_exec_ctx);
 
   grpc_closure_list_move(NULL, NULL);
   grpc_closure_list_append(NULL, NULL, GRPC_ERROR_CREATE("Foo"));
@@ -72,8 +72,8 @@ static void test_code(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_exec_ctx_flush(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_exec_ctx_sched(&exec_ctx, &closure, GRPC_ERROR_CREATE("Foo"), NULL);
-  grpc_exec_ctx_enqueue_list(&exec_ctx, &closure_list, NULL);
+  grpc_closure_sched(&exec_ctx, &closure, GRPC_ERROR_CREATE("Foo"));
+  grpc_closure_list_sched(&exec_ctx, &closure_list);
 
   /* endpoint.h */
   grpc_endpoint endpoint;
@@ -99,7 +99,6 @@ static void test_code(void) {
 
   /* executor.h */
   grpc_executor_init();
-  grpc_executor_push(&closure, GRPC_ERROR_CREATE("Phi"));
   grpc_executor_shutdown();
 
   /* pollset.h */
diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c
index f7d5809be7..9b6d6ff9b4 100644
--- a/test/core/iomgr/combiner_test.c
+++ b/test/core/iomgr/combiner_test.c
@@ -59,9 +59,10 @@ static void test_execute_one(void) {
   grpc_combiner *lock = grpc_combiner_create(NULL);
   bool done = false;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_combiner_execute(&exec_ctx, lock,
-                        grpc_closure_create(set_bool_to_true, &done),
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(&exec_ctx,
+                     grpc_closure_create(set_bool_to_true, &done,
+                                         grpc_combiner_scheduler(lock, false)),
+                     GRPC_ERROR_NONE);
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(done);
   grpc_combiner_destroy(&exec_ctx, lock);
@@ -94,9 +95,10 @@ static void execute_many_loop(void *a) {
       ex_args *c = gpr_malloc(sizeof(*c));
       c->ctr = &args->ctr;
       c->value = n++;
-      grpc_combiner_execute(&exec_ctx, args->lock,
-                            grpc_closure_create(check_one, c), GRPC_ERROR_NONE,
-                            false);
+      grpc_closure_sched(
+          &exec_ctx, grpc_closure_create(check_one, c, grpc_combiner_scheduler(
+                                                           args->lock, false)),
+          GRPC_ERROR_NONE);
       grpc_exec_ctx_flush(&exec_ctx);
     }
     // sleep for a little bit, to test a combiner draining and another thread
@@ -134,9 +136,10 @@ static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
 }
 
 static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
-  grpc_combiner_execute_finally(exec_ctx, arg,
-                                grpc_closure_create(in_finally, NULL),
-                                GRPC_ERROR_NONE, false);
+  grpc_closure_sched(exec_ctx, grpc_closure_create(
+                                   in_finally, NULL,
+                                   grpc_combiner_finally_scheduler(arg, false)),
+                     GRPC_ERROR_NONE);
 }
 
 static void test_execute_finally(void) {
@@ -144,8 +147,10 @@ static void test_execute_finally(void) {
 
   grpc_combiner *lock = grpc_combiner_create(NULL);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_combiner_execute(&exec_ctx, lock, grpc_closure_create(add_finally, lock),
-                        GRPC_ERROR_NONE, false);
+  grpc_closure_sched(&exec_ctx,
+                     grpc_closure_create(add_finally, lock,
+                                         grpc_combiner_scheduler(lock, false)),
+                     GRPC_ERROR_NONE);
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(got_in_finally);
   grpc_combiner_destroy(&exec_ctx, lock);
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 2a257a7cea..6899f6524a 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -81,7 +81,7 @@ int main(int argc, char **argv) {
   g_pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 8186ea7e85..87a9d79e9b 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -211,9 +211,10 @@ static void read_and_write_test(grpc_endpoint_test_config config,
   state.write_done = 0;
   state.current_read_data = 0;
   state.current_write_data = 0;
-  grpc_closure_init(&state.done_read, read_and_write_test_read_handler, &state);
+  grpc_closure_init(&state.done_read, read_and_write_test_read_handler, &state,
+                    grpc_schedule_on_exec_ctx);
   grpc_closure_init(&state.done_write, read_and_write_test_write_handler,
-                    &state);
+                    &state, grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&state.outgoing);
   grpc_slice_buffer_init(&state.incoming);
 
@@ -290,16 +291,19 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
   grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
-                     grpc_closure_create(inc_on_failure, &fail_count));
+                     grpc_closure_create(inc_on_failure, &fail_count,
+                                         grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 0);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
   wait_for_fail_count(&exec_ctx, &fail_count, 1);
   grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer,
-                     grpc_closure_create(inc_on_failure, &fail_count));
+                     grpc_closure_create(inc_on_failure, &fail_count,
+                                         grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 2);
   grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a"));
   grpc_endpoint_write(&exec_ctx, f.client_ep, &slice_buffer,
-                      grpc_closure_create(inc_on_failure, &fail_count));
+                      grpc_closure_create(inc_on_failure, &fail_count,
+                                          grpc_schedule_on_exec_ctx));
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 564b05d7f4..4fee4cb8c3 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -102,7 +102,7 @@ static void test_pollset_cleanup(grpc_exec_ctx *exec_ctx,
   int i;
 
   for (i = 0; i < num_pollsets; i++) {
-    grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].pollset);
+    grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].pollset, grpc_schedule_on_exec_ctx);
     grpc_pollset_shutdown(exec_ctx, pollsets[i].pollset, &destroyed);
 
     grpc_exec_ctx_flush(exec_ctx);
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 6166699fe6..e7abecdb46 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -546,7 +546,7 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   test_grpc_fd();
   test_grpc_fd_change();
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index e4136a7a7a..d844e6eceb 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -71,7 +71,8 @@ void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) {
   grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset);
   grpc_pollset_set_destroy(args->pollset_set);
   grpc_closure do_nothing_cb;
-  grpc_closure_init(&do_nothing_cb, do_nothing, NULL);
+  grpc_closure_init(&do_nothing_cb, do_nothing, NULL,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(exec_ctx, args->pollset, &do_nothing_cb);
   // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
   grpc_exec_ctx_flush(exec_ctx);
@@ -136,8 +137,10 @@ static void test_localhost(void) {
   args_struct args;
   args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
-  grpc_resolve_address(&exec_ctx, "localhost:1", NULL, args.pollset_set,
-                       grpc_closure_create(must_succeed, &args), &args.addrs);
+  grpc_resolve_address(
+      &exec_ctx, "localhost:1", NULL, args.pollset_set,
+      grpc_closure_create(must_succeed, &args, grpc_schedule_on_exec_ctx),
+      &args.addrs);
   args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -147,8 +150,10 @@ static void test_default_port(void) {
   args_struct args;
   args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
-  grpc_resolve_address(&exec_ctx, "localhost", "1", args.pollset_set,
-                       grpc_closure_create(must_succeed, &args), &args.addrs);
+  grpc_resolve_address(
+      &exec_ctx, "localhost", "1", args.pollset_set,
+      grpc_closure_create(must_succeed, &args, grpc_schedule_on_exec_ctx),
+      &args.addrs);
   args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -158,8 +163,10 @@ static void test_missing_default_port(void) {
   args_struct args;
   args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
-  grpc_resolve_address(&exec_ctx, "localhost", NULL, args.pollset_set,
-                       grpc_closure_create(must_fail, &args), &args.addrs);
+  grpc_resolve_address(
+      &exec_ctx, "localhost", NULL, args.pollset_set,
+      grpc_closure_create(must_fail, &args, grpc_schedule_on_exec_ctx),
+      &args.addrs);
   args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -169,8 +176,10 @@ static void test_ipv6_with_port(void) {
   args_struct args;
   args_init(&exec_ctx, &args);
   poll_pollset_until_request_done(&args);
-  grpc_resolve_address(&exec_ctx, "[2001:db8::1]:1", NULL, args.pollset_set,
-                       grpc_closure_create(must_succeed, &args), &args.addrs);
+  grpc_resolve_address(
+      &exec_ctx, "[2001:db8::1]:1", NULL, args.pollset_set,
+      grpc_closure_create(must_succeed, &args, grpc_schedule_on_exec_ctx),
+      &args.addrs);
   args_finish(&exec_ctx, &args);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -185,8 +194,10 @@ static void test_ipv6_without_port(void) {
     args_struct args;
     args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
-    grpc_resolve_address(&exec_ctx, kCases[i], "80", args.pollset_set,
-                         grpc_closure_create(must_succeed, &args), &args.addrs);
+    grpc_resolve_address(
+        &exec_ctx, kCases[i], "80", args.pollset_set,
+        grpc_closure_create(must_succeed, &args, grpc_schedule_on_exec_ctx),
+        &args.addrs);
     args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
   }
@@ -202,8 +213,10 @@ static void test_invalid_ip_addresses(void) {
     args_struct args;
     args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
-    grpc_resolve_address(&exec_ctx, kCases[i], NULL, args.pollset_set,
-                         grpc_closure_create(must_fail, &args), &args.addrs);
+    grpc_resolve_address(
+        &exec_ctx, kCases[i], NULL, args.pollset_set,
+        grpc_closure_create(must_fail, &args, grpc_schedule_on_exec_ctx),
+        &args.addrs);
     args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
   }
@@ -219,8 +232,10 @@ static void test_unparseable_hostports(void) {
     args_struct args;
     args_init(&exec_ctx, &args);
     poll_pollset_until_request_done(&args);
-    grpc_resolve_address(&exec_ctx, kCases[i], "1", args.pollset_set,
-                         grpc_closure_create(must_fail, &args), &args.addrs);
+    grpc_resolve_address(
+        &exec_ctx, kCases[i], "1", args.pollset_set,
+        grpc_closure_create(must_fail, &args, grpc_schedule_on_exec_ctx),
+        &args.addrs);
     args_finish(&exec_ctx, &args);
     grpc_exec_ctx_finish(&exec_ctx);
   }
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index a82d44f7f8..181776341f 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -45,7 +45,9 @@ static void inc_int_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
 static void set_bool_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
   *(bool *)a = true;
 }
-grpc_closure *set_bool(bool *p) { return grpc_closure_create(set_bool_cb, p); }
+grpc_closure *set_bool(bool *p) {
+  return grpc_closure_create(set_bool_cb, p, grpc_schedule_on_exec_ctx);
+}
 
 typedef struct {
   size_t size;
@@ -67,7 +69,7 @@ grpc_closure *make_reclaimer(grpc_resource_user *resource_user, size_t size,
   a->size = size;
   a->resource_user = resource_user;
   a->then = then;
-  return grpc_closure_create(reclaimer_cb, a);
+  return grpc_closure_create(reclaimer_cb, a, grpc_schedule_on_exec_ctx);
 }
 
 static void unused_reclaimer_cb(grpc_exec_ctx *exec_ctx, void *arg,
@@ -76,7 +78,8 @@ static void unused_reclaimer_cb(grpc_exec_ctx *exec_ctx, void *arg,
   grpc_closure_run(exec_ctx, arg, GRPC_ERROR_NONE);
 }
 grpc_closure *make_unused_reclaimer(grpc_closure *then) {
-  return grpc_closure_create(unused_reclaimer_cb, then);
+  return grpc_closure_create(unused_reclaimer_cb, then,
+                             grpc_schedule_on_exec_ctx);
 }
 
 static void destroy_user(grpc_resource_user *usr) {
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index 5fab826fb7..2100fd4c2f 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -113,7 +113,7 @@ void test_succeeds(void) {
   /* connect to it */
   GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)addr,
                          (socklen_t *)&resolved_addr.len) == 0);
-  grpc_closure_init(&done, must_succeed, NULL);
+  grpc_closure_init(&done, must_succeed, NULL, grpc_schedule_on_exec_ctx);
   grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
                           &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
 
@@ -163,7 +163,7 @@ void test_fails(void) {
   gpr_mu_unlock(g_mu);
 
   /* connect to a broken address */
-  grpc_closure_init(&done, must_fail, NULL);
+  grpc_closure_init(&done, must_fail, NULL, grpc_schedule_on_exec_ctx);
   grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL,
                           &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME));
 
@@ -207,7 +207,7 @@ int main(int argc, char **argv) {
   gpr_log(GPR_ERROR, "End of first test");
   test_fails();
   grpc_pollset_set_destroy(g_pollset_set);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 5eafa570bb..340b807047 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -194,7 +194,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
   state.read_bytes = 0;
   state.target_read_bytes = written_bytes;
   grpc_slice_buffer_init(&state.incoming);
-  grpc_closure_init(&state.read_cb, read_cb, &state);
+  grpc_closure_init(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx);
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
@@ -245,7 +245,7 @@ static void large_read_test(size_t slice_size) {
   state.read_bytes = 0;
   state.target_read_bytes = (size_t)written_bytes;
   grpc_slice_buffer_init(&state.incoming);
-  grpc_closure_init(&state.read_cb, read_cb, &state);
+  grpc_closure_init(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx);
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
@@ -384,7 +384,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
 
   grpc_slice_buffer_init(&outgoing);
   grpc_slice_buffer_addn(&outgoing, slices, num_blocks);
-  grpc_closure_init(&write_done_closure, write_done, &state);
+  grpc_closure_init(&write_done_closure, write_done, &state, grpc_schedule_on_exec_ctx);
 
   grpc_endpoint_write(&exec_ctx, ep, &outgoing, &write_done_closure);
   drain_socket_blocking(sv[0], num_bytes, num_bytes);
@@ -429,7 +429,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure fd_released_cb;
   int fd_released_done = 0;
-  grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done);
+  grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done, grpc_schedule_on_exec_ctx);
 
   gpr_log(GPR_INFO,
           "Release fd read_test of size %" PRIuPTR ", slice size %" PRIuPTR,
@@ -452,7 +452,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   state.read_bytes = 0;
   state.target_read_bytes = written_bytes;
   grpc_slice_buffer_init(&state.incoming);
-  grpc_closure_init(&state.read_cb, read_cb, &state);
+  grpc_closure_init(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx);
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
@@ -561,7 +561,7 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
   run_tests();
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 9a7810e227..020f005980 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -104,7 +104,7 @@ static void server_weak_ref_shutdown(grpc_exec_ctx *exec_ctx, void *arg,
 static void server_weak_ref_init(server_weak_ref *weak_ref) {
   weak_ref->server = NULL;
   grpc_closure_init(&weak_ref->server_shutdown, server_weak_ref_shutdown,
-                    weak_ref);
+                    weak_ref, grpc_schedule_on_exec_ctx);
 }
 
 /* Make weak_ref->server_shutdown a shutdown_starting cb on server.
@@ -366,7 +366,8 @@ int main(int argc, char **argv) {
   test_connect(1);
   test_connect(10);
 
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 9bea229466..67ef81fab2 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -234,7 +234,7 @@ int main(int argc, char **argv) {
   test_receive(1);
   test_receive(10);
 
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d4c755088d..d624a38438 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -565,7 +565,7 @@ static int compute_engine_httpcli_get_success_override(
     grpc_httpcli_response *response) {
   validate_compute_engine_http_request(request);
   *response = http_response(200, valid_oauth2_json_response);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -575,7 +575,7 @@ static int compute_engine_httpcli_get_failure_override(
     grpc_httpcli_response *response) {
   validate_compute_engine_http_request(request);
   *response = http_response(403, "Not Authorized.");
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -668,7 +668,7 @@ static int refresh_token_httpcli_post_success(
     grpc_closure *on_done, grpc_httpcli_response *response) {
   validate_refresh_token_http_request(request, body, body_size);
   *response = http_response(200, valid_oauth2_json_response);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -678,7 +678,7 @@ static int refresh_token_httpcli_post_failure(
     grpc_closure *on_done, grpc_httpcli_response *response) {
   validate_refresh_token_http_request(request, body, body_size);
   *response = http_response(403, "Not Authorized.");
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -917,7 +917,7 @@ static int default_creds_gce_detection_httpcli_get_success_override(
   response->hdrs = headers;
   GPR_ASSERT(strcmp(request->http.path, "/") == 0);
   GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -975,7 +975,7 @@ static int default_creds_gce_detection_httpcli_get_failure_override(
   GPR_ASSERT(strcmp(request->http.path, "/") == 0);
   GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
   *response = http_response(200, "");
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index 9a21814adc..a4d65dccd9 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -346,7 +346,7 @@ static int httpcli_get_google_keys_for_email(
                     "/robot/v1/metadata/x509/"
                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
                     "gserviceaccount.com") == 0);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -390,7 +390,7 @@ static int httpcli_get_custom_keys_for_email(
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
   GPR_ASSERT(strcmp(request->host, "keys.bar.com") == 0);
   GPR_ASSERT(strcmp(request->http.path, "/jwk/foo@bar.com") == 0);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -424,7 +424,7 @@ static int httpcli_get_jwk_set(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
   GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
   GPR_ASSERT(strcmp(request->http.path, "/oauth2/v3/certs") == 0);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -439,7 +439,7 @@ static int httpcli_get_openid_config(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(strcmp(request->http.path, GRPC_OPENID_CONFIG_URL_SUFFIX) == 0);
   grpc_httpcli_set_override(httpcli_get_jwk_set,
                             httpcli_post_should_not_be_called);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
@@ -479,7 +479,7 @@ static int httpcli_get_bad_json(grpc_exec_ctx *exec_ctx,
                                 grpc_httpcli_response *response) {
   *response = http_response(200, gpr_strdup("{\"bad\": \"stuff\"}"));
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
-  grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, on_done, GRPC_ERROR_NONE);
   return 1;
 }
 
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index 44a209258d..ff77af908a 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -92,7 +92,8 @@ char *grpc_test_fetch_oauth2_token_with_credentials(
   request.pops = grpc_polling_entity_create_from_pollset(pollset);
   request.is_done = 0;
 
-  grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
+  grpc_closure_init(&do_nothing_closure, do_nothing, NULL,
+                    grpc_schedule_on_exec_ctx);
 
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, creds, &request.pops, null_ctx, on_oauth2_response, &request);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index b5d95004fe..a004fc0b41 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -158,7 +158,7 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
   gpr_log(GPR_INFO, "Start test left over");
 
   grpc_slice_buffer_init(&incoming);
-  grpc_closure_init(&done_closure, inc_call_ctr, &n);
+  grpc_closure_init(&done_closure, inc_call_ctr, &n, grpc_schedule_on_exec_ctx);
   grpc_endpoint_read(&exec_ctx, f.client_ep, &incoming, &done_closure);
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(n == 1);
@@ -191,7 +191,7 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
   test_leftover(configs[1], 1);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c
index 93a4794222..8ebe8d07e4 100644
--- a/test/core/surface/concurrent_connectivity_test.c
+++ b/test/core/surface/concurrent_connectivity_test.c
@@ -229,9 +229,9 @@ int main(int argc, char **argv) {
   gpr_atm_rel_store(&args.stop, 1);
   gpr_thd_join(server);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_pollset_shutdown(
-      &exec_ctx, args.pollset,
-      grpc_closure_create(done_pollset_shutdown, args.pollset));
+  grpc_pollset_shutdown(&exec_ctx, args.pollset,
+                        grpc_closure_create(done_pollset_shutdown, args.pollset,
+                                            grpc_schedule_on_exec_ctx));
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_shutdown();
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 6afcefca92..af36a2d734 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -62,7 +62,7 @@ void test_transport_op(grpc_channel *channel) {
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  grpc_closure_init(&transport_op_cb, verify_connectivity, &state);
+  grpc_closure_init(&transport_op_cb, verify_connectivity, &state, grpc_schedule_on_exec_ctx);
 
   op = grpc_make_transport_op(NULL);
   op->on_connectivity_state_change = &transport_op_cb;
@@ -71,7 +71,7 @@ void test_transport_op(grpc_channel *channel) {
   elem->filter->start_transport_op(&exec_ctx, elem, op);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_closure_init(&transport_op_cb, do_nothing, NULL);
+  grpc_closure_init(&transport_op_cb, do_nothing, NULL, grpc_schedule_on_exec_ctx);
   op = grpc_make_transport_op(&transport_op_cb);
   elem->filter->start_transport_op(&exec_ctx, elem, op);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c
index 1050059eff..1a347354f4 100644
--- a/test/core/transport/connectivity_state_test.c
+++ b/test/core/transport/connectivity_state_test.c
@@ -86,7 +86,7 @@ static void test_check(void) {
 
 static void test_subscribe_then_unsubscribe(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG);
+  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_then_unsubscribe");
@@ -109,7 +109,7 @@ static void test_subscribe_then_unsubscribe(void) {
 
 static void test_subscribe_then_destroy(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_succeed, THE_ARG);
+  grpc_closure *closure = grpc_closure_create(must_succeed, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_then_destroy");
@@ -128,7 +128,7 @@ static void test_subscribe_then_destroy(void) {
 
 static void test_subscribe_with_failure_then_destroy(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG);
+  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_with_failure_then_destroy");
diff --git a/test/core/util/mock_endpoint.c b/test/core/util/mock_endpoint.c
index bf6d85252a..04793bceab 100644
--- a/test/core/util/mock_endpoint.c
+++ b/test/core/util/mock_endpoint.c
@@ -55,7 +55,7 @@ static void me_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   gpr_mu_lock(&m->mu);
   if (m->read_buffer.count > 0) {
     grpc_slice_buffer_swap(&m->read_buffer, slices);
-    grpc_exec_ctx_sched(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
   } else {
     m->on_read = cb;
     m->on_read_out = slices;
@@ -69,7 +69,7 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   for (size_t i = 0; i < slices->count; i++) {
     m->on_write(slices->slices[i]);
   }
-  grpc_exec_ctx_sched(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
 }
 
 static void me_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -82,8 +82,8 @@ static void me_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
   grpc_mock_endpoint *m = (grpc_mock_endpoint *)ep;
   gpr_mu_lock(&m->mu);
   if (m->on_read) {
-    grpc_exec_ctx_sched(exec_ctx, m->on_read,
-                        GRPC_ERROR_CREATE("Endpoint Shutdown"), NULL);
+    grpc_closure_sched(exec_ctx, m->on_read,
+                       GRPC_ERROR_CREATE("Endpoint Shutdown"));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->mu);
@@ -144,7 +144,7 @@ void grpc_mock_endpoint_put_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   gpr_mu_lock(&m->mu);
   if (m->on_read != NULL) {
     grpc_slice_buffer_add(m->on_read_out, slice);
-    grpc_exec_ctx_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE);
     m->on_read = NULL;
   } else {
     grpc_slice_buffer_add(&m->read_buffer, slice);
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index b3405f02e9..15ba092c5b 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -63,11 +63,10 @@ static void me_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   half *m = (half *)ep;
   gpr_mu_lock(&m->parent->mu);
   if (m->parent->shutdown) {
-    grpc_exec_ctx_sched(exec_ctx, cb, GRPC_ERROR_CREATE("Already shutdown"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE("Already shutdown"));
   } else if (m->read_buffer.count > 0) {
     grpc_slice_buffer_swap(&m->read_buffer, slices);
-    grpc_exec_ctx_sched(exec_ctx, cb, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE);
   } else {
     m->on_read = cb;
     m->on_read_out = slices;
@@ -91,7 +90,7 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     for (size_t i = 0; i < slices->count; i++) {
       grpc_slice_buffer_add(m->on_read_out, grpc_slice_ref(slices->slices[i]));
     }
-    grpc_exec_ctx_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE, NULL);
+    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE);
     m->on_read = NULL;
   } else {
     for (size_t i = 0; i < slices->count; i++) {
@@ -99,7 +98,7 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     }
   }
   gpr_mu_unlock(&m->parent->mu);
-  grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
+  grpc_closure_sched(exec_ctx, cb, error);
 }
 
 static void me_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -113,14 +112,12 @@ static void me_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
   gpr_mu_lock(&m->parent->mu);
   m->parent->shutdown = true;
   if (m->on_read) {
-    grpc_exec_ctx_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"));
     m->on_read = NULL;
   }
   m = other_half(m);
   if (m->on_read) {
-    grpc_exec_ctx_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"),
-                        NULL);
+    grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_CREATE("Shutdown"));
     m->on_read = NULL;
   }
   gpr_mu_unlock(&m->parent->mu);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index b2342feeb4..0bde726ba1 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -92,7 +92,8 @@ void grpc_free_port_using_server(char *server, int port) {
   grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(pollset, &pr.mu);
   pr.pops = grpc_polling_entity_create_from_pollset(pollset);
-  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops);
+  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
+                                         grpc_schedule_on_exec_ctx);
 
   req.host = server;
   gpr_asprintf(&path, "/drop/%d", port);
@@ -103,7 +104,9 @@ void grpc_free_port_using_server(char *server, int port) {
       grpc_resource_quota_create("port_server_client/free");
   grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
-                   grpc_closure_create(freed_port_from_server, &pr), &rsp);
+                   grpc_closure_create(freed_port_from_server, &pr,
+                                       grpc_schedule_on_exec_ctx),
+                   &rsp);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   gpr_mu_lock(pr.mu);
   while (!pr.done) {
@@ -174,7 +177,8 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
         grpc_resource_quota_create("port_server_client/pick_retry");
     grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pops, resource_quota, &req,
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
-                     grpc_closure_create(got_port_from_server, pr),
+                     grpc_closure_create(got_port_from_server, pr,
+                                         grpc_schedule_on_exec_ctx),
                      &pr->response);
     grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
     return;
@@ -208,7 +212,8 @@ int grpc_pick_port_using_server(char *server) {
   grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(pollset, &pr.mu);
   pr.pops = grpc_polling_entity_create_from_pollset(pollset);
-  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops);
+  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
+                                         grpc_schedule_on_exec_ctx);
   pr.port = -1;
   pr.server = server;
   pr.ctx = &context;
@@ -219,10 +224,11 @@ int grpc_pick_port_using_server(char *server) {
   grpc_httpcli_context_init(&context);
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("port_server_client/pick");
-  grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
-                   grpc_closure_create(got_port_from_server, &pr),
-                   &pr.response);
+  grpc_httpcli_get(
+      &exec_ctx, &context, &pr.pops, resource_quota, &req,
+      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
+      grpc_closure_create(got_port_from_server, &pr, grpc_schedule_on_exec_ctx),
+      &pr.response);
   grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_mu_lock(pr.mu);
diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c
index 16df91d968..af085dee47 100644
--- a/test/core/util/test_tcp_server.c
+++ b/test/core/util/test_tcp_server.c
@@ -57,7 +57,7 @@ void test_tcp_server_init(test_tcp_server *server,
                           grpc_tcp_server_cb on_connect, void *user_data) {
   grpc_init();
   server->tcp_server = NULL;
-  grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server);
+  grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server, grpc_schedule_on_exec_ctx);
   server->shutdown = 0;
   server->pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(server->pollset, &server->mu);
@@ -111,7 +111,7 @@ void test_tcp_server_destroy(test_tcp_server *server) {
   gpr_timespec shutdown_deadline;
   grpc_closure do_nothing_cb;
   grpc_tcp_server_unref(&exec_ctx, server->tcp_server);
-  grpc_closure_init(&do_nothing_cb, do_nothing, NULL);
+  grpc_closure_init(&do_nothing_cb, do_nothing, NULL, grpc_schedule_on_exec_ctx);
   shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                    gpr_time_from_seconds(5, GPR_TIMESPAN));
   while (!server->shutdown &&
-- 
GitLab


From 3cb3447e49b81dc2e4dcb66170eda3b04766eaba Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 28 Dec 2016 16:11:38 -0800
Subject: [PATCH 203/344] Fix some uninitialized variables

---
 src/core/lib/iomgr/tcp_posix.c        |  8 ++++----
 src/core/lib/iomgr/tcp_server_posix.c | 12 ++++++------
 src/core/lib/surface/server.c         |  4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 1000776d61..21a0371d10 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -551,10 +551,10 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd,
   gpr_ref_init(&tcp->refcount, 1);
   gpr_atm_no_barrier_store(&tcp->shutdown_count, 0);
   tcp->em_fd = em_fd;
-  tcp->read_closure.cb = tcp_handle_read;
-  tcp->read_closure.cb_arg = tcp;
-  tcp->write_closure.cb = tcp_handle_write;
-  tcp->write_closure.cb_arg = tcp;
+  grpc_closure_init(&tcp->read_closure, tcp_handle_read, tcp,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&tcp->write_closure, tcp_handle_write, tcp,
+                    grpc_schedule_on_exec_ctx);
   grpc_slice_buffer_init(&tcp->last_read_buffer);
   tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string);
   grpc_resource_user_slice_allocator_init(
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index e7eae19cf3..6db624dd56 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -254,8 +254,8 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
     grpc_tcp_listener *sp;
     for (sp = s->head; sp; sp = sp->next) {
       grpc_unlink_if_unix_domain_socket(&sp->addr);
-      sp->destroyed_closure.cb = destroyed_port;
-      sp->destroyed_closure.cb_arg = s;
+      grpc_closure_init(&sp->destroyed_closure, destroyed_port, s,
+                        grpc_schedule_on_exec_ctx);
       grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
                      "tcp_listener_shutdown");
     }
@@ -723,8 +723,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
           "clone_port", clone_port(sp, (unsigned)(pollset_count - 1))));
       for (i = 0; i < pollset_count; i++) {
         grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
-        sp->read_closure.cb = on_read;
-        sp->read_closure.cb_arg = sp;
+        grpc_closure_init(&sp->read_closure, on_read, sp,
+                          grpc_schedule_on_exec_ctx);
         grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
         s->active_ports++;
         sp = sp->next;
@@ -733,8 +733,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
       for (i = 0; i < pollset_count; i++) {
         grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
       }
-      sp->read_closure.cb = on_read;
-      sp->read_closure.cb_arg = sp;
+      grpc_closure_init(&sp->read_closure, on_read, sp,
+                        grpc_schedule_on_exec_ctx);
       grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
       s->active_ports++;
       sp = sp->next;
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index d143ad9607..78699e9e65 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -441,8 +441,8 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand,
   orphan_channel(chand);
   server_ref(chand->server);
   maybe_finish_shutdown(exec_ctx, chand->server);
-  chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
-  chand->finish_destroy_channel_closure.cb_arg = chand;
+  grpc_closure_init(&chand->finish_destroy_channel_closure,
+                    finish_destroy_channel, chand, grpc_schedule_on_exec_ctx);
 
   if (grpc_server_channel_trace && error != GRPC_ERROR_NONE) {
     const char *msg = grpc_error_string(error);
-- 
GitLab


From 0d62d7e8d763022ff46567842a5961e99a0da1d1 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Wed, 28 Dec 2016 14:28:44 -0800
Subject: [PATCH 204/344] Add `auto-gen`d comment to `_pb2_grpc.py` files

---
 src/compiler/python_generator.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 0fac1b88cd..4841da8da8 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -724,6 +724,9 @@ pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
     out = &out_printer;
 
     if (generate_in_pb2_grpc) {
+      out->Print(
+          "# Generated by the gRPC Python protocol compiler plugin. "
+          "DO NOT EDIT!\n");
       if (!PrintPreamble()) {
         return make_pair(false, "");
       }
-- 
GitLab


From a13ec951b996b855a4e82a22269cc9693a51b030 Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Thu, 29 Dec 2016 09:44:25 +0800
Subject: [PATCH 205/344] Remove for loop initial declarations

---
 src/core/lib/support/string.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index f263f82baf..426fce28f8 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -279,7 +279,8 @@ int gpr_stricmp(const char *a, const char *b) {
 void *gpr_memrchr(const void *s, int c, size_t n) {
   if (s == NULL) return NULL;
   char *b = (char *)s;
-  for (size_t i = 0; i < n; i++) {
+  size_t i;
+  for (i = 0; i < n; i++) {
     if (b[n - i - 1] == c) {
       return &b[n - i - 1];
     }
-- 
GitLab


From d0386f940e2decde901e707233c596ebc6720f88 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Thu, 29 Dec 2016 17:42:03 +0000
Subject: [PATCH 206/344] Exempt generated Python from copyright check

Some of these files contain the magic string "DO NOT EDIT" but we do
not wish for our tests to depend upon that.
---
 tools/distrib/check_copyright.py | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index f06e5f1d1a..51852adfd3 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -92,9 +92,20 @@ LICENSE_PREFIX = {
   'LICENSE':    '',
 }
 
-KNOWN_BAD = set([
+_EXEMPT = frozenset((
+  # Generated protocol compiler output.
+  'examples/python/helloworld/helloworld_pb2.py',
+  'examples/python/helloworld/helloworld_pb2_grpc.py',
+  'examples/python/multiplex/helloworld_pb2.py',
+  'examples/python/multiplex/helloworld_pb2_grpc.py',
+  'examples/python/multiplex/route_guide_pb2.py',
+  'examples/python/multiplex/route_guide_pb2_grpc.py',
+  'examples/python/route_guide/route_guide_pb2.py',
+  'examples/python/route_guide/route_guide_pb2_grpc.py',
+
+  # An older file originally from outside gRPC.
   'src/php/tests/bootstrap.php',
-])
+))
 
 
 RE_YEAR = r'Copyright (?P<first_year>[0-9]+\-)?(?P<last_year>[0-9]+), Google Inc\.'
@@ -140,7 +151,8 @@ except subprocess.CalledProcessError:
   sys.exit(0)
 
 for filename in filename_list:
-  if filename in KNOWN_BAD: continue
+  if filename in _EXEMPT:
+    continue
   ext = os.path.splitext(filename)[1]
   base = os.path.basename(filename)
   if ext in RE_LICENSE:
-- 
GitLab


From d6887e0e4eaa68c10145cd2f730da8fb709a0588 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 29 Dec 2016 10:11:40 -0800
Subject: [PATCH 207/344] Some fixes

---
 src/core/lib/iomgr/executor.c         | 2 ++
 src/core/lib/iomgr/tcp_client_posix.c | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 37a7142792..5f2a789e30 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -115,6 +115,8 @@ static void maybe_spawn_locked() {
 static void executor_push(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                           grpc_error *error) {
   gpr_mu_lock(&g_executor.mu);
+  GPR_ASSERT(closure->scheduler == grpc_executor_scheduler);
+  closure->scheduler = grpc_schedule_on_exec_ctx;
   if (g_executor.shutting_down == 0) {
     grpc_closure_list_append(&g_executor.closures, closure, error);
     maybe_spawn_locked();
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index be7b695ad6..d089d2bc3b 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -342,8 +342,8 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
   addr_str = NULL;
   gpr_mu_init(&ac->mu);
   ac->refs = 2;
-  ac->write_closure.cb = on_writable;
-  ac->write_closure.cb_arg = ac;
+  grpc_closure_init(&ac->write_closure, on_writable, ac,
+                    grpc_schedule_on_exec_ctx);
   ac->channel_args = grpc_channel_args_copy(channel_args);
 
   if (grpc_tcp_trace) {
-- 
GitLab


From 2fab0e78b0e48ad9b5504a90c8f44e7547162a6d Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Thu, 29 Dec 2016 18:41:31 +0000
Subject: [PATCH 208/344] Rename interop-as-a-unit-test "intraop"

It's been confusing that these tests have been called "interop" but
are not actually tests of interoperation.
---
 ...{_insecure_interop_test.py => _insecure_intraop_test.py} | 6 +++---
 .../{_interop_test_case.py => _intraop_test_case.py}        | 2 +-
 .../{_secure_interop_test.py => _secure_intraop_test.py}    | 6 +++---
 src/python/grpcio_tests/tests/tests.json                    | 4 ++--
 4 files changed, 9 insertions(+), 9 deletions(-)
 rename src/python/grpcio_tests/tests/interop/{_insecure_interop_test.py => _insecure_intraop_test.py} (95%)
 rename src/python/grpcio_tests/tests/interop/{_interop_test_case.py => _intraop_test_case.py} (98%)
 rename src/python/grpcio_tests/tests/interop/{_secure_interop_test.py => _secure_intraop_test.py} (95%)

diff --git a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
similarity index 95%
rename from src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
rename to src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
index 936c895bd2..4fb22b4d9d 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
@@ -35,13 +35,13 @@ import unittest
 import grpc
 from src.proto.grpc.testing import test_pb2
 
-from tests.interop import _interop_test_case
+from tests.interop import _intraop_test_case
 from tests.interop import methods
 from tests.interop import server
 
 
-class InsecureInteropTest(
-    _interop_test_case.InteropTestCase,
+class InsecureIntraopTest(
+    _intraop_test_case.IntraopTestCase,
     unittest.TestCase):
 
   def setUp(self):
diff --git a/src/python/grpcio_tests/tests/interop/_interop_test_case.py b/src/python/grpcio_tests/tests/interop/_intraop_test_case.py
similarity index 98%
rename from src/python/grpcio_tests/tests/interop/_interop_test_case.py
rename to src/python/grpcio_tests/tests/interop/_intraop_test_case.py
index ccea17a66d..fe1c173992 100644
--- a/src/python/grpcio_tests/tests/interop/_interop_test_case.py
+++ b/src/python/grpcio_tests/tests/interop/_intraop_test_case.py
@@ -32,7 +32,7 @@
 from tests.interop import methods
 
 
-class InteropTestCase(object):
+class IntraopTestCase(object):
   """Unit test methods.
 
   This class must be mixed in with unittest.TestCase and a class that defines
diff --git a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
similarity index 95%
rename from src/python/grpcio_tests/tests/interop/_secure_interop_test.py
rename to src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
index eaca553e1b..3665c69726 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
@@ -35,15 +35,15 @@ import unittest
 import grpc
 from src.proto.grpc.testing import test_pb2
 
-from tests.interop import _interop_test_case
+from tests.interop import _intraop_test_case
 from tests.interop import methods
 from tests.interop import resources
 
 _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
 
-class SecureInteropTest(
-    _interop_test_case.InteropTestCase,
+class SecureIntraopTest(
+    _intraop_test_case.IntraopTestCase,
     unittest.TestCase):
 
   def setUp(self):
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index c31a5f9d33..0109ee2173 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -1,7 +1,7 @@
 [
   "health_check._health_servicer_test.HealthServicerTest",
-  "interop._insecure_interop_test.InsecureInteropTest",
-  "interop._secure_interop_test.SecureInteropTest",
+  "interop._insecure_intraop_test.InsecureIntraopTest",
+  "interop._secure_intraop_test.SecureIntraopTest",
   "protoc_plugin._python_plugin_test.PythonPluginTest",
   "protoc_plugin._split_definitions_test.SameCommonTest",
   "protoc_plugin._split_definitions_test.SameSeparateTest",
-- 
GitLab


From 061ef740c0822326e58f1b47f91cc19ba02c7088 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 29 Dec 2016 10:54:09 -0800
Subject: [PATCH 209/344] Some fixes

---
 src/core/lib/iomgr/ev_epoll_linux.c |  4 +++-
 src/core/lib/iomgr/exec_ctx.c       |  4 +++-
 src/core/lib/iomgr/executor.c       | 26 ++++++++++++++++++++------
 test/core/iomgr/fd_posix_test.c     | 23 ++++++++++++-----------
 4 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index ac94d2e634..e8daa1f52c 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -1420,7 +1420,9 @@ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
         workqueue_maybe_wakeup(pi);
       }
       grpc_closure *c = (grpc_closure *)n;
-      grpc_closure_run(exec_ctx, c, c->error_data.error);
+      grpc_error *error = c->error_data.error;
+      c->cb(exec_ctx, c->cb_arg, error);
+      GRPC_ERROR_UNREF(error);
       return true;
     } else if (gpr_atm_no_barrier_load(&pi->workqueue_item_count) > 0) {
       /* n == NULL might mean there's work but it's not available to be popped
diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c
index c243bc803f..6aa788f8e5 100644
--- a/src/core/lib/iomgr/exec_ctx.c
+++ b/src/core/lib/iomgr/exec_ctx.c
@@ -66,8 +66,10 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
       exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL;
       while (c != NULL) {
         grpc_closure *next = c->next_data.next;
+        grpc_error *error = c->error_data.error;
         did_something = true;
-        grpc_closure_run(exec_ctx, c, c->error_data.error);
+        c->cb(exec_ctx, c->cb_arg, error);
+        GRPC_ERROR_UNREF(error);
         c = next;
       }
     } else if (!grpc_combiner_continue_exec_ctx(exec_ctx)) {
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 5f2a789e30..1342a28d8d 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -77,10 +77,18 @@ static void closure_exec_thread_func(void *ignored) {
       gpr_mu_unlock(&g_executor.mu);
       break;
     } else {
-      grpc_closure_list_sched(&exec_ctx, &g_executor.closures);
+      grpc_closure *c = g_executor.closures.head;
+      grpc_closure_list_init(&g_executor.closures);
+      gpr_mu_unlock(&g_executor.mu);
+      while (c != NULL) {
+        grpc_closure *next = c->next_data.next;
+        grpc_error *error = c->error_data.error;
+        c->cb(&exec_ctx, c->cb_arg, error);
+        GRPC_ERROR_UNREF(error);
+        c = next;
+      }
+      grpc_exec_ctx_flush(&exec_ctx);
     }
-    gpr_mu_unlock(&g_executor.mu);
-    grpc_exec_ctx_flush(&exec_ctx);
   }
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -115,8 +123,6 @@ static void maybe_spawn_locked() {
 static void executor_push(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                           grpc_error *error) {
   gpr_mu_lock(&g_executor.mu);
-  GPR_ASSERT(closure->scheduler == grpc_executor_scheduler);
-  closure->scheduler = grpc_schedule_on_exec_ctx;
   if (g_executor.shutting_down == 0) {
     grpc_closure_list_append(&g_executor.closures, closure, error);
     maybe_spawn_locked();
@@ -136,7 +142,15 @@ void grpc_executor_shutdown() {
    * list below because we aren't accepting new work */
 
   /* Execute pending callbacks, some may be performing cleanups */
-  grpc_closure_list_sched(&exec_ctx, &g_executor.closures);
+  grpc_closure *c = g_executor.closures.head;
+  grpc_closure_list_init(&g_executor.closures);
+  while (c != NULL) {
+    grpc_closure *next = c->next_data.next;
+    grpc_error *error = c->error_data.error;
+    c->cb(&exec_ctx, c->cb_arg, error);
+    GRPC_ERROR_UNREF(error);
+    c = next;
+  }
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
   if (pending_join) {
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index e7abecdb46..4dd476526d 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -219,8 +219,8 @@ static void listen_cb(grpc_exec_ctx *exec_ctx, void *arg, /*=sv_arg*/
   se->sv = sv;
   se->em_fd = grpc_fd_create(fd, "listener");
   grpc_pollset_add_fd(exec_ctx, g_pollset, se->em_fd);
-  se->session_read_closure.cb = session_read_cb;
-  se->session_read_closure.cb_arg = se;
+  grpc_closure_init(&se->session_read_closure, session_read_cb, se,
+                    grpc_schedule_on_exec_ctx);
   grpc_fd_notify_on_read(exec_ctx, se->em_fd, &se->session_read_closure);
 
   grpc_fd_notify_on_read(exec_ctx, listen_em_fd, &sv->listen_closure);
@@ -249,8 +249,8 @@ static int server_start(grpc_exec_ctx *exec_ctx, server *sv) {
   sv->em_fd = grpc_fd_create(fd, "server");
   grpc_pollset_add_fd(exec_ctx, g_pollset, sv->em_fd);
   /* Register to be interested in reading from listen_fd. */
-  sv->listen_closure.cb = listen_cb;
-  sv->listen_closure.cb_arg = sv;
+  grpc_closure_init(&sv->listen_closure, listen_cb, sv,
+                    grpc_schedule_on_exec_ctx);
   grpc_fd_notify_on_read(exec_ctx, sv->em_fd, &sv->listen_closure);
 
   return port;
@@ -333,8 +333,8 @@ static void client_session_write(grpc_exec_ctx *exec_ctx, void *arg, /*client */
   if (errno == EAGAIN) {
     gpr_mu_lock(g_mu);
     if (cl->client_write_cnt < CLIENT_TOTAL_WRITE_CNT) {
-      cl->write_closure.cb = client_session_write;
-      cl->write_closure.cb_arg = cl;
+      grpc_closure_init(&cl->write_closure, client_session_write, cl,
+                        grpc_schedule_on_exec_ctx);
       grpc_fd_notify_on_write(exec_ctx, cl->em_fd, &cl->write_closure);
       cl->client_write_cnt++;
     } else {
@@ -459,10 +459,10 @@ static void test_grpc_fd_change(void) {
   grpc_closure second_closure;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  first_closure.cb = first_read_callback;
-  first_closure.cb_arg = &a;
-  second_closure.cb = second_read_callback;
-  second_closure.cb_arg = &b;
+  grpc_closure_init(&first_closure, first_read_callback, &a,
+                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&second_closure, second_read_callback, &b,
+                    grpc_schedule_on_exec_ctx);
 
   init_change_data(&a);
   init_change_data(&b);
@@ -546,7 +546,8 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   test_grpc_fd();
   test_grpc_fd_change();
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
-- 
GitLab


From eff97ae57a02b813a44043d9e81778d80fe909cf Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 29 Dec 2016 12:17:48 -0800
Subject: [PATCH 210/344] Update cronet

---
 .../cronet/transport/cronet_transport.c       | 23 +++++++++----------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 6f94ccbc87..df0a769f6c 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -850,16 +850,16 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_INITIAL_METADATA", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
       grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                          GRPC_ERROR_CANCELLED, NULL);
+                         GRPC_ERROR_CANCELLED);
     } else if (stream_state->state_callback_received[OP_FAILED]) {
       grpc_closure_sched(
           exec_ctx, stream_op->recv_initial_metadata_ready,
-          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
+          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."));
     } else {
       grpc_chttp2_incoming_metadata_buffer_publish(
           &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata);
       grpc_closure_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                          GRPC_ERROR_NONE, NULL);
+                         GRPC_ERROR_NONE);
     }
     stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true;
     result = ACTION_TAKEN_NO_CALLBACK;
@@ -911,21 +911,21 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
       CRONET_LOG(GPR_DEBUG, "Stream is cancelled.");
       grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
-                          GRPC_ERROR_CANCELLED, NULL);
+                         GRPC_ERROR_CANCELLED);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->state_callback_received[OP_FAILED]) {
       CRONET_LOG(GPR_DEBUG, "Stream failed.");
       grpc_closure_sched(
           exec_ctx, stream_op->recv_message_ready,
-          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
+          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."));
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       result = ACTION_TAKEN_NO_CALLBACK;
     } else if (stream_state->rs.read_stream_closed == true) {
       /* No more data will be received */
       CRONET_LOG(GPR_DEBUG, "read stream closed");
       grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
-                          GRPC_ERROR_NONE, NULL);
+                         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;
@@ -959,7 +959,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
           *((grpc_byte_buffer **)stream_op->recv_message) =
               (grpc_byte_buffer *)&stream_state->rs.sbs;
           grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
-                              GRPC_ERROR_NONE, NULL);
+                             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;
@@ -994,7 +994,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       *((grpc_byte_buffer **)stream_op->recv_message) =
           (grpc_byte_buffer *)&stream_state->rs.sbs;
       grpc_closure_sched(exec_ctx, stream_op->recv_message_ready,
-                          GRPC_ERROR_NONE, NULL);
+                         GRPC_ERROR_NONE);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
       oas->state.state_op_done[OP_RECV_MESSAGE] = true;
       /* Do an extra read to trigger on_succeeded() callback in case connection
@@ -1056,17 +1056,16 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_ON_COMPLETE", oas);
     if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
       grpc_closure_sched(exec_ctx, stream_op->on_complete,
-                          GRPC_ERROR_REF(stream_state->cancel_error), NULL);
+                         GRPC_ERROR_REF(stream_state->cancel_error));
     } else if (stream_state->state_callback_received[OP_FAILED]) {
       grpc_closure_sched(
           exec_ctx, stream_op->on_complete,
-          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."), NULL);
+          make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."));
     } else {
       /* All actions in this stream_op are complete. Call the on_complete
        * callback
        */
-      grpc_closure_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE,
-                          NULL);
+      grpc_closure_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE);
     }
     oas->state.state_op_done[OP_ON_COMPLETE] = true;
     oas->done = true;
-- 
GitLab


From ff281b9d229da707f94fe4d55236dd683432e53a Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 29 Dec 2016 13:39:51 -0800
Subject: [PATCH 211/344] Fix udp server

---
 src/core/lib/iomgr/udp_server.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 69812e2804..dfbd295c91 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -170,8 +170,8 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
     for (sp = s->head; sp; sp = sp->next) {
       grpc_unlink_if_unix_domain_socket(&sp->addr);
 
-      sp->destroyed_closure.cb = destroyed_port;
-      sp->destroyed_closure.cb_arg = s;
+      grpc_closure_init(&sp->destroyed_closure, destroyed_port, s,
+                        grpc_schedule_on_exec_ctx);
 
       /* Call the orphan_cb to signal that the FD is about to be closed and
        * should no longer be used. */
@@ -446,8 +446,8 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
     for (i = 0; i < pollset_count; i++) {
       grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
     }
-    sp->read_closure.cb = on_read;
-    sp->read_closure.cb_arg = sp;
+    grpc_closure_init(&sp->read_closure, on_read, sp,
+                      grpc_schedule_on_exec_ctx);
     grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
 
     s->active_ports++;
-- 
GitLab


From 801c6cc5481285968eb18e19f8d1cf2ae0a4a204 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 08:13:13 -0800
Subject: [PATCH 212/344] Fix some NULL usage

---
 include/grpc++/resource_quota.h     | 3 ++-
 src/core/lib/iomgr/ev_epoll_linux.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/grpc++/resource_quota.h b/include/grpc++/resource_quota.h
index 75e04d4e2f..68a514658d 100644
--- a/include/grpc++/resource_quota.h
+++ b/include/grpc++/resource_quota.h
@@ -37,6 +37,7 @@
 struct grpc_resource_quota;
 
 #include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/grpc_library.h>
 
 namespace grpc {
 
@@ -44,7 +45,7 @@ namespace grpc {
 /// A ResourceQuota can be attached to a server (via ServerBuilder), or a client
 /// channel (via ChannelArguments). gRPC will attempt to keep memory used by
 /// all attached entities below the ResourceQuota bound.
-class ResourceQuota final {
+class ResourceQuota final : private GrpcLibraryCodegen {
  public:
   explicit ResourceQuota(const grpc::string& name);
   ResourceQuota();
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index e8daa1f52c..045001f6d8 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -830,7 +830,8 @@ static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
 
 static grpc_closure_scheduler *workqueue_scheduler(grpc_workqueue *workqueue) {
   polling_island *pi = (polling_island *)workqueue;
-  return &pi->workqueue_scheduler;
+  return workqueue == NULL ? grpc_schedule_on_exec_ctx
+                           : &pi->workqueue_scheduler;
 }
 
 static grpc_error *polling_island_global_init() {
-- 
GitLab


From 460da03d0c335bf9c81e5fc035299e9ddf5804d1 Mon Sep 17 00:00:00 2001
From: Craig Tiller <craig.tiller@gmail.com>
Date: Tue, 3 Jan 2017 08:45:29 -0800
Subject: [PATCH 213/344] Fixup Windows source files for new closure APIs

---
 src/core/lib/iomgr/pollset_windows.c         | 3 +--
 src/core/lib/iomgr/resolve_address_windows.c | 4 ++--
 src/core/lib/iomgr/tcp_server_windows.c      | 6 +++---
 src/core/lib/iomgr/tcp_windows.c             | 9 ++++-----
 4 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/src/core/lib/iomgr/pollset_windows.c b/src/core/lib/iomgr/pollset_windows.c
index 6714d8d51d..2a45e708df 100644
--- a/src/core/lib/iomgr/pollset_windows.c
+++ b/src/core/lib/iomgr/pollset_windows.c
@@ -167,8 +167,7 @@ grpc_error *grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
       }
 
       if (pollset->shutting_down && pollset->on_shutdown != NULL) {
-        grpc_closure_sched(exec_ctx, pollset->on_shutdown, GRPC_ERROR_NONE,
-                            NULL);
+        grpc_closure_sched(exec_ctx, pollset->on_shutdown, GRPC_ERROR_NONE);
         pollset->on_shutdown = NULL;
       }
       goto done;
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index bda7f77f9c..a18ccf3adb 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -173,12 +173,12 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addresses) {
   request *r = gpr_malloc(sizeof(request));
-  grpc_closure_init(&r->request_closure, do_request_thread, r, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&r->request_closure, do_request_thread, r, grpc_executor_scheduler);
   r->name = gpr_strdup(name);
   r->default_port = gpr_strdup(default_port);
   r->on_done = on_done;
   r->addresses = addresses;
-  grpc_executor_push(&r->request_closure, GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx,&r->request_closure, GRPC_ERROR_NONE);
 }
 
 void (*grpc_resolve_address)(
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 2a54949354..db447e72b5 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -165,8 +165,8 @@ static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
     grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
-  grpc_closure_sched(exec_ctx, grpc_closure_create(destroy_server, s),
-                      GRPC_ERROR_NONE, NULL);
+  grpc_closure_sched(exec_ctx, grpc_closure_create(destroy_server, s, grpc_schedule_on_exec_ctx),
+                      GRPC_ERROR_NONE);
 }
 
 grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
@@ -204,7 +204,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
     grpc_tcp_server_shutdown_listeners(exec_ctx, s);
     gpr_mu_lock(&s->mu);
-    grpc_closure_list_sched(exec_ctx, &s->shutdown_starting, NULL);
+    grpc_closure_list_sched(exec_ctx, &s->shutdown_starting);
     gpr_mu_unlock(&s->mu);
     tcp_server_destroy(exec_ctx, s);
   }
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index b84a448a81..78e0a20bf4 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -203,7 +203,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                        GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
+                        GRPC_ERROR_CREATE("TCP socket is shutting down"));
     return;
   }
 
@@ -241,7 +241,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     if (wsa_error != WSA_IO_PENDING) {
       info->wsa_error = wsa_error;
       grpc_closure_sched(exec_ctx, &tcp->on_read,
-                          GRPC_WSA_ERROR(info->wsa_error, "WSARecv"), NULL);
+                          GRPC_WSA_ERROR(info->wsa_error, "WSARecv"));
       return;
     }
   }
@@ -291,7 +291,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                        GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
+                        GRPC_ERROR_CREATE("TCP socket is shutting down"));
     return;
   }
 
@@ -340,8 +340,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     int wsa_error = WSAGetLastError();
     if (wsa_error != WSA_IO_PENDING) {
       TCP_UNREF(exec_ctx, tcp, "write");
-      grpc_closure_sched(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend"),
-                          NULL);
+      grpc_closure_sched(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend"));
       return;
     }
   }
-- 
GitLab


From d4654560dcccf4d3bb0f55538a3bc64dc1793f2a Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 08:45:56 -0800
Subject: [PATCH 214/344] clang-format code

---
 src/core/ext/census/grpc_filter.c                   | 3 ++-
 src/core/ext/client_channel/channel_connectivity.c  | 3 ++-
 src/core/ext/load_reporting/load_reporting_filter.c | 3 ++-
 src/core/lib/iomgr/resolve_address_windows.c        | 5 +++--
 src/core/lib/iomgr/tcp_server_windows.c             | 5 +++--
 src/core/lib/iomgr/tcp_uv.c                         | 2 +-
 src/core/lib/iomgr/tcp_windows.c                    | 6 +++---
 src/core/lib/iomgr/timer_uv.c                       | 3 ++-
 src/core/lib/surface/completion_queue.c             | 3 ++-
 test/core/bad_client/bad_client.c                   | 6 ++++--
 test/core/iomgr/endpoint_pair_test.c                | 3 ++-
 test/core/iomgr/ev_epoll_linux_test.c               | 3 ++-
 test/core/iomgr/tcp_client_posix_test.c             | 3 ++-
 test/core/iomgr/tcp_posix_test.c                    | 9 ++++++---
 test/core/iomgr/udp_server_test.c                   | 3 ++-
 test/core/security/secure_endpoint_test.c           | 3 ++-
 test/core/surface/lame_client_test.c                | 6 ++++--
 test/core/transport/connectivity_state_test.c       | 9 ++++++---
 test/core/util/test_tcp_server.c                    | 6 ++++--
 19 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 6429ee444e..8e4d4732b8 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -154,7 +154,8 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
   memset(d, 0, sizeof(*d));
   d->start_ts = args->start_time;
   /* TODO(hongyu): call census_tracing_start_op here. */
-  grpc_closure_init(&d->finish_recv, server_on_done_recv, elem, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&d->finish_recv, server_on_done_recv, elem,
+                    grpc_schedule_on_exec_ctx);
   return GRPC_ERROR_NONE;
 }
 
diff --git a/src/core/ext/client_channel/channel_connectivity.c b/src/core/ext/client_channel/channel_connectivity.c
index 4cbd4293df..b10f444b63 100644
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ b/src/core/ext/client_channel/channel_connectivity.c
@@ -198,7 +198,8 @@ void grpc_channel_watch_connectivity_state(
   grpc_cq_begin_op(cq, tag);
 
   gpr_mu_init(&w->mu);
-  grpc_closure_init(&w->on_complete, watch_complete, w, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&w->on_complete, watch_complete, w,
+                    grpc_schedule_on_exec_ctx);
   w->phase = WAITING;
   w->state = last_observed_state;
   w->cq = cq;
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index df72686446..1403eb0d33 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -114,7 +114,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   memset(calld, 0, sizeof(call_data));
 
   calld->id = (intptr_t)args->call_stack;
-  grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem,
+                    grpc_schedule_on_exec_ctx);
 
   /* TODO(dgq): do something with the data
   channel_data *chand = elem->channel_data;
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index a18ccf3adb..2439ce3cb7 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -173,12 +173,13 @@ static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
                                  grpc_closure *on_done,
                                  grpc_resolved_addresses **addresses) {
   request *r = gpr_malloc(sizeof(request));
-  grpc_closure_init(&r->request_closure, do_request_thread, r, grpc_executor_scheduler);
+  grpc_closure_init(&r->request_closure, do_request_thread, r,
+                    grpc_executor_scheduler);
   r->name = gpr_strdup(name);
   r->default_port = gpr_strdup(default_port);
   r->on_done = on_done;
   r->addresses = addresses;
-  grpc_closure_sched(exec_ctx,&r->request_closure, GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx, &r->request_closure, GRPC_ERROR_NONE);
 }
 
 void (*grpc_resolve_address)(
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index db447e72b5..6302bff5d2 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -165,8 +165,9 @@ static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
     grpc_closure_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE);
   }
 
-  grpc_closure_sched(exec_ctx, grpc_closure_create(destroy_server, s, grpc_schedule_on_exec_ctx),
-                      GRPC_ERROR_NONE);
+  grpc_closure_sched(exec_ctx, grpc_closure_create(destroy_server, s,
+                                                   grpc_schedule_on_exec_ctx),
+                     GRPC_ERROR_NONE);
 }
 
 grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index f97ca885b4..e2fefa5821 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -244,7 +244,7 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                        GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
+                       GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
     return;
   }
 
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 78e0a20bf4..fa13ac1d25 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -203,7 +203,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                        GRPC_ERROR_CREATE("TCP socket is shutting down"));
+                       GRPC_ERROR_CREATE("TCP socket is shutting down"));
     return;
   }
 
@@ -241,7 +241,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
     if (wsa_error != WSA_IO_PENDING) {
       info->wsa_error = wsa_error;
       grpc_closure_sched(exec_ctx, &tcp->on_read,
-                          GRPC_WSA_ERROR(info->wsa_error, "WSARecv"));
+                         GRPC_WSA_ERROR(info->wsa_error, "WSARecv"));
       return;
     }
   }
@@ -291,7 +291,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                        GRPC_ERROR_CREATE("TCP socket is shutting down"));
+                       GRPC_ERROR_CREATE("TCP socket is shutting down"));
     return;
   }
 
diff --git a/src/core/lib/iomgr/timer_uv.c b/src/core/lib/iomgr/timer_uv.c
index 7153535a85..00b835ffb8 100644
--- a/src/core/lib/iomgr/timer_uv.c
+++ b/src/core/lib/iomgr/timer_uv.c
@@ -65,7 +65,8 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
                      void *timer_cb_arg, gpr_timespec now) {
   uint64_t timeout;
   uv_timer_t *uv_timer;
-  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
+                    grpc_schedule_on_exec_ctx);
   if (gpr_time_cmp(deadline, now) <= 0) {
     timer->triggered = 1;
     grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index aefdd39547..4613c9021e 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -168,7 +168,8 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
 #ifndef NDEBUG
   cc->outstanding_tag_count = 0;
 #endif
-  grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc,
+                    grpc_schedule_on_exec_ctx);
 
   GPR_TIMER_END("grpc_completion_queue_create", 0);
 
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 4d8f10860e..d579dcc7d4 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -148,7 +148,8 @@ void grpc_run_bad_client_test(
 
   grpc_slice_buffer_init(&outgoing);
   grpc_slice_buffer_add(&outgoing, slice);
-  grpc_closure_init(&done_write_closure, done_write, &a, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&done_write_closure, done_write, &a,
+                    grpc_schedule_on_exec_ctx);
 
   /* Write data */
   grpc_endpoint_write(&exec_ctx, sfd.client, &outgoing, &done_write_closure);
@@ -175,7 +176,8 @@ void grpc_run_bad_client_test(
       grpc_slice_buffer_init(&args.incoming);
       gpr_event_init(&args.read_done);
       grpc_closure read_done_closure;
-      grpc_closure_init(&read_done_closure, read_done, &args, grpc_schedule_on_exec_ctx);
+      grpc_closure_init(&read_done_closure, read_done, &args,
+                        grpc_schedule_on_exec_ctx);
       grpc_endpoint_read(&exec_ctx, sfd.client, &args.incoming,
                          &read_done_closure);
       grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 6899f6524a..f02171f2ef 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -81,7 +81,8 @@ int main(int argc, char **argv) {
   g_pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 4fee4cb8c3..5bce9801a5 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -102,7 +102,8 @@ static void test_pollset_cleanup(grpc_exec_ctx *exec_ctx,
   int i;
 
   for (i = 0; i < num_pollsets; i++) {
-    grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].pollset, grpc_schedule_on_exec_ctx);
+    grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].pollset,
+                      grpc_schedule_on_exec_ctx);
     grpc_pollset_shutdown(exec_ctx, pollsets[i].pollset, &destroyed);
 
     grpc_exec_ctx_flush(exec_ctx);
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index 2100fd4c2f..0ea7a000eb 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -207,7 +207,8 @@ int main(int argc, char **argv) {
   gpr_log(GPR_ERROR, "End of first test");
   test_fails();
   grpc_pollset_set_destroy(g_pollset_set);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 340b807047..c646e61de0 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -384,7 +384,8 @@ static void write_test(size_t num_bytes, size_t slice_size) {
 
   grpc_slice_buffer_init(&outgoing);
   grpc_slice_buffer_addn(&outgoing, slices, num_blocks);
-  grpc_closure_init(&write_done_closure, write_done, &state, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&write_done_closure, write_done, &state,
+                    grpc_schedule_on_exec_ctx);
 
   grpc_endpoint_write(&exec_ctx, ep, &outgoing, &write_done_closure);
   drain_socket_blocking(sv[0], num_bytes, num_bytes);
@@ -429,7 +430,8 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure fd_released_cb;
   int fd_released_done = 0;
-  grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done,
+                    grpc_schedule_on_exec_ctx);
 
   gpr_log(GPR_INFO,
           "Release fd read_test of size %" PRIuPTR ", slice size %" PRIuPTR,
@@ -561,7 +563,8 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
   run_tests();
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 67ef81fab2..0a247caf89 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -234,7 +234,8 @@ int main(int argc, char **argv) {
   test_receive(1);
   test_receive(10);
 
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index a004fc0b41..cbf8a171af 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -191,7 +191,8 @@ int main(int argc, char **argv) {
   grpc_pollset_init(g_pollset, &g_mu);
   grpc_endpoint_tests(configs[0], g_pollset, g_mu);
   test_leftover(configs[1], 1);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
+                    grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index af36a2d734..b6db6a6b08 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -62,7 +62,8 @@ void test_transport_op(grpc_channel *channel) {
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  grpc_closure_init(&transport_op_cb, verify_connectivity, &state, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&transport_op_cb, verify_connectivity, &state,
+                    grpc_schedule_on_exec_ctx);
 
   op = grpc_make_transport_op(NULL);
   op->on_connectivity_state_change = &transport_op_cb;
@@ -71,7 +72,8 @@ void test_transport_op(grpc_channel *channel) {
   elem->filter->start_transport_op(&exec_ctx, elem, op);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_closure_init(&transport_op_cb, do_nothing, NULL, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&transport_op_cb, do_nothing, NULL,
+                    grpc_schedule_on_exec_ctx);
   op = grpc_make_transport_op(&transport_op_cb);
   elem->filter->start_transport_op(&exec_ctx, elem, op);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c
index 1a347354f4..3520ef0a80 100644
--- a/test/core/transport/connectivity_state_test.c
+++ b/test/core/transport/connectivity_state_test.c
@@ -86,7 +86,8 @@ static void test_check(void) {
 
 static void test_subscribe_then_unsubscribe(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
+  grpc_closure *closure =
+      grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_then_unsubscribe");
@@ -109,7 +110,8 @@ static void test_subscribe_then_unsubscribe(void) {
 
 static void test_subscribe_then_destroy(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_succeed, THE_ARG, grpc_schedule_on_exec_ctx);
+  grpc_closure *closure =
+      grpc_closure_create(must_succeed, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_then_destroy");
@@ -128,7 +130,8 @@ static void test_subscribe_then_destroy(void) {
 
 static void test_subscribe_with_failure_then_destroy(void) {
   grpc_connectivity_state_tracker tracker;
-  grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
+  grpc_closure *closure =
+      grpc_closure_create(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
   grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_with_failure_then_destroy");
diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c
index af085dee47..2338b81ab1 100644
--- a/test/core/util/test_tcp_server.c
+++ b/test/core/util/test_tcp_server.c
@@ -57,7 +57,8 @@ void test_tcp_server_init(test_tcp_server *server,
                           grpc_tcp_server_cb on_connect, void *user_data) {
   grpc_init();
   server->tcp_server = NULL;
-  grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server,
+                    grpc_schedule_on_exec_ctx);
   server->shutdown = 0;
   server->pollset = gpr_malloc(grpc_pollset_size());
   grpc_pollset_init(server->pollset, &server->mu);
@@ -111,7 +112,8 @@ void test_tcp_server_destroy(test_tcp_server *server) {
   gpr_timespec shutdown_deadline;
   grpc_closure do_nothing_cb;
   grpc_tcp_server_unref(&exec_ctx, server->tcp_server);
-  grpc_closure_init(&do_nothing_cb, do_nothing, NULL, grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&do_nothing_cb, do_nothing, NULL,
+                    grpc_schedule_on_exec_ctx);
   shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                    gpr_time_from_seconds(5, GPR_TIMESPAN));
   while (!server->shutdown &&
-- 
GitLab


From aef521c6f9df8d36ae927a4504d055e1d376bfa6 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 09:13:36 -0800
Subject: [PATCH 215/344] Fix closure usage in UV code

---
 src/core/lib/iomgr/tcp_server_uv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index 89624b447c..8abc60d624 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -170,7 +170,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
     /* Complete shutdown_starting work before destroying. */
     grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_closure_list_sched(&local_exec_ctx, &s->shutdown_starting, NULL);
+    grpc_closure_list_sched(&local_exec_ctx, &s->shutdown_starting);
     if (exec_ctx == NULL) {
       grpc_exec_ctx_flush(&local_exec_ctx);
       tcp_server_destroy(&local_exec_ctx, s);
-- 
GitLab


From fb27caca3b78e7b4bbd650fce928d2bb2951c3e6 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 09:54:51 -0800
Subject: [PATCH 216/344] More UV fixes

---
 src/core/lib/iomgr/tcp_uv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index e2fefa5821..4be95457d5 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -244,7 +244,7 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   if (tcp->shutting_down) {
     grpc_closure_sched(exec_ctx, cb,
-                       GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
+                       GRPC_ERROR_CREATE("TCP socket is shutting down"));
     return;
   }
 
-- 
GitLab


From 76c0bbadf9e88ff671de3ea8e5ce1e8b53986706 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 10:04:54 -0800
Subject: [PATCH 217/344] Fix test

---
 test/core/security/jwt_verifier_test.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index 9be08c8780..48c834655b 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -295,11 +295,13 @@ static void test_bad_subject_claims_failure(void) {
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
              GRPC_JWT_VERIFIER_BAD_SUBJECT);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static char *json_key_str(const char *last_part) {
-- 
GitLab


From e4c2b10516038bc4540baf9d76b876da5dc4afd7 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 12:02:22 -0800
Subject: [PATCH 218/344] No need for copyright on generated files

---
 .../proto/grpc/lb/v1/load_balancer.pb.c       | 32 -------------------
 .../proto/grpc/lb/v1/load_balancer.pb.h       | 32 -------------------
 tools/distrib/check_copyright.py              |  3 ++
 3 files changed, 3 insertions(+), 64 deletions(-)

diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
index afecb716fb..e352e0396f 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
@@ -1,35 +1,3 @@
-/*
- *
- * Copyright 2016, 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.
- *
- */
 /* Automatically generated nanopb constant definitions */
 /* Generated by nanopb-0.3.7-dev */
 
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
index e36d0966f8..725aa7e386 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
@@ -1,35 +1,3 @@
-/*
- *
- * Copyright 2016, 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.
- *
- */
 /* Automatically generated nanopb header */
 /* Generated by nanopb-0.3.7-dev */
 
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index 51852adfd3..718bb563f3 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -103,6 +103,9 @@ _EXEMPT = frozenset((
   'examples/python/route_guide/route_guide_pb2.py',
   'examples/python/route_guide/route_guide_pb2_grpc.py',
 
+  'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+  'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
+
   # An older file originally from outside gRPC.
   'src/php/tests/bootstrap.php',
 ))
-- 
GitLab


From de7e8c78f75e80c7ade68394cf75100cb49d1b80 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 3 Jan 2017 14:03:01 -0800
Subject: [PATCH 219/344] Dont add copyright

---
 tools/codegen/core/gen_nano_proto.sh | 47 ----------------------------
 1 file changed, 47 deletions(-)

diff --git a/tools/codegen/core/gen_nano_proto.sh b/tools/codegen/core/gen_nano_proto.sh
index df107c208f..99e49814b8 100755
--- a/tools/codegen/core/gen_nano_proto.sh
+++ b/tools/codegen/core/gen_nano_proto.sh
@@ -42,46 +42,6 @@
 # 4: Output dir not an absolute path.
 # 5: Couldn't create output directory (2nd argument).
 
-read -r -d '' COPYRIGHT <<'EOF'
-/*
- *
- * Copyright <YEAR>, 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.
- *
- */
-
-EOF
-
-CURRENT_YEAR=$(date +%Y)
-COPYRIGHT_FILE=$(mktemp)
-echo "${COPYRIGHT/<YEAR>/$CURRENT_YEAR}" > $COPYRIGHT_FILE
-
 set -ex
 if [ $# -lt 2 ] || [ $# -gt 3 ]; then
   echo "Usage: $0 <input.proto> <absolute path to output dir> [grpc path]"
@@ -143,13 +103,6 @@ readonly UC_PROTO_BASENAME=`echo $PROTO_BASENAME | tr [a-z] [A-Z]`
 sed -i "s:PB_${UC_PROTO_BASENAME}_PB_H_INCLUDED:GRPC_${INCLUDE_GUARD_BASE}_${UC_PROTO_BASENAME}_PB_H:g" \
   "$OUTPUT_DIR/$PROTO_BASENAME.pb.h"
 
-# prepend copyright
-TMPFILE=$(mktemp)
-cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c" > $TMPFILE
-mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
-cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h" > $TMPFILE
-mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h"
-
 deactivate
 rm -rf $VENV_DIR
 
-- 
GitLab


From db194ce03562a617fc4ed0e2aa95fc3ac763f370 Mon Sep 17 00:00:00 2001
From: Jozef Izso <jozef.izso@gmail.com>
Date: Wed, 4 Jan 2017 16:03:42 +0100
Subject: [PATCH 220/344] Update link to CoApp installer

Use the functional link to download CoApp installer.
---
 vsprojects/coapp/zlib/README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/vsprojects/coapp/zlib/README.md b/vsprojects/coapp/zlib/README.md
index d62e9030ed..e9a89c030e 100644
--- a/vsprojects/coapp/zlib/README.md
+++ b/vsprojects/coapp/zlib/README.md
@@ -10,7 +10,7 @@ Multiple versions of VS installed to be able to build all the targets:
 * Visual Studio 2013
 * Visual Studio 2010 (you might need SP1 to prevent LNK1123 error)
 
-CoApp toolkit: http://downloads.coapp.org/files/CoApp.Tools.Powershell.msi
+CoApp toolkit: http://coapp.org/files/CoApp.Tools.Powershell.msi
 
 More details on installation: http://coapp.org/tutorials/installation.html
 
@@ -33,4 +33,4 @@ This will create three NuGet packages:
 * the symbols package (debug symbols)
 
 Later, you can push the package to NuGet.org repo.
-Attention: before pusing the resulting nuget package to public nuget repo, you have to be 100% sure it works correctly - there’s no way how to delete or update an already existing package.
\ No newline at end of file
+Attention: before pusing the resulting nuget package to public nuget repo, you have to be 100% sure it works correctly - there’s no way how to delete or update an already existing package.
-- 
GitLab


From e7cd7c111916bcf26c66da9d64e5fa8535820bed Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 09:48:54 -0800
Subject: [PATCH 221/344] Expunge vs2010 references

---
 vsprojects/README.md        |  2 +-
 vsprojects/build_vs2010.bat | 39 -------------------------------------
 2 files changed, 1 insertion(+), 40 deletions(-)
 delete mode 100644 vsprojects/build_vs2010.bat

diff --git a/vsprojects/README.md b/vsprojects/README.md
index 7af69c2726..afd6430bfe 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -2,7 +2,7 @@ This directory contains MS Visual Studio project & solution files.
 
 #Supported Visual Studio versions
 
-Currently supported versions are Visual Studio 2013 (our primary focus) and 2010.
+Currently supported versions are Visual Studio 2013 (our primary focus).
 
 #Building
 We are using [NuGet](http://www.nuget.org) to pull zlib and openssl dependencies.
diff --git a/vsprojects/build_vs2010.bat b/vsprojects/build_vs2010.bat
deleted file mode 100644
index d951295369..0000000000
--- a/vsprojects/build_vs2010.bat
+++ /dev/null
@@ -1,39 +0,0 @@
-@rem Copyright 2016, Google Inc.
-@rem All rights reserved.
-@rem
-@rem Redistribution and use in source and binary forms, with or without
-@rem modification, are permitted provided that the following conditions are
-@rem met:
-@rem
-@rem     * Redistributions of source code must retain the above copyright
-@rem notice, this list of conditions and the following disclaimer.
-@rem     * Redistributions in binary form must reproduce the above
-@rem copyright notice, this list of conditions and the following disclaimer
-@rem in the documentation and/or other materials provided with the
-@rem distribution.
-@rem     * Neither the name of Google Inc. nor the names of its
-@rem contributors may be used to endorse or promote products derived from
-@rem this software without specific prior written permission.
-@rem
-@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-@rem Convenience wrapper that runs specified gRPC target using msbuild
-@rem Usage: build_vs2010.bat TARGET_NAME
-
-setlocal
-@rem Set VS variables (uses Visual Studio 2010)
-@call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-
-msbuild %*
-exit /b %ERRORLEVEL%
-endlocal
-- 
GitLab


From f9445d05523b3909063547a5b932b0a5ef00907a Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 4 Jan 2017 22:46:47 +0100
Subject: [PATCH 222/344] Boringssl will need duplication for now.

---
 .gitmodules                      | 3 +++
 WORKSPACE                        | 4 ++--
 third_party/boringssl            | 2 +-
 third_party/boringssl-with-bazel | 1 +
 4 files changed, 7 insertions(+), 3 deletions(-)
 create mode 160000 third_party/boringssl-with-bazel

diff --git a/.gitmodules b/.gitmodules
index 04d155cfb4..c8ca8ab046 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -20,3 +20,6 @@
 [submodule "third_party/benchmark"]
 	path = third_party/benchmark
 	url = https://github.com/google/benchmark
+[submodule "third_party/boringssl-with-bazel"]
+	path = third_party/boringssl-with-bazel
+	url = https://boringssl.googlesource.com/boringssl
diff --git a/WORKSPACE b/WORKSPACE
index 98c3afa5bd..9883109634 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -30,8 +30,8 @@ bind(
 
 new_local_repository(
     name = "submodule_boringssl",
-    path = "third_party/boringssl",
-    build_file = "third_party/boringssl/BUILD",
+    path = "third_party/boringssl-with-bazel",
+    build_file = "third_party/boringssl-with-bazel/BUILD",
 )
 
 new_local_repository(
diff --git a/third_party/boringssl b/third_party/boringssl
index 9612e1d2ce..c880e42ba1 160000
--- a/third_party/boringssl
+++ b/third_party/boringssl
@@ -1 +1 @@
-Subproject commit 9612e1d2ce16a1bd67fbbe6ce969839af4d84a29
+Subproject commit c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9
diff --git a/third_party/boringssl-with-bazel b/third_party/boringssl-with-bazel
new file mode 160000
index 0000000000..886e7d7536
--- /dev/null
+++ b/third_party/boringssl-with-bazel
@@ -0,0 +1 @@
+Subproject commit 886e7d75368e3f4fab3f4d0d3584e4abfc557755
-- 
GitLab


From 3d5592cea87e58f89fec1b579460b10820a9f5fc Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 4 Jan 2017 23:23:40 +0100
Subject: [PATCH 223/344] Moving message_size_filter properly.

---
 BUILD                                         |   2 +
 CMakeLists.txt                                |   8 +-
 Makefile                                      |   9 +-
 binding.gyp                                   |   2 +-
 build.yaml                                    |   3 +-
 config.m4                                     |   2 +-
 gRPC-Core.podspec                             |   6 +-
 grpc.gemspec                                  |   4 +-
 package.xml                                   |   4 +-
 .../message_size_filter.c                     |   2 +-
 .../message_size_filter.h                     |   6 +-
 src/python/grpcio/grpc_core_dependencies.py   |   2 +-
 test/core/bad_client/gen_build_yaml.py        | 100 ++++++++++++++++++
 tools/doxygen/Doxyfile.core.internal          |   4 +-
 .../generated/sources_and_headers.json        |   6 +-
 vsprojects/vcxproj/grpc/grpc.vcxproj          |   6 +-
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters  |  12 +--
 .../grpc_test_util/grpc_test_util.vcxproj     |   3 -
 .../grpc_test_util.vcxproj.filters            |   6 --
 .../grpc_unsecure/grpc_unsecure.vcxproj       |   6 +-
 .../grpc_unsecure.vcxproj.filters             |  12 +--
 21 files changed, 149 insertions(+), 56 deletions(-)
 rename src/core/ext/{client_config => client_channel}/message_size_filter.c (99%)
 rename src/core/ext/{client_config => client_channel}/message_size_filter.h (90%)
 create mode 100755 test/core/bad_client/gen_build_yaml.py

diff --git a/BUILD b/BUILD
index e7bfafe663..2e040bb87c 100644
--- a/BUILD
+++ b/BUILD
@@ -659,6 +659,7 @@ grpc_cc_library(
         "src/core/ext/client_channel/lb_policy.c",
         "src/core/ext/client_channel/lb_policy_factory.c",
         "src/core/ext/client_channel/lb_policy_registry.c",
+        "src/core/ext/client_channel/message_size_filter.c",
         "src/core/ext/client_channel/parse_address.c",
         "src/core/ext/client_channel/resolver.c",
         "src/core/ext/client_channel/resolver_factory.c",
@@ -676,6 +677,7 @@ grpc_cc_library(
         "src/core/ext/client_channel/lb_policy.h",
         "src/core/ext/client_channel/lb_policy_factory.h",
         "src/core/ext/client_channel/lb_policy_registry.h",
+        "src/core/ext/client_channel/message_size_filter.h",
         "src/core/ext/client_channel/parse_address.h",
         "src/core/ext/client_channel/resolver.h",
         "src/core/ext/client_channel/resolver_factory.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff0927504a..3d16e3ba6c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -294,7 +294,6 @@ add_library(grpc
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -460,6 +459,7 @@ add_library(grpc
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
+  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -575,7 +575,6 @@ add_library(grpc_cronet
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -715,6 +714,7 @@ add_library(grpc_cronet
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
+  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -827,7 +827,6 @@ add_library(grpc_unsecure
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -969,6 +968,7 @@ add_library(grpc_unsecure
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
+  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -1294,7 +1294,6 @@ add_library(grpc++_cronet
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
-  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -1409,6 +1408,7 @@ add_library(grpc++_cronet
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
+  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
diff --git a/Makefile b/Makefile
index 8f7328ae28..4b35bc16e8 100644
--- a/Makefile
+++ b/Makefile
@@ -2633,7 +2633,6 @@ LIBGRPC_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -2799,6 +2798,7 @@ LIBGRPC_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
+    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -2932,7 +2932,6 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3072,6 +3071,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
+    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -3221,7 +3221,6 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3438,7 +3437,6 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3580,6 +3578,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
+    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -4017,7 +4016,6 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -4132,6 +4130,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
+    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
diff --git a/binding.gyp b/binding.gyp
index 516cbdce5d..910e1c1053 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -574,7 +574,6 @@
         'src/core/lib/channel/handshaker.c',
         'src/core/lib/channel/http_client_filter.c',
         'src/core/lib/channel/http_server_filter.c',
-        'src/core/lib/channel/message_size_filter.c',
         'src/core/lib/compression/compression.c',
         'src/core/lib/compression/message_compress.c',
         'src/core/lib/debug/trace.c',
@@ -740,6 +739,7 @@
         'src/core/ext/client_channel/lb_policy.c',
         'src/core/ext/client_channel/lb_policy_factory.c',
         'src/core/ext/client_channel/lb_policy_registry.c',
+        'src/core/ext/client_channel/message_size_filter.c',
         'src/core/ext/client_channel/parse_address.c',
         'src/core/ext/client_channel/resolver.c',
         'src/core/ext/client_channel/resolver_factory.c',
diff --git a/build.yaml b/build.yaml
index df009539b2..8d14507b15 100644
--- a/build.yaml
+++ b/build.yaml
@@ -269,7 +269,6 @@ filegroups:
   - src/core/lib/channel/handshaker.c
   - src/core/lib/channel/http_client_filter.c
   - src/core/lib/channel/http_server_filter.c
-  - src/core/lib/channel/message_size_filter.c
   - src/core/lib/compression/compression.c
   - src/core/lib/compression/message_compress.c
   - src/core/lib/debug/trace.c
@@ -386,6 +385,7 @@ filegroups:
   - src/core/ext/client_channel/lb_policy.h
   - src/core/ext/client_channel/lb_policy_factory.h
   - src/core/ext/client_channel/lb_policy_registry.h
+  - src/core/ext/client_channel/message_size_filter.h
   - src/core/ext/client_channel/parse_address.h
   - src/core/ext/client_channel/resolver.h
   - src/core/ext/client_channel/resolver_factory.h
@@ -405,6 +405,7 @@ filegroups:
   - src/core/ext/client_channel/lb_policy.c
   - src/core/ext/client_channel/lb_policy_factory.c
   - src/core/ext/client_channel/lb_policy_registry.c
+  - src/core/ext/client_channel/message_size_filter.c
   - src/core/ext/client_channel/parse_address.c
   - src/core/ext/client_channel/resolver.c
   - src/core/ext/client_channel/resolver_factory.c
diff --git a/config.m4 b/config.m4
index 4b86e25581..e4d55c9e19 100644
--- a/config.m4
+++ b/config.m4
@@ -90,7 +90,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -256,6 +255,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
+    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index e10e534a5e..f8b95f9152 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -257,7 +257,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/handshaker.h',
                       'src/core/lib/channel/http_client_filter.h',
                       'src/core/lib/channel/http_server_filter.h',
-                      'src/core/lib/channel/message_size_filter.h',
                       'src/core/lib/compression/algorithm_metadata.h',
                       'src/core/lib/compression/message_compress.h',
                       'src/core/lib/debug/trace.h',
@@ -398,6 +397,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_channel/lb_policy.h',
                       'src/core/ext/client_channel/lb_policy_factory.h',
                       'src/core/ext/client_channel/lb_policy_registry.h',
+                      'src/core/ext/client_channel/message_size_filter.h',
                       'src/core/ext/client_channel/parse_address.h',
                       'src/core/ext/client_channel/resolver.h',
                       'src/core/ext/client_channel/resolver_factory.h',
@@ -436,7 +436,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/handshaker.c',
                       'src/core/lib/channel/http_client_filter.c',
                       'src/core/lib/channel/http_server_filter.c',
-                      'src/core/lib/channel/message_size_filter.c',
                       'src/core/lib/compression/compression.c',
                       'src/core/lib/compression/message_compress.c',
                       'src/core/lib/debug/trace.c',
@@ -602,6 +601,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_channel/lb_policy.c',
                       'src/core/ext/client_channel/lb_policy_factory.c',
                       'src/core/ext/client_channel/lb_policy_registry.c',
+                      'src/core/ext/client_channel/message_size_filter.c',
                       'src/core/ext/client_channel/parse_address.c',
                       'src/core/ext/client_channel/resolver.c',
                       'src/core/ext/client_channel/resolver_factory.c',
@@ -664,7 +664,6 @@ Pod::Spec.new do |s|
                               'src/core/lib/channel/handshaker.h',
                               'src/core/lib/channel/http_client_filter.h',
                               'src/core/lib/channel/http_server_filter.h',
-                              'src/core/lib/channel/message_size_filter.h',
                               'src/core/lib/compression/algorithm_metadata.h',
                               'src/core/lib/compression/message_compress.h',
                               'src/core/lib/debug/trace.h',
@@ -805,6 +804,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/client_channel/lb_policy.h',
                               'src/core/ext/client_channel/lb_policy_factory.h',
                               'src/core/ext/client_channel/lb_policy_registry.h',
+                              'src/core/ext/client_channel/message_size_filter.h',
                               'src/core/ext/client_channel/parse_address.h',
                               'src/core/ext/client_channel/resolver.h',
                               'src/core/ext/client_channel/resolver_factory.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 9cafd1f2f9..563ad58725 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -174,7 +174,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/handshaker.h )
   s.files += %w( src/core/lib/channel/http_client_filter.h )
   s.files += %w( src/core/lib/channel/http_server_filter.h )
-  s.files += %w( src/core/lib/channel/message_size_filter.h )
   s.files += %w( src/core/lib/compression/algorithm_metadata.h )
   s.files += %w( src/core/lib/compression/message_compress.h )
   s.files += %w( src/core/lib/debug/trace.h )
@@ -315,6 +314,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_channel/lb_policy.h )
   s.files += %w( src/core/ext/client_channel/lb_policy_factory.h )
   s.files += %w( src/core/ext/client_channel/lb_policy_registry.h )
+  s.files += %w( src/core/ext/client_channel/message_size_filter.h )
   s.files += %w( src/core/ext/client_channel/parse_address.h )
   s.files += %w( src/core/ext/client_channel/resolver.h )
   s.files += %w( src/core/ext/client_channel/resolver_factory.h )
@@ -353,7 +353,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/handshaker.c )
   s.files += %w( src/core/lib/channel/http_client_filter.c )
   s.files += %w( src/core/lib/channel/http_server_filter.c )
-  s.files += %w( src/core/lib/channel/message_size_filter.c )
   s.files += %w( src/core/lib/compression/compression.c )
   s.files += %w( src/core/lib/compression/message_compress.c )
   s.files += %w( src/core/lib/debug/trace.c )
@@ -519,6 +518,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_channel/lb_policy.c )
   s.files += %w( src/core/ext/client_channel/lb_policy_factory.c )
   s.files += %w( src/core/ext/client_channel/lb_policy_registry.c )
+  s.files += %w( src/core/ext/client_channel/message_size_filter.c )
   s.files += %w( src/core/ext/client_channel/parse_address.c )
   s.files += %w( src/core/ext/client_channel/resolver.c )
   s.files += %w( src/core/ext/client_channel/resolver_factory.c )
diff --git a/package.xml b/package.xml
index 61668815a6..871495231a 100644
--- a/package.xml
+++ b/package.xml
@@ -182,7 +182,6 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.h" role="src" />
@@ -323,6 +322,7 @@
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_channel/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.h" role="src" />
@@ -361,7 +361,6 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/compression.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.c" role="src" />
@@ -527,6 +526,7 @@
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_channel/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.c" role="src" />
diff --git a/src/core/ext/client_config/message_size_filter.c b/src/core/ext/client_channel/message_size_filter.c
similarity index 99%
rename from src/core/ext/client_config/message_size_filter.c
rename to src/core/ext/client_channel/message_size_filter.c
index f0b20742e7..c6d94cb6d0 100644
--- a/src/core/ext/client_config/message_size_filter.c
+++ b/src/core/ext/client_channel/message_size_filter.c
@@ -29,7 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "src/core/ext/client_config/message_size_filter.h"
+#include "src/core/ext/client_channel/message_size_filter.h"
 
 #include <limits.h>
 #include <string.h>
diff --git a/src/core/ext/client_config/message_size_filter.h b/src/core/ext/client_channel/message_size_filter.h
similarity index 90%
rename from src/core/ext/client_config/message_size_filter.h
rename to src/core/ext/client_channel/message_size_filter.h
index a88ff7f81a..8ee4f4cca4 100644
--- a/src/core/ext/client_config/message_size_filter.h
+++ b/src/core/ext/client_channel/message_size_filter.h
@@ -29,11 +29,11 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#ifndef GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
-#define GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
+#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H
+#define GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_message_size_filter;
 
-#endif /* GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H */
+#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H */
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index d43f93b94f..804c30f798 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -84,7 +84,6 @@ CORE_SOURCE_FILES = [
   'src/core/lib/channel/handshaker.c',
   'src/core/lib/channel/http_client_filter.c',
   'src/core/lib/channel/http_server_filter.c',
-  'src/core/lib/channel/message_size_filter.c',
   'src/core/lib/compression/compression.c',
   'src/core/lib/compression/message_compress.c',
   'src/core/lib/debug/trace.c',
@@ -250,6 +249,7 @@ CORE_SOURCE_FILES = [
   'src/core/ext/client_channel/lb_policy.c',
   'src/core/ext/client_channel/lb_policy_factory.c',
   'src/core/ext/client_channel/lb_policy_registry.c',
+  'src/core/ext/client_channel/message_size_filter.c',
   'src/core/ext/client_channel/parse_address.c',
   'src/core/ext/client_channel/resolver.c',
   'src/core/ext/client_channel/resolver_factory.c',
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py
new file mode 100755
index 0000000000..32ab3f2137
--- /dev/null
+++ b/test/core/bad_client/gen_build_yaml.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python2.7
+# 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.
+
+
+"""Generates the appropriate build.json data for all the bad_client tests."""
+
+
+import collections
+import yaml
+
+TestOptions = collections.namedtuple('TestOptions', 'flaky cpu_cost')
+default_test_options = TestOptions(False, 1.0)
+
+# maps test names to options
+BAD_CLIENT_TESTS = {
+    'badreq': default_test_options,
+    'connection_prefix': default_test_options._replace(cpu_cost=0.2),
+    'headers': default_test_options._replace(cpu_cost=0.2),
+    'initial_settings_frame': default_test_options._replace(cpu_cost=0.2),
+    'head_of_line_blocking': default_test_options,
+    'large_metadata': default_test_options,
+    'server_registered_method': default_test_options,
+    'simple_request': default_test_options,
+    'window_overflow': default_test_options,
+    'unknown_frame': default_test_options,
+}
+
+def main():
+  json = {
+      '#': 'generated with test/bad_client/gen_build_json.py',
+      'libs': [
+          {
+            'name': 'bad_client_test',
+            'build': 'private',
+            'language': 'c',
+            'src': [
+              'test/core/bad_client/bad_client.c'
+            ],
+            'headers': [
+              'test/core/bad_client/bad_client.h'
+            ],
+            'vs_proj_dir': 'test/bad_client',
+            'deps': [
+              'grpc_test_util_unsecure',
+              'grpc_unsecure',
+              'gpr_test_util',
+              'gpr'
+            ]
+          }],
+      'targets': [
+          {
+              'name': '%s_bad_client_test' % t,
+              'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost,
+              'build': 'test',
+              'language': 'c',
+              'secure': 'no',
+              'src': ['test/core/bad_client/tests/%s.c' % t],
+              'vs_proj_dir': 'test',
+              'exclude_iomgrs': ['uv'],
+              'deps': [
+                  'bad_client_test',
+                  'grpc_test_util_unsecure',
+                  'grpc_unsecure',
+                  'gpr_test_util',
+                  'gpr'
+              ]
+          }
+      for t in sorted(BAD_CLIENT_TESTS.keys())]}
+  print yaml.dump(json)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 6572bd4ddf..7213d022dc 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -798,7 +798,6 @@ src/core/lib/channel/deadline_filter.h \
 src/core/lib/channel/handshaker.h \
 src/core/lib/channel/http_client_filter.h \
 src/core/lib/channel/http_server_filter.h \
-src/core/lib/channel/message_size_filter.h \
 src/core/lib/compression/algorithm_metadata.h \
 src/core/lib/compression/message_compress.h \
 src/core/lib/debug/trace.h \
@@ -939,6 +938,7 @@ src/core/ext/client_channel/initial_connect_string.h \
 src/core/ext/client_channel/lb_policy.h \
 src/core/ext/client_channel/lb_policy_factory.h \
 src/core/ext/client_channel/lb_policy_registry.h \
+src/core/ext/client_channel/message_size_filter.h \
 src/core/ext/client_channel/parse_address.h \
 src/core/ext/client_channel/resolver.h \
 src/core/ext/client_channel/resolver_factory.h \
@@ -977,7 +977,6 @@ src/core/lib/channel/deadline_filter.c \
 src/core/lib/channel/handshaker.c \
 src/core/lib/channel/http_client_filter.c \
 src/core/lib/channel/http_server_filter.c \
-src/core/lib/channel/message_size_filter.c \
 src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
 src/core/lib/debug/trace.c \
@@ -1143,6 +1142,7 @@ src/core/ext/client_channel/initial_connect_string.c \
 src/core/ext/client_channel/lb_policy.c \
 src/core/ext/client_channel/lb_policy_factory.c \
 src/core/ext/client_channel/lb_policy_registry.c \
+src/core/ext/client_channel/message_size_filter.c \
 src/core/ext/client_channel/parse_address.c \
 src/core/ext/client_channel/resolver.c \
 src/core/ext/client_channel/resolver_factory.c \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 6ae269cc20..77e6b7e8af 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6683,7 +6683,6 @@
       "src/core/lib/channel/handshaker.h", 
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.h", 
-      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/debug/trace.h", 
@@ -6803,8 +6802,6 @@
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.c", 
       "src/core/lib/channel/http_server_filter.h", 
-      "src/core/lib/channel/message_size_filter.c", 
-      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/compression.c", 
       "src/core/lib/compression/message_compress.c", 
@@ -7011,6 +7008,7 @@
       "src/core/ext/client_channel/lb_policy.h", 
       "src/core/ext/client_channel/lb_policy_factory.h", 
       "src/core/ext/client_channel/lb_policy_registry.h", 
+      "src/core/ext/client_channel/message_size_filter.h", 
       "src/core/ext/client_channel/parse_address.h", 
       "src/core/ext/client_channel/resolver.h", 
       "src/core/ext/client_channel/resolver_factory.h", 
@@ -7042,6 +7040,8 @@
       "src/core/ext/client_channel/lb_policy_factory.h", 
       "src/core/ext/client_channel/lb_policy_registry.c", 
       "src/core/ext/client_channel/lb_policy_registry.h", 
+      "src/core/ext/client_channel/message_size_filter.c", 
+      "src/core/ext/client_channel/message_size_filter.h", 
       "src/core/ext/client_channel/parse_address.c", 
       "src/core/ext/client_channel/parse_address.h", 
       "src/core/ext/client_channel/resolver.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 558b5b0c66..6725b1c18a 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -307,7 +307,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -448,6 +447,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
@@ -498,8 +498,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -830,6 +828,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index a40a1b5f1c..eb38a01ca7 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -31,9 +31,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -529,6 +526,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
+      <Filter>src\core\ext\client_channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
@@ -764,9 +764,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
@@ -1187,6 +1184,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h">
+      <Filter>src\core\ext\client_channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 2acdd32cf3..33590c5534 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -200,7 +200,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -347,8 +346,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 6c918f1254..4160413455 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -88,9 +88,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -554,9 +551,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 661192101c..6143c9c8a3 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -297,7 +297,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -415,6 +414,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
@@ -466,8 +466,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -750,6 +748,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 466116e604..8d19f4716a 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -34,9 +34,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
-      <Filter>src\core\lib\channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -460,6 +457,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
+      <Filter>src\core\ext\client_channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
@@ -677,9 +677,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
-      <Filter>src\core\lib\channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
@@ -1031,6 +1028,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h">
+      <Filter>src\core\ext\client_channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
-- 
GitLab


From c8b0fba95350235c51fb7cf3fe0f0889fb89f2c4 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 4 Jan 2017 23:32:27 +0100
Subject: [PATCH 224/344] Forgot to git add these.

---
 test/core/bad_ssl/gen_build_yaml.py | 106 ++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100755 test/core/bad_ssl/gen_build_yaml.py

diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py
new file mode 100755
index 0000000000..c17b17eb13
--- /dev/null
+++ b/test/core/bad_ssl/gen_build_yaml.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python2.7
+# 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.
+
+
+"""Generates the appropriate build.json data for all the end2end tests."""
+
+
+import collections
+import yaml
+
+TestOptions = collections.namedtuple('TestOptions', 'flaky cpu_cost')
+default_test_options = TestOptions(False, 1.0)
+
+# maps test names to options
+BAD_CLIENT_TESTS = {
+    'cert': default_test_options._replace(cpu_cost=0.1),
+    # Disabling this test because it does not link correctly as written
+    # 'alpn': default_test_options._replace(cpu_cost=0.1),
+}
+
+def main():
+  json = {
+      '#': 'generated with test/bad_ssl/gen_build_json.py',
+      'libs': [
+          {
+              'name': 'bad_ssl_test_server',
+              'build': 'private',
+              'language': 'c',
+              'src': ['test/core/bad_ssl/server_common.c'],
+              'headers': ['test/core/bad_ssl/server_common.h'],
+              'vs_proj_dir': 'test',
+              'platforms': ['linux', 'posix', 'mac'],
+              'deps': [
+                  'grpc_test_util',
+                  'grpc',
+                  'gpr_test_util',
+                  'gpr'
+              ]
+          }
+      ],
+      'targets': [
+          {
+              'name': 'bad_ssl_%s_server' % t,
+              'build': 'test',
+              'language': 'c',
+              'run': False,
+              'src': ['test/core/bad_ssl/servers/%s.c' % t],
+              'vs_proj_dir': 'test/bad_ssl',
+              'platforms': ['linux', 'posix', 'mac'],
+              'deps': [
+                  'bad_ssl_test_server',
+                  'grpc_test_util',
+                  'grpc',
+                  'gpr_test_util',
+                  'gpr'
+              ]
+          }
+      for t in sorted(BAD_CLIENT_TESTS.keys())] + [
+          {
+              'name': 'bad_ssl_%s_test' % t,
+              'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost,
+              'build': 'test',
+              'language': 'c',
+              'src': ['test/core/bad_ssl/bad_ssl_test.c'],
+              'vs_proj_dir': 'test',
+              'platforms': ['linux', 'posix', 'mac'],
+              'deps': [
+                  'grpc_test_util',
+                  'grpc',
+                  'gpr_test_util',
+                  'gpr'
+              ]
+          }
+      for t in sorted(BAD_CLIENT_TESTS.keys())]}
+  print yaml.dump(json)
+
+
+if __name__ == '__main__':
+  main()
-- 
GitLab


From 9bca58cf0ac18373847b882adf1c1c30ffdbe638 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 14:47:34 -0800
Subject: [PATCH 225/344] Remove old fixture

---
 test/core/end2end/generate_tests.bzl | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index aae8b4f7bd..2f57114504 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -51,7 +51,6 @@ END2END_FIXTURES = {
     'h2_census': fixture_options(),
     'h2_load_reporting': fixture_options(),
     'h2_fakesec': fixture_options(),
-    'h2_fake_resolver': fixture_options(),
     'h2_fd': fixture_options(dns_resolver=False, fullstack=False,
                              platforms=['linux', 'mac', 'posix']),
     'h2_full': fixture_options(),
-- 
GitLab


From 0fc9999fba0b7869206026e7e592b7b7199d997b Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 4 Jan 2017 23:50:42 +0100
Subject: [PATCH 226/344] Putting message size filter back.

---
 BUILD                                                  |  4 ++--
 CMakeLists.txt                                         |  4 ++++
 Makefile                                               |  5 +++++
 binding.gyp                                            |  1 +
 build.yaml                                             |  2 ++
 config.m4                                              |  1 +
 gRPC-Core.podspec                                      |  3 +++
 grpc.gemspec                                           |  2 ++
 package.xml                                            |  2 ++
 .../channel}/message_size_filter.c                     |  2 +-
 .../channel}/message_size_filter.h                     |  6 +++---
 src/core/lib/surface/init.c                            | 10 ++++++++++
 src/python/grpcio/grpc_core_dependencies.py            |  1 +
 tools/doxygen/Doxyfile.core.internal                   |  2 ++
 tools/run_tests/generated/sources_and_headers.json     |  3 +++
 vsprojects/vcxproj/grpc/grpc.vcxproj                   |  3 +++
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters           |  6 ++++++
 .../vcxproj/grpc_test_util/grpc_test_util.vcxproj      |  3 +++
 .../grpc_test_util/grpc_test_util.vcxproj.filters      |  6 ++++++
 vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj |  3 +++
 .../grpc_unsecure/grpc_unsecure.vcxproj.filters        |  6 ++++++
 21 files changed, 69 insertions(+), 6 deletions(-)
 rename src/core/{ext/client_channel => lib/channel}/message_size_filter.c (99%)
 rename src/core/{ext/client_channel => lib/channel}/message_size_filter.h (90%)

diff --git a/BUILD b/BUILD
index 2e040bb87c..b6b68e3060 100644
--- a/BUILD
+++ b/BUILD
@@ -423,6 +423,7 @@ grpc_cc_library(
         "src/core/lib/channel/handshaker.c",
         "src/core/lib/channel/http_client_filter.c",
         "src/core/lib/channel/http_server_filter.c",
+        "src/core/lib/channel/message_size_filter.c",
         "src/core/lib/compression/compression.c",
         "src/core/lib/compression/message_compress.c",
         "src/core/lib/debug/trace.c",
@@ -537,6 +538,7 @@ grpc_cc_library(
         "src/core/lib/channel/handshaker.h",
         "src/core/lib/channel/http_client_filter.h",
         "src/core/lib/channel/http_server_filter.h",
+        "src/core/lib/channel/message_size_filter.h",
         "src/core/lib/compression/algorithm_metadata.h",
         "src/core/lib/compression/message_compress.h",
         "src/core/lib/debug/trace.h",
@@ -659,7 +661,6 @@ grpc_cc_library(
         "src/core/ext/client_channel/lb_policy.c",
         "src/core/ext/client_channel/lb_policy_factory.c",
         "src/core/ext/client_channel/lb_policy_registry.c",
-        "src/core/ext/client_channel/message_size_filter.c",
         "src/core/ext/client_channel/parse_address.c",
         "src/core/ext/client_channel/resolver.c",
         "src/core/ext/client_channel/resolver_factory.c",
@@ -677,7 +678,6 @@ grpc_cc_library(
         "src/core/ext/client_channel/lb_policy.h",
         "src/core/ext/client_channel/lb_policy_factory.h",
         "src/core/ext/client_channel/lb_policy_registry.h",
-        "src/core/ext/client_channel/message_size_filter.h",
         "src/core/ext/client_channel/parse_address.h",
         "src/core/ext/client_channel/resolver.h",
         "src/core/ext/client_channel/resolver_factory.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3d16e3ba6c..1244fbb3da 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -294,6 +294,7 @@ add_library(grpc
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
+  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -575,6 +576,7 @@ add_library(grpc_cronet
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
+  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -827,6 +829,7 @@ add_library(grpc_unsecure
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
+  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
@@ -1294,6 +1297,7 @@ add_library(grpc++_cronet
   src/core/lib/channel/handshaker.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
+  src/core/lib/channel/message_size_filter.c
   src/core/lib/compression/compression.c
   src/core/lib/compression/message_compress.c
   src/core/lib/debug/trace.c
diff --git a/Makefile b/Makefile
index 4b35bc16e8..eca5d143f6 100644
--- a/Makefile
+++ b/Makefile
@@ -2633,6 +2633,7 @@ LIBGRPC_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -2932,6 +2933,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3221,6 +3223,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -3437,6 +3440,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
@@ -4016,6 +4020,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
diff --git a/binding.gyp b/binding.gyp
index 910e1c1053..f920e8822d 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -574,6 +574,7 @@
         'src/core/lib/channel/handshaker.c',
         'src/core/lib/channel/http_client_filter.c',
         'src/core/lib/channel/http_server_filter.c',
+        'src/core/lib/channel/message_size_filter.c',
         'src/core/lib/compression/compression.c',
         'src/core/lib/compression/message_compress.c',
         'src/core/lib/debug/trace.c',
diff --git a/build.yaml b/build.yaml
index 8d14507b15..c3db86ba4e 100644
--- a/build.yaml
+++ b/build.yaml
@@ -173,6 +173,7 @@ filegroups:
   - src/core/lib/channel/handshaker.h
   - src/core/lib/channel/http_client_filter.h
   - src/core/lib/channel/http_server_filter.h
+  - src/core/lib/channel/message_size_filter.h
   - src/core/lib/compression/algorithm_metadata.h
   - src/core/lib/compression/message_compress.h
   - src/core/lib/debug/trace.h
@@ -269,6 +270,7 @@ filegroups:
   - src/core/lib/channel/handshaker.c
   - src/core/lib/channel/http_client_filter.c
   - src/core/lib/channel/http_server_filter.c
+  - src/core/lib/channel/message_size_filter.c
   - src/core/lib/compression/compression.c
   - src/core/lib/compression/message_compress.c
   - src/core/lib/debug/trace.c
diff --git a/config.m4 b/config.m4
index e4d55c9e19..77f5136513 100644
--- a/config.m4
+++ b/config.m4
@@ -90,6 +90,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/channel/handshaker.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
+    src/core/lib/channel/message_size_filter.c \
     src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index f8b95f9152..e0ac63d682 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -257,6 +257,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/handshaker.h',
                       'src/core/lib/channel/http_client_filter.h',
                       'src/core/lib/channel/http_server_filter.h',
+                      'src/core/lib/channel/message_size_filter.h',
                       'src/core/lib/compression/algorithm_metadata.h',
                       'src/core/lib/compression/message_compress.h',
                       'src/core/lib/debug/trace.h',
@@ -436,6 +437,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/handshaker.c',
                       'src/core/lib/channel/http_client_filter.c',
                       'src/core/lib/channel/http_server_filter.c',
+                      'src/core/lib/channel/message_size_filter.c',
                       'src/core/lib/compression/compression.c',
                       'src/core/lib/compression/message_compress.c',
                       'src/core/lib/debug/trace.c',
@@ -664,6 +666,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/channel/handshaker.h',
                               'src/core/lib/channel/http_client_filter.h',
                               'src/core/lib/channel/http_server_filter.h',
+                              'src/core/lib/channel/message_size_filter.h',
                               'src/core/lib/compression/algorithm_metadata.h',
                               'src/core/lib/compression/message_compress.h',
                               'src/core/lib/debug/trace.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 563ad58725..cd41f63e0f 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -174,6 +174,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/handshaker.h )
   s.files += %w( src/core/lib/channel/http_client_filter.h )
   s.files += %w( src/core/lib/channel/http_server_filter.h )
+  s.files += %w( src/core/lib/channel/message_size_filter.h )
   s.files += %w( src/core/lib/compression/algorithm_metadata.h )
   s.files += %w( src/core/lib/compression/message_compress.h )
   s.files += %w( src/core/lib/debug/trace.h )
@@ -353,6 +354,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/handshaker.c )
   s.files += %w( src/core/lib/channel/http_client_filter.c )
   s.files += %w( src/core/lib/channel/http_server_filter.c )
+  s.files += %w( src/core/lib/channel/message_size_filter.c )
   s.files += %w( src/core/lib/compression/compression.c )
   s.files += %w( src/core/lib/compression/message_compress.c )
   s.files += %w( src/core/lib/debug/trace.c )
diff --git a/package.xml b/package.xml
index 871495231a..2e1a6b18ca 100644
--- a/package.xml
+++ b/package.xml
@@ -182,6 +182,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.h" role="src" />
@@ -361,6 +362,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/compression.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.c" role="src" />
diff --git a/src/core/ext/client_channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
similarity index 99%
rename from src/core/ext/client_channel/message_size_filter.c
rename to src/core/lib/channel/message_size_filter.c
index c6d94cb6d0..b5e882de52 100644
--- a/src/core/ext/client_channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -29,7 +29,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "src/core/ext/client_channel/message_size_filter.h"
+#include "src/core/lib/channel/message_size_filter.h"
 
 #include <limits.h>
 #include <string.h>
diff --git a/src/core/ext/client_channel/message_size_filter.h b/src/core/lib/channel/message_size_filter.h
similarity index 90%
rename from src/core/ext/client_channel/message_size_filter.h
rename to src/core/lib/channel/message_size_filter.h
index 8ee4f4cca4..a88ff7f81a 100644
--- a/src/core/ext/client_channel/message_size_filter.h
+++ b/src/core/lib/channel/message_size_filter.h
@@ -29,11 +29,11 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H
+#ifndef GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
+#define GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H
 
 #include "src/core/lib/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_message_size_filter;
 
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_MESSAGE_SIZE_FILTER_H */
+#endif /* GRPC_CORE_LIB_CHANNEL_MESSAGE_SIZE_FILTER_H */
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 64aa0e3361..7903f57a68 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -46,6 +46,7 @@
 #include "src/core/lib/channel/deadline_filter.h"
 #include "src/core/lib/channel/http_client_filter.h"
 #include "src/core/lib/channel/http_server_filter.h"
+#include "src/core/lib/channel/message_size_filter.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -106,6 +107,15 @@ static void register_builtin_channel_init() {
   grpc_channel_init_register_stage(
       GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
       (void *)&grpc_server_deadline_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      prepend_filter, (void *)&grpc_message_size_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      prepend_filter, (void *)&grpc_message_size_filter);
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
+      (void *)&grpc_message_size_filter);
   grpc_channel_init_register_stage(
       GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, prepend_filter,
       (void *)&grpc_compress_filter);
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 804c30f798..179df7bb14 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -84,6 +84,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/channel/handshaker.c',
   'src/core/lib/channel/http_client_filter.c',
   'src/core/lib/channel/http_server_filter.c',
+  'src/core/lib/channel/message_size_filter.c',
   'src/core/lib/compression/compression.c',
   'src/core/lib/compression/message_compress.c',
   'src/core/lib/debug/trace.c',
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 7213d022dc..0b529535a9 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -798,6 +798,7 @@ src/core/lib/channel/deadline_filter.h \
 src/core/lib/channel/handshaker.h \
 src/core/lib/channel/http_client_filter.h \
 src/core/lib/channel/http_server_filter.h \
+src/core/lib/channel/message_size_filter.h \
 src/core/lib/compression/algorithm_metadata.h \
 src/core/lib/compression/message_compress.h \
 src/core/lib/debug/trace.h \
@@ -977,6 +978,7 @@ src/core/lib/channel/deadline_filter.c \
 src/core/lib/channel/handshaker.c \
 src/core/lib/channel/http_client_filter.c \
 src/core/lib/channel/http_server_filter.c \
+src/core/lib/channel/message_size_filter.c \
 src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
 src/core/lib/debug/trace.c \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 77e6b7e8af..d304021b2e 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6683,6 +6683,7 @@
       "src/core/lib/channel/handshaker.h", 
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.h", 
+      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/debug/trace.h", 
@@ -6802,6 +6803,8 @@
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.c", 
       "src/core/lib/channel/http_server_filter.h", 
+      "src/core/lib/channel/message_size_filter.c", 
+      "src/core/lib/channel/message_size_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
       "src/core/lib/compression/compression.c", 
       "src/core/lib/compression/message_compress.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 6725b1c18a..8fe4a86ef0 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -307,6 +307,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -498,6 +499,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index eb38a01ca7..886a695679 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -31,6 +31,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -764,6 +767,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 33590c5534..2acdd32cf3 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -200,6 +200,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -346,6 +347,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 4160413455..6c918f1254 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -88,6 +88,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -551,6 +554,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 6143c9c8a3..a280e84d8c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -297,6 +297,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
@@ -466,6 +467,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 8d19f4716a..d400ec8826 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -34,6 +34,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
@@ -677,6 +680,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
       <Filter>src\core\lib\compression</Filter>
     </ClInclude>
-- 
GitLab


From 9f87ee2792b9d47749f70a007fbbad3bf3e76968 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 14:55:35 -0800
Subject: [PATCH 227/344] Fixes for tests

---
 BUILD                           | 1 +
 test/core/end2end/fuzzers/BUILD | 3 +--
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/BUILD b/BUILD
index 2e040bb87c..527b0f60c7 100644
--- a/BUILD
+++ b/BUILD
@@ -647,6 +647,7 @@ grpc_cc_library(
 
 grpc_cc_library(
     name = "grpc_client_channel",
+    language = "c",
     srcs = [
         "src/core/ext/client_channel/channel_connectivity.c",
         "src/core/ext/client_channel/client_channel.c",
diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD
index d08603148e..2adda560b4 100644
--- a/test/core/end2end/fuzzers/BUILD
+++ b/test/core/end2end/fuzzers/BUILD
@@ -32,7 +32,7 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 grpc_fuzzer(
   name = "api_fuzzer",
   srcs = ["api_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 = "api_fuzzer_corpus",
   copts = ["-std=c99"],
 )
@@ -52,4 +52,3 @@ grpc_fuzzer(
   corpus = "server_fuzzer_corpus",
   copts = ["-std=c99"],
 )
-
-- 
GitLab


From 16f155bcfcc49b4334781cab8c324da566f521fc Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 15:06:39 -0800
Subject: [PATCH 228/344] Fixes for tests

---
 test/core/end2end/generate_tests.bzl | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 2f57114504..31f330c6b9 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -86,6 +86,7 @@ def test_options(needs_fullstack=False, needs_dns=False, proxyable=True,
 END2END_TESTS = {
     'bad_hostname': test_options(),
     'binary_metadata': test_options(),
+    'resource_quota_server': test_options(proxyable=False),
     'call_creds': test_options(secure=True),
     'cancel_after_accept': test_options(),
     'cancel_after_client_done': test_options(),
@@ -128,6 +129,8 @@ END2END_TESTS = {
     'simple_request': test_options(),
     'streaming_error_response': test_options(),
     'trailing_metadata': test_options(),
+    'authority_not_supported': test_options(),
+    'filter_latency': test_options(),
 }
 
 
@@ -150,7 +153,7 @@ def compatible(fopt, topt):
 def grpc_end2end_tests():
   native.cc_library(
     name = 'end2end_tests',
-    srcs = ['end2end_tests.c'] + [
+    srcs = ['end2end_tests.c', 'end2end_test_utils.c'] + [
              'tests/%s.c' % t
              for t in sorted(END2END_TESTS.keys())],
     hdrs = [
-- 
GitLab


From c2390cc01b64fdf94c33dd8b593eaae03316fc45 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 5 Jan 2017 00:35:58 +0100
Subject: [PATCH 229/344] Properly removing message_size_filter duplicate.

---
 CMakeLists.txt                                              | 4 ----
 Makefile                                                    | 4 ----
 binding.gyp                                                 | 1 -
 build.yaml                                                  | 2 --
 config.m4                                                   | 1 -
 gRPC-Core.podspec                                           | 3 ---
 grpc.gemspec                                                | 2 --
 package.xml                                                 | 2 --
 src/python/grpcio/grpc_core_dependencies.py                 | 1 -
 tools/doxygen/Doxyfile.core.internal                        | 2 --
 tools/run_tests/generated/sources_and_headers.json          | 3 ---
 vsprojects/vcxproj/grpc/grpc.vcxproj                        | 3 ---
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters                | 6 ------
 vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj      | 3 ---
 .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters     | 6 ------
 15 files changed, 43 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1244fbb3da..ff0927504a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -460,7 +460,6 @@ add_library(grpc
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -716,7 +715,6 @@ add_library(grpc_cronet
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -971,7 +969,6 @@ add_library(grpc_unsecure
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
@@ -1412,7 +1409,6 @@ add_library(grpc++_cronet
   src/core/ext/client_channel/lb_policy.c
   src/core/ext/client_channel/lb_policy_factory.c
   src/core/ext/client_channel/lb_policy_registry.c
-  src/core/ext/client_channel/message_size_filter.c
   src/core/ext/client_channel/parse_address.c
   src/core/ext/client_channel/resolver.c
   src/core/ext/client_channel/resolver_factory.c
diff --git a/Makefile b/Makefile
index eca5d143f6..8f7328ae28 100644
--- a/Makefile
+++ b/Makefile
@@ -2799,7 +2799,6 @@ LIBGRPC_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -3073,7 +3072,6 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -3582,7 +3580,6 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
@@ -4135,7 +4132,6 @@ LIBGRPC++_CRONET_SRC = \
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
diff --git a/binding.gyp b/binding.gyp
index f920e8822d..516cbdce5d 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -740,7 +740,6 @@
         'src/core/ext/client_channel/lb_policy.c',
         'src/core/ext/client_channel/lb_policy_factory.c',
         'src/core/ext/client_channel/lb_policy_registry.c',
-        'src/core/ext/client_channel/message_size_filter.c',
         'src/core/ext/client_channel/parse_address.c',
         'src/core/ext/client_channel/resolver.c',
         'src/core/ext/client_channel/resolver_factory.c',
diff --git a/build.yaml b/build.yaml
index c3db86ba4e..de9d253ef1 100644
--- a/build.yaml
+++ b/build.yaml
@@ -387,7 +387,6 @@ filegroups:
   - src/core/ext/client_channel/lb_policy.h
   - src/core/ext/client_channel/lb_policy_factory.h
   - src/core/ext/client_channel/lb_policy_registry.h
-  - src/core/ext/client_channel/message_size_filter.h
   - src/core/ext/client_channel/parse_address.h
   - src/core/ext/client_channel/resolver.h
   - src/core/ext/client_channel/resolver_factory.h
@@ -407,7 +406,6 @@ filegroups:
   - src/core/ext/client_channel/lb_policy.c
   - src/core/ext/client_channel/lb_policy_factory.c
   - src/core/ext/client_channel/lb_policy_registry.c
-  - src/core/ext/client_channel/message_size_filter.c
   - src/core/ext/client_channel/parse_address.c
   - src/core/ext/client_channel/resolver.c
   - src/core/ext/client_channel/resolver_factory.c
diff --git a/config.m4 b/config.m4
index 77f5136513..4b86e25581 100644
--- a/config.m4
+++ b/config.m4
@@ -256,7 +256,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_channel/lb_policy.c \
     src/core/ext/client_channel/lb_policy_factory.c \
     src/core/ext/client_channel/lb_policy_registry.c \
-    src/core/ext/client_channel/message_size_filter.c \
     src/core/ext/client_channel/parse_address.c \
     src/core/ext/client_channel/resolver.c \
     src/core/ext/client_channel/resolver_factory.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index e0ac63d682..e10e534a5e 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -398,7 +398,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_channel/lb_policy.h',
                       'src/core/ext/client_channel/lb_policy_factory.h',
                       'src/core/ext/client_channel/lb_policy_registry.h',
-                      'src/core/ext/client_channel/message_size_filter.h',
                       'src/core/ext/client_channel/parse_address.h',
                       'src/core/ext/client_channel/resolver.h',
                       'src/core/ext/client_channel/resolver_factory.h',
@@ -603,7 +602,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_channel/lb_policy.c',
                       'src/core/ext/client_channel/lb_policy_factory.c',
                       'src/core/ext/client_channel/lb_policy_registry.c',
-                      'src/core/ext/client_channel/message_size_filter.c',
                       'src/core/ext/client_channel/parse_address.c',
                       'src/core/ext/client_channel/resolver.c',
                       'src/core/ext/client_channel/resolver_factory.c',
@@ -807,7 +805,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/client_channel/lb_policy.h',
                               'src/core/ext/client_channel/lb_policy_factory.h',
                               'src/core/ext/client_channel/lb_policy_registry.h',
-                              'src/core/ext/client_channel/message_size_filter.h',
                               'src/core/ext/client_channel/parse_address.h',
                               'src/core/ext/client_channel/resolver.h',
                               'src/core/ext/client_channel/resolver_factory.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index cd41f63e0f..9cafd1f2f9 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -315,7 +315,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_channel/lb_policy.h )
   s.files += %w( src/core/ext/client_channel/lb_policy_factory.h )
   s.files += %w( src/core/ext/client_channel/lb_policy_registry.h )
-  s.files += %w( src/core/ext/client_channel/message_size_filter.h )
   s.files += %w( src/core/ext/client_channel/parse_address.h )
   s.files += %w( src/core/ext/client_channel/resolver.h )
   s.files += %w( src/core/ext/client_channel/resolver_factory.h )
@@ -520,7 +519,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_channel/lb_policy.c )
   s.files += %w( src/core/ext/client_channel/lb_policy_factory.c )
   s.files += %w( src/core/ext/client_channel/lb_policy_registry.c )
-  s.files += %w( src/core/ext/client_channel/message_size_filter.c )
   s.files += %w( src/core/ext/client_channel/parse_address.c )
   s.files += %w( src/core/ext/client_channel/resolver.c )
   s.files += %w( src/core/ext/client_channel/resolver_factory.c )
diff --git a/package.xml b/package.xml
index 2e1a6b18ca..61668815a6 100644
--- a/package.xml
+++ b/package.xml
@@ -323,7 +323,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/message_size_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.h" role="src" />
@@ -528,7 +527,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/lb_policy_registry.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_channel/message_size_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/parse_address.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_channel/resolver_factory.c" role="src" />
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 179df7bb14..d43f93b94f 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -250,7 +250,6 @@ CORE_SOURCE_FILES = [
   'src/core/ext/client_channel/lb_policy.c',
   'src/core/ext/client_channel/lb_policy_factory.c',
   'src/core/ext/client_channel/lb_policy_registry.c',
-  'src/core/ext/client_channel/message_size_filter.c',
   'src/core/ext/client_channel/parse_address.c',
   'src/core/ext/client_channel/resolver.c',
   'src/core/ext/client_channel/resolver_factory.c',
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 0b529535a9..6572bd4ddf 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -939,7 +939,6 @@ src/core/ext/client_channel/initial_connect_string.h \
 src/core/ext/client_channel/lb_policy.h \
 src/core/ext/client_channel/lb_policy_factory.h \
 src/core/ext/client_channel/lb_policy_registry.h \
-src/core/ext/client_channel/message_size_filter.h \
 src/core/ext/client_channel/parse_address.h \
 src/core/ext/client_channel/resolver.h \
 src/core/ext/client_channel/resolver_factory.h \
@@ -1144,7 +1143,6 @@ src/core/ext/client_channel/initial_connect_string.c \
 src/core/ext/client_channel/lb_policy.c \
 src/core/ext/client_channel/lb_policy_factory.c \
 src/core/ext/client_channel/lb_policy_registry.c \
-src/core/ext/client_channel/message_size_filter.c \
 src/core/ext/client_channel/parse_address.c \
 src/core/ext/client_channel/resolver.c \
 src/core/ext/client_channel/resolver_factory.c \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index d304021b2e..6ae269cc20 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -7011,7 +7011,6 @@
       "src/core/ext/client_channel/lb_policy.h", 
       "src/core/ext/client_channel/lb_policy_factory.h", 
       "src/core/ext/client_channel/lb_policy_registry.h", 
-      "src/core/ext/client_channel/message_size_filter.h", 
       "src/core/ext/client_channel/parse_address.h", 
       "src/core/ext/client_channel/resolver.h", 
       "src/core/ext/client_channel/resolver_factory.h", 
@@ -7043,8 +7042,6 @@
       "src/core/ext/client_channel/lb_policy_factory.h", 
       "src/core/ext/client_channel/lb_policy_registry.c", 
       "src/core/ext/client_channel/lb_policy_registry.h", 
-      "src/core/ext/client_channel/message_size_filter.c", 
-      "src/core/ext/client_channel/message_size_filter.h", 
       "src/core/ext/client_channel/parse_address.c", 
       "src/core/ext/client_channel/parse_address.h", 
       "src/core/ext/client_channel/resolver.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 8fe4a86ef0..558b5b0c66 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -448,7 +448,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
@@ -831,8 +830,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 886a695679..a40a1b5f1c 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -529,9 +529,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
-      <Filter>src\core\ext\client_channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
@@ -1190,9 +1187,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h">
-      <Filter>src\core\ext\client_channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index a280e84d8c..661192101c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -415,7 +415,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver_factory.h" />
@@ -751,8 +750,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\resolver.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index d400ec8826..466116e604 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -460,9 +460,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.c">
-      <Filter>src\core\ext\client_channel</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.c">
       <Filter>src\core\ext\client_channel</Filter>
     </ClCompile>
@@ -1034,9 +1031,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\lb_policy_registry.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\message_size_filter.h">
-      <Filter>src\core\ext\client_channel</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\parse_address.h">
       <Filter>src\core\ext\client_channel</Filter>
     </ClInclude>
-- 
GitLab


From 17dfaf1a6e6dfe03b9fbcfff4f2101fcc77a22cc Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 5 Jan 2017 01:05:30 +0100
Subject: [PATCH 230/344] Fixing submodules sanity.

---
 tools/run_tests/sanity/check_submodules.sh | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index be12f968d2..61e8185854 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -41,13 +41,14 @@ want_submodules=`mktemp /tmp/submXXXXXX`
 
 git submodule | awk '{ print $1 }' | sort > $submodules
 cat << EOF | awk '{ print $1 }' | sort > $want_submodules
- c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9 third_party/boringssl (version_for_cocoapods_2.0-100-gc880e42)
- 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  44c25c892a6229b20db7cd9dc05584ea865896de third_party/benchmark (v0.1.0-343-g44c25c8)
+ c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9 third_party/boringssl (c880e42)
+ 886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7)
+ 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
- a428e42072765993ff674fda72863c9f1aa2d268 third_party/protobuf (v3.1.0)
+ a428e42072765993ff674fda72863c9f1aa2d268 third_party/protobuf (v3.1.0-alpha-1)
+ bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift (bcad917)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
- bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift
 EOF
 
 diff -u $submodules $want_submodules
-- 
GitLab


From 4b53d3511395328ddf3a9d0d3bd48efaf1f7e57d Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 16:05:46 -0800
Subject: [PATCH 231/344] Faster test building: avoid repeated linking

---
 test/core/end2end/end2end_test.sh         | 33 +++++++++++++++++++++++
 test/core/end2end/generate_tests.bzl      | 11 ++++----
 test/core/util/BUILD                      |  6 +++++
 test/core/util/fuzzer_one_entry_runner.sh | 33 +++++++++++++++++++++++
 test/core/util/grpc_fuzzer.bzl            | 12 ++++-----
 5 files changed, 84 insertions(+), 11 deletions(-)
 create mode 100755 test/core/end2end/end2end_test.sh
 create mode 100755 test/core/util/fuzzer_one_entry_runner.sh

diff --git a/test/core/end2end/end2end_test.sh b/test/core/end2end/end2end_test.sh
new file mode 100755
index 0000000000..f2309acc88
--- /dev/null
+++ b/test/core/end2end/end2end_test.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Test runner for end2end tests from bazel
+
+# 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.
+$1 $2
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 31f330c6b9..ed1ba3eea9 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -175,8 +175,8 @@ def grpc_end2end_tests():
   )
 
   for f, fopt in END2END_FIXTURES.items():
-    native.cc_library(
-      name = '%s_test_lib' % f,
+    native.cc_binary(
+      name = '%s_test' % f,
       srcs = ['fixtures/%s.c' % f],
       copts = ['-std=c99'],
       deps = [':end2end_tests']
@@ -184,8 +184,9 @@ def grpc_end2end_tests():
     for t, topt in END2END_TESTS.items():
       #print(compatible(fopt, topt), f, t, fopt, topt)
       if not compatible(fopt, topt): continue
-      native.cc_test(
+      native.sh_test(
         name = '%s_test@%s' % (f, t),
-        args = [t],
-        deps = [':%s_test_lib' % f],
+        srcs = ['end2end_test.sh'],
+        args = ['$(location %s_test)' % f, t],
+        data = [':%s_test' % f],
       )
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index e44e4e2105..e50e595d03 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -50,3 +50,9 @@ cc_library(
   deps = [":gpr_test_util", "//:grpc"],
   visibility = ["//test:__subpackages__"],
 )
+
+sh_library(
+  name = "fuzzer_one_entry_runner",
+  srcs = ["fuzzer_one_entry_runner.sh"],
+  visibility = ["//test:__subpackages__"],
+)
diff --git a/test/core/util/fuzzer_one_entry_runner.sh b/test/core/util/fuzzer_one_entry_runner.sh
new file mode 100755
index 0000000000..a0558a9c09
--- /dev/null
+++ b/test/core/util/fuzzer_one_entry_runner.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Test runner for fuzzer tests from bazel
+
+# 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.
+$1 $2
diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl
index 3ec9e4e485..2f552a9fdb 100644
--- a/test/core/util/grpc_fuzzer.bzl
+++ b/test/core/util/grpc_fuzzer.bzl
@@ -28,16 +28,16 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs):
-  native.cc_library(
-    name = "%s/one_entry" % name,
+  native.cc_binary(
+    name = '%s/one_entry.bin' % name,
     srcs = srcs,
     deps = deps + ["//test/core/util:one_corpus_entry_fuzzer"],
     **kwargs
   )
   for entry in native.glob(['%s/*' % corpus]):
-    native.cc_test(
+    native.sh_test(
       name = '%s/one_entry/%s' % (name, entry),
-      deps = [':%s/one_entry' % name],
-      args = ['$(location %s)' % entry],
-      data = [entry],
+      data = [':%s/one_entry.bin' % name, entry],
+      srcs = ['//test/core/util:fuzzer_one_entry_runner'],
+      args = ['$(location :%s/one_entry.bin)' % name, '$(location %s)' % entry]
     )
-- 
GitLab


From a3a5b2d68c45745277a6b91366aeab1a6b739b5d Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 4 Jan 2017 16:07:50 -0800
Subject: [PATCH 232/344] Remove errant header

---
 src/core/ext/transport/chttp2/client/chttp2_connector.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index bf4d797938..2385f91dbd 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -47,7 +47,6 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/iomgr/tcp_client.h"
-#include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/slice/slice_internal.h"
 
 typedef struct {
-- 
GitLab


From 4e6247a23cf94bc363abb2e8eb0d2b03195b9c5d Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 5 Jan 2017 10:17:01 -0800
Subject: [PATCH 233/344] Fix sequential write buffering

---
 Makefile                                      |   2 +
 include/grpc/impl/codegen/grpc_types.h        |   3 +
 .../chttp2/transport/chttp2_transport.c       |  31 +-
 .../ext/transport/chttp2/transport/internal.h |   6 +
 test/core/end2end/end2end_nosec_tests.c       |   8 +
 test/core/end2end/end2end_tests.c             |   8 +
 test/core/end2end/gen_build_yaml.py           |   1 +
 test/core/end2end/generate_tests.bzl          |   1 +
 test/core/end2end/tests/write_buffering.c     | 291 +++++++
 .../generated/sources_and_headers.json        |   6 +-
 tools/run_tests/generated/tests.json          | 738 +++++++++++++++++-
 .../end2end_nosec_tests.vcxproj               |   2 +
 .../end2end_nosec_tests.vcxproj.filters       |   3 +
 .../tests/end2end_tests/end2end_tests.vcxproj |   2 +
 .../end2end_tests.vcxproj.filters             |   3 +
 15 files changed, 1085 insertions(+), 20 deletions(-)
 create mode 100644 test/core/end2end/tests/write_buffering.c

diff --git a/Makefile b/Makefile
index 8f7328ae28..edcf50ec71 100644
--- a/Makefile
+++ b/Makefile
@@ -7215,6 +7215,7 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
+    test/core/end2end/tests/write_buffering.c \
 
 PUBLIC_HEADERS_C += \
 
@@ -7301,6 +7302,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
+    test/core/end2end/tests/write_buffering.c \
 
 PUBLIC_HEADERS_C += \
 
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 4471ccf745..4dfd879499 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -179,6 +179,9 @@ typedef struct {
     Larger values give lower CPU usage for large messages, but more head of line
     blocking for small messages. */
 #define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
+/** How much data are we willing to queue up per stream if
+    GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
+#define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"
 /** Default authority to pass if none specified on call construction. A string.
  * */
 #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 488c3b93cc..30c66d8952 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -269,6 +269,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
      window -- this should by rights be 0 */
   t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
   t->sent_local_settings = 0;
+  t->write_buffer_size = DEFAULT_WINDOW;
 
   if (is_client) {
     grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
@@ -319,6 +320,11 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
           grpc_chttp2_hpack_compressor_set_max_usable_size(&t->hpack_compressor,
                                                            (uint32_t)value);
         }
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
+        t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
+            &channel_args->args[i],
+            (grpc_integer_options){0, 0, 64 * 1024 * 1024});
       } else {
         static const struct {
           const char *channel_arg_name;
@@ -895,15 +901,22 @@ static bool contains_non_ok_status(grpc_metadata_batch *batch) {
   return false;
 }
 
+static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx *exec_ctx,
+                                                  grpc_chttp2_transport *t,
+                                                  grpc_chttp2_stream *s) {
+  if (s->id != 0 && (!s->write_buffering ||
+                     s->flow_controlled_buffer.length > t->write_buffer_size)) {
+    grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
+  }
+}
+
 static void add_fetched_slice_locked(grpc_exec_ctx *exec_ctx,
                                      grpc_chttp2_transport *t,
                                      grpc_chttp2_stream *s) {
   s->fetched_send_message_length +=
       (uint32_t)GRPC_SLICE_LENGTH(s->fetching_slice);
   grpc_slice_buffer_add(&s->flow_controlled_buffer, s->fetching_slice);
-  if (s->id != 0) {
-    grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
-  }
+  maybe_become_writable_due_to_send_msg(exec_ctx, t, s);
 }
 
 static void continue_fetching_send_locked(grpc_exec_ctx *exec_ctx,
@@ -1096,14 +1109,13 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
                                    (int64_t)len;
       s->complete_fetch_covered_by_poller = op->covered_by_poller;
       if (flags & GRPC_WRITE_BUFFER_HINT) {
-        /* allow up to 64kb to be buffered */
-        /* TODO(ctiller): make this configurable */
-        s->next_message_end_offset -= 65536;
+        s->next_message_end_offset -= t->write_buffer_size;
+        s->write_buffering = true;
+      } else {
+        s->write_buffering = false;
       }
       continue_fetching_send_locked(exec_ctx, t, s);
-      if (s->id != 0) {
-        grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
-      }
+      maybe_become_writable_due_to_send_msg(exec_ctx, t, s);
     }
   }
 
@@ -1112,6 +1124,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
     on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
     s->send_trailing_metadata_finished = add_closure_barrier(on_complete);
     s->send_trailing_metadata = op->send_trailing_metadata;
+    s->write_buffering = false;
     const size_t metadata_size =
         grpc_metadata_batch_size(op->send_trailing_metadata);
     const size_t metadata_peer_limit =
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index a52acbacdb..ea7beb4c2b 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -249,6 +249,9 @@ struct grpc_chttp2_transport {
   int64_t announce_incoming_window;
   /** how much window would we like to have for incoming_window */
   uint32_t connection_window_target;
+  /** how much data are we willing to buffer when the WRITE_BUFFER_HINT is set?
+   */
+  uint32_t write_buffer_size;
 
   /** have we seen a goaway */
   uint8_t seen_goaway;
@@ -403,6 +406,9 @@ struct grpc_chttp2_stream {
   /** Has this stream seen an error.
       If true, then pending incoming frames can be thrown away. */
   bool seen_error;
+  /** Are we buffering writes on this stream? If yes, we won't become writable
+      until there's enough queued up in the flow_controlled_buffer */
+  bool write_buffering;
 
   /** the error that resulted in this stream being read-closed */
   grpc_error *read_closed_error;
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index 663489082f..03e98ee850 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -135,6 +135,8 @@ extern void streaming_error_response(grpc_end2end_test_config config);
 extern void streaming_error_response_pre_init(void);
 extern void trailing_metadata(grpc_end2end_test_config config);
 extern void trailing_metadata_pre_init(void);
+extern void write_buffering(grpc_end2end_test_config config);
+extern void write_buffering_pre_init(void);
 
 void grpc_end2end_tests_pre_init(void) {
   GPR_ASSERT(!g_pre_init_called);
@@ -185,6 +187,7 @@ void grpc_end2end_tests_pre_init(void) {
   simple_request_pre_init();
   streaming_error_response_pre_init();
   trailing_metadata_pre_init();
+  write_buffering_pre_init();
 }
 
 void grpc_end2end_tests(int argc, char **argv,
@@ -240,6 +243,7 @@ void grpc_end2end_tests(int argc, char **argv,
     simple_request(config);
     streaming_error_response(config);
     trailing_metadata(config);
+    write_buffering(config);
     return;
   }
 
@@ -428,6 +432,10 @@ void grpc_end2end_tests(int argc, char **argv,
       trailing_metadata(config);
       continue;
     }
+    if (0 == strcmp("write_buffering", argv[i])) {
+      write_buffering(config);
+      continue;
+    }
     gpr_log(GPR_DEBUG, "not a test: '%s'", argv[i]);
     abort();
   }
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index 25c7c62fde..f116dc0c70 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -137,6 +137,8 @@ extern void streaming_error_response(grpc_end2end_test_config config);
 extern void streaming_error_response_pre_init(void);
 extern void trailing_metadata(grpc_end2end_test_config config);
 extern void trailing_metadata_pre_init(void);
+extern void write_buffering(grpc_end2end_test_config config);
+extern void write_buffering_pre_init(void);
 
 void grpc_end2end_tests_pre_init(void) {
   GPR_ASSERT(!g_pre_init_called);
@@ -188,6 +190,7 @@ void grpc_end2end_tests_pre_init(void) {
   simple_request_pre_init();
   streaming_error_response_pre_init();
   trailing_metadata_pre_init();
+  write_buffering_pre_init();
 }
 
 void grpc_end2end_tests(int argc, char **argv,
@@ -244,6 +247,7 @@ void grpc_end2end_tests(int argc, char **argv,
     simple_request(config);
     streaming_error_response(config);
     trailing_metadata(config);
+    write_buffering(config);
     return;
   }
 
@@ -436,6 +440,10 @@ void grpc_end2end_tests(int argc, char **argv,
       trailing_metadata(config);
       continue;
     }
+    if (0 == strcmp("write_buffering", argv[i])) {
+      write_buffering(config);
+      continue;
+    }
     gpr_log(GPR_DEBUG, "not a test: '%s'", argv[i]);
     abort();
   }
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 201a92a1fd..52142c2640 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -143,6 +143,7 @@ END2END_TESTS = {
     'streaming_error_response': default_test_options,
     'trailing_metadata': default_test_options,
     'authority_not_supported': default_test_options,
+    'write_buffering': default_test_options,
 }
 
 
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index ed1ba3eea9..8195abab69 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -131,6 +131,7 @@ END2END_TESTS = {
     'trailing_metadata': test_options(),
     'authority_not_supported': test_options(),
     'filter_latency': test_options(),
+    'write_buffering': test_options(),
 }
 
 
diff --git a/test/core/end2end/tests/write_buffering.c b/test/core/end2end/tests/write_buffering.c
new file mode 100644
index 0000000000..856e9f0306
--- /dev/null
+++ b/test/core/end2end/tests/write_buffering.c
@@ -0,0 +1,291 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/end2end/cq_verifier.h"
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char *test_name,
+                                            grpc_channel_args *client_args,
+                                            grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  config.init_server(&f, server_args);
+  config.init_client(&f, client_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(
+                 f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+                 .type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+}
+
+/* Client sends a request with payload, server reads then returns status. */
+static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
+  grpc_call *c;
+  grpc_call *s;
+  grpc_slice request_payload_slice1 =
+      grpc_slice_from_copied_string("hello world");
+  grpc_byte_buffer *request_payload1 =
+      grpc_raw_byte_buffer_create(&request_payload_slice1, 1);
+  grpc_slice request_payload_slice2 = grpc_slice_from_copied_string("abc123");
+  grpc_byte_buffer *request_payload2 =
+      grpc_raw_byte_buffer_create(&request_payload_slice2, 1);
+  gpr_timespec deadline = five_seconds_time();
+  grpc_end2end_test_fixture f =
+      begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_byte_buffer *request_payload_recv1 = NULL;
+  grpc_byte_buffer *request_payload_recv2 = NULL;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  char *details = NULL;
+  size_t details_capacity = 0;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
+      get_host_override_string("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
+                                 f.server, &s, &call_details,
+                                 &request_metadata_recv, f.cq, f.cq, tag(101)));
+  CQ_EXPECT_COMPLETION(cqv, tag(1), true); /* send message is buffered */
+  CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message = request_payload1;
+  op->flags = GRPC_WRITE_BUFFER_HINT;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  /* recv message should not succeed yet - it's buffered at the client still */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv1;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(3), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+  cq_verify(cqv);
+
+  /* send another message, this time not buffered */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message = request_payload2;
+  op->flags = 0;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  /* now the first send should match up with the first recv */
+  CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(4), true);
+  cq_verify(cqv);
+
+  /* and the next recv should be ready immediately also */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv2;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(104), true);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->data.recv_status_on_client.status_details_capacity = &details_capacity;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_OK;
+  op->data.send_status_from_server.status_details = "xyz";
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(105), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_OK);
+  GPR_ASSERT(0 == strcmp(details, "xyz"));
+  GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 0);
+  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world"));
+  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv2, "abc123"));
+
+  gpr_free(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_destroy(c);
+  grpc_call_destroy(s);
+
+  cq_verifier_destroy(cqv);
+
+  grpc_byte_buffer_destroy(request_payload1);
+  grpc_byte_buffer_destroy(request_payload_recv1);
+  grpc_byte_buffer_destroy(request_payload2);
+  grpc_byte_buffer_destroy(request_payload_recv2);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void write_buffering(grpc_end2end_test_config config) {
+  test_invoke_request_with_payload(config);
+}
+
+void write_buffering_pre_init(void) {}
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 6ae269cc20..3755f242e0 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6362,7 +6362,8 @@
       "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/streaming_error_response.c", 
-      "test/core/end2end/tests/trailing_metadata.c"
+      "test/core/end2end/tests/trailing_metadata.c", 
+      "test/core/end2end/tests/write_buffering.c"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -6431,7 +6432,8 @@
       "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/streaming_error_response.c", 
-      "test/core/end2end/tests/trailing_metadata.c"
+      "test/core/end2end/tests/trailing_metadata.c", 
+      "test/core/end2end/tests/write_buffering.c"
     ], 
     "third_party": false, 
     "type": "lib"
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b76263b8b9..50992aa436 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -6080,6 +6080,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -7163,6 +7186,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -8199,6 +8245,28 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -9165,6 +9233,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -10248,6 +10339,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -11141,6 +11255,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -12178,6 +12311,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -13306,6 +13462,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -14389,6 +14569,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -15517,6 +15720,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -16477,6 +16704,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -17487,7 +17738,7 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "write_buffering"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17501,7 +17752,7 @@
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_sockpair+trace_test", 
+    "name": "h2_sockpair_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -17511,7 +17762,7 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17535,7 +17786,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17559,7 +17810,7 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17583,14 +17834,14 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17607,14 +17858,38 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18421,6 +18696,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -19487,6 +19786,32 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -20570,6 +20895,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -21653,6 +22001,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -22613,6 +22984,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -23671,6 +24066,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -24731,6 +25149,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -25791,6 +26232,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -26734,6 +27198,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -27794,6 +28281,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -28668,6 +29178,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -29682,6 +30211,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -30786,6 +31338,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -31846,6 +32422,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -32782,6 +33381,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -33766,6 +34389,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -34678,6 +35325,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -35718,6 +36389,32 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -36753,6 +37450,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "--scenarios_json", 
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
index 4fb8f8f4a1..5f1ea5ed27 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
@@ -247,6 +247,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
index ff82a4dd43..5f38c36f78 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
@@ -145,6 +145,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_test_helpers.h">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
index 0b7d7c2e75..83e57eff7d 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -249,6 +249,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
index e641930e64..00587c05b8 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
@@ -148,6 +148,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_test_helpers.h">
-- 
GitLab


From 2ef5a647bfb2bc9390a14be843647c2fb7841b36 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 5 Jan 2017 10:33:47 -0800
Subject: [PATCH 234/344] Add a test of finishing buffering with EOS

---
 Makefile                                      |   2 +
 test/core/end2end/end2end_nosec_tests.c       |   8 +
 test/core/end2end/end2end_tests.c             |   8 +
 test/core/end2end/gen_build_yaml.py           |   1 +
 test/core/end2end/generate_tests.bzl          |   1 +
 .../end2end/tests/write_buffering_at_end.c    | 280 +++++++
 .../generated/sources_and_headers.json        |   6 +-
 tools/run_tests/generated/tests.json          | 738 +++++++++++++++++-
 .../end2end_nosec_tests.vcxproj               |   2 +
 .../end2end_nosec_tests.vcxproj.filters       |   3 +
 .../tests/end2end_tests/end2end_tests.vcxproj |   2 +
 .../end2end_tests.vcxproj.filters             |   3 +
 12 files changed, 1043 insertions(+), 11 deletions(-)
 create mode 100644 test/core/end2end/tests/write_buffering_at_end.c

diff --git a/Makefile b/Makefile
index edcf50ec71..da06d17547 100644
--- a/Makefile
+++ b/Makefile
@@ -7216,6 +7216,7 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
     test/core/end2end/tests/write_buffering.c \
+    test/core/end2end/tests/write_buffering_at_end.c \
 
 PUBLIC_HEADERS_C += \
 
@@ -7303,6 +7304,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/streaming_error_response.c \
     test/core/end2end/tests/trailing_metadata.c \
     test/core/end2end/tests/write_buffering.c \
+    test/core/end2end/tests/write_buffering_at_end.c \
 
 PUBLIC_HEADERS_C += \
 
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index 03e98ee850..b162bf2f40 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -137,6 +137,8 @@ extern void trailing_metadata(grpc_end2end_test_config config);
 extern void trailing_metadata_pre_init(void);
 extern void write_buffering(grpc_end2end_test_config config);
 extern void write_buffering_pre_init(void);
+extern void write_buffering_at_end(grpc_end2end_test_config config);
+extern void write_buffering_at_end_pre_init(void);
 
 void grpc_end2end_tests_pre_init(void) {
   GPR_ASSERT(!g_pre_init_called);
@@ -188,6 +190,7 @@ void grpc_end2end_tests_pre_init(void) {
   streaming_error_response_pre_init();
   trailing_metadata_pre_init();
   write_buffering_pre_init();
+  write_buffering_at_end_pre_init();
 }
 
 void grpc_end2end_tests(int argc, char **argv,
@@ -244,6 +247,7 @@ void grpc_end2end_tests(int argc, char **argv,
     streaming_error_response(config);
     trailing_metadata(config);
     write_buffering(config);
+    write_buffering_at_end(config);
     return;
   }
 
@@ -436,6 +440,10 @@ void grpc_end2end_tests(int argc, char **argv,
       write_buffering(config);
       continue;
     }
+    if (0 == strcmp("write_buffering_at_end", argv[i])) {
+      write_buffering_at_end(config);
+      continue;
+    }
     gpr_log(GPR_DEBUG, "not a test: '%s'", argv[i]);
     abort();
   }
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index f116dc0c70..9bca0c81f6 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -139,6 +139,8 @@ extern void trailing_metadata(grpc_end2end_test_config config);
 extern void trailing_metadata_pre_init(void);
 extern void write_buffering(grpc_end2end_test_config config);
 extern void write_buffering_pre_init(void);
+extern void write_buffering_at_end(grpc_end2end_test_config config);
+extern void write_buffering_at_end_pre_init(void);
 
 void grpc_end2end_tests_pre_init(void) {
   GPR_ASSERT(!g_pre_init_called);
@@ -191,6 +193,7 @@ void grpc_end2end_tests_pre_init(void) {
   streaming_error_response_pre_init();
   trailing_metadata_pre_init();
   write_buffering_pre_init();
+  write_buffering_at_end_pre_init();
 }
 
 void grpc_end2end_tests(int argc, char **argv,
@@ -248,6 +251,7 @@ void grpc_end2end_tests(int argc, char **argv,
     streaming_error_response(config);
     trailing_metadata(config);
     write_buffering(config);
+    write_buffering_at_end(config);
     return;
   }
 
@@ -444,6 +448,10 @@ void grpc_end2end_tests(int argc, char **argv,
       write_buffering(config);
       continue;
     }
+    if (0 == strcmp("write_buffering_at_end", argv[i])) {
+      write_buffering_at_end(config);
+      continue;
+    }
     gpr_log(GPR_DEBUG, "not a test: '%s'", argv[i]);
     abort();
   }
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 52142c2640..bcb7136eaa 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -144,6 +144,7 @@ END2END_TESTS = {
     'trailing_metadata': default_test_options,
     'authority_not_supported': default_test_options,
     'write_buffering': default_test_options,
+    'write_buffering_at_end': default_test_options,
 }
 
 
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 8195abab69..95c06de73f 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -132,6 +132,7 @@ END2END_TESTS = {
     'authority_not_supported': test_options(),
     'filter_latency': test_options(),
     'write_buffering': test_options(),
+    'write_buffering_at_end': test_options(),
 }
 
 
diff --git a/test/core/end2end/tests/write_buffering_at_end.c b/test/core/end2end/tests/write_buffering_at_end.c
new file mode 100644
index 0000000000..43aefcbdbc
--- /dev/null
+++ b/test/core/end2end/tests/write_buffering_at_end.c
@@ -0,0 +1,280 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/end2end/cq_verifier.h"
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char *test_name,
+                                            grpc_channel_args *client_args,
+                                            grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  config.init_server(&f, server_args);
+  config.init_client(&f, client_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(
+                 f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+                 .type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+}
+
+/* Client sends a request with payload, server reads then returns status. */
+static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
+  grpc_call *c;
+  grpc_call *s;
+  grpc_slice request_payload_slice =
+      grpc_slice_from_copied_string("hello world");
+  grpc_byte_buffer *request_payload =
+      grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  gpr_timespec deadline = five_seconds_time();
+  grpc_end2end_test_fixture f =
+      begin_test(config, "test_invoke_request_with_payload", NULL, NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_byte_buffer *request_payload_recv1 = NULL;
+  grpc_byte_buffer *request_payload_recv2 = NULL;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  char *details = NULL;
+  size_t details_capacity = 0;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(
+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
+      get_host_override_string("foo.test.google.fr:1234", config), deadline,
+      NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
+                                 f.server, &s, &call_details,
+                                 &request_metadata_recv, f.cq, f.cq, tag(101)));
+  CQ_EXPECT_COMPLETION(cqv, tag(1), true); /* send message is buffered */
+  CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message = request_payload;
+  op->flags = GRPC_WRITE_BUFFER_HINT;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  /* recv message should not succeed yet - it's buffered at the client still */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv1;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(3), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+  cq_verify(cqv);
+
+  /* send end of stream: should release the buffering */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  /* now the first send should match up with the first recv */
+  CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+  CQ_EXPECT_COMPLETION(cqv, tag(4), true);
+  cq_verify(cqv);
+
+  /* and the next recv should be ready immediately also (and empty) */
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv2;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(104), true);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->data.recv_status_on_client.status_details_capacity = &details_capacity;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_OK;
+  op->data.send_status_from_server.status_details = "xyz";
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(105), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_OK);
+  GPR_ASSERT(0 == strcmp(details, "xyz"));
+  GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 0);
+  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world"));
+  GPR_ASSERT(request_payload_recv2 == NULL);
+
+  gpr_free(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_destroy(c);
+  grpc_call_destroy(s);
+
+  cq_verifier_destroy(cqv);
+
+  grpc_byte_buffer_destroy(request_payload);
+  grpc_byte_buffer_destroy(request_payload_recv1);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void write_buffering_at_end(grpc_end2end_test_config config) {
+  test_invoke_request_with_payload(config);
+}
+
+void write_buffering_at_end_pre_init(void) {}
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 3755f242e0..9287c83974 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6363,7 +6363,8 @@
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/streaming_error_response.c", 
       "test/core/end2end/tests/trailing_metadata.c", 
-      "test/core/end2end/tests/write_buffering.c"
+      "test/core/end2end/tests/write_buffering.c", 
+      "test/core/end2end/tests/write_buffering_at_end.c"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -6433,7 +6434,8 @@
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/streaming_error_response.c", 
       "test/core/end2end/tests/trailing_metadata.c", 
-      "test/core/end2end/tests/write_buffering.c"
+      "test/core/end2end/tests/write_buffering.c", 
+      "test/core/end2end/tests/write_buffering_at_end.c"
     ], 
     "third_party": false, 
     "type": "lib"
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 50992aa436..9ac477c5cd 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -6103,6 +6103,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -7209,6 +7232,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -8267,6 +8313,28 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -9256,6 +9324,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -10362,6 +10453,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -11274,6 +11388,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -12334,6 +12467,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -13486,6 +13642,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -14592,6 +14772,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -15744,6 +15947,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -16728,6 +16955,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -17762,7 +18013,7 @@
   }, 
   {
     "args": [
-      "authority_not_supported"
+      "write_buffering_at_end"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17776,7 +18027,7 @@
     ], 
     "flaky": false, 
     "language": "c", 
-    "name": "h2_sockpair+trace_test", 
+    "name": "h2_sockpair_test", 
     "platforms": [
       "windows", 
       "linux", 
@@ -17786,7 +18037,7 @@
   }, 
   {
     "args": [
-      "bad_hostname"
+      "authority_not_supported"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17810,7 +18061,7 @@
   }, 
   {
     "args": [
-      "binary_metadata"
+      "bad_hostname"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17834,7 +18085,7 @@
   }, 
   {
     "args": [
-      "call_creds"
+      "binary_metadata"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17858,14 +18109,14 @@
   }, 
   {
     "args": [
-      "cancel_after_accept"
+      "call_creds"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 0.1, 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -17882,14 +18133,38 @@
   }, 
   {
     "args": [
-      "cancel_after_client_done"
+      "cancel_after_accept"
     ], 
     "ci_platforms": [
       "windows", 
       "linux", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [
       "uv"
@@ -18720,6 +18995,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -19812,6 +20111,32 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -20918,6 +21243,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -22024,6 +22372,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -23008,6 +23379,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -24089,6 +24484,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -25172,6 +25590,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -26255,6 +26696,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -27221,6 +27685,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -28304,6 +28791,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -29197,6 +29707,25 @@
       "linux"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -30234,6 +30763,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -31362,6 +31914,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -32445,6 +33021,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -33405,6 +34004,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -34413,6 +35036,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -35349,6 +35996,30 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -36415,6 +37086,32 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "authority_not_supported"
@@ -37473,6 +38170,29 @@
       "posix"
     ]
   }, 
+  {
+    "args": [
+      "write_buffering_at_end"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [
       "--scenarios_json", 
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
index 5f1ea5ed27..6506f24d1b 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
@@ -249,6 +249,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering_at_end.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
index 5f38c36f78..77e5ebf8b1 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
@@ -148,6 +148,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering_at_end.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_test_helpers.h">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
index 83e57eff7d..176e8f7197 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -251,6 +251,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering_at_end.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
index 00587c05b8..fa70267933 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
@@ -151,6 +151,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\write_buffering_at_end.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_test_helpers.h">
-- 
GitLab


From 599db64d0beb5cf88be4fa3b5d1f251046e46778 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 5 Jan 2017 11:21:59 -0800
Subject: [PATCH 235/344] Support long grpc-messages on abnormal close path

---
 .../ext/transport/chttp2/transport/chttp2_transport.c  | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 488c3b93cc..8a4b8978c8 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -47,6 +47,7 @@
 #include "src/core/ext/transport/chttp2/transport/http2_errors.h"
 #include "src/core/ext/transport/chttp2/transport/internal.h"
 #include "src/core/ext/transport/chttp2/transport/status_conversion.h"
+#include "src/core/ext/transport/chttp2/transport/varint.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/workqueue.h"
@@ -1672,8 +1673,9 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 
     if (optional_message != NULL) {
       size_t msg_len = strlen(optional_message);
-      GPR_ASSERT(msg_len < 127);
-      message_pfx = grpc_slice_malloc(15);
+      GPR_ASSERT(msg_len <= UINT32_MAX);
+      uint32_t msg_len_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)msg_len, 0);
+      message_pfx = grpc_slice_malloc(14 + msg_len_len);
       p = GRPC_SLICE_START_PTR(message_pfx);
       *p++ = 0x40;
       *p++ = 12; /* len(grpc-message) */
@@ -1689,7 +1691,9 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
       *p++ = 'a';
       *p++ = 'g';
       *p++ = 'e';
-      *p++ = (uint8_t)msg_len;
+      GRPC_CHTTP2_WRITE_VARINT((uint32_t)msg_len, 0, 0, p,
+                               (uint32_t)msg_len_len);
+      p += msg_len_len;
       GPR_ASSERT(p == GRPC_SLICE_END_PTR(message_pfx));
       len += (uint32_t)GRPC_SLICE_LENGTH(message_pfx);
       len += (uint32_t)msg_len;
-- 
GitLab


From 229def1a863a26715e9f66b033c4c1a65d781c1a Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Thu, 5 Jan 2017 05:40:51 +0100
Subject: [PATCH 236/344] Adding Bazel tests.

---
 .../dockerfile/test/bazel/Dockerfile.template | 48 ++++++++++++
 tools/dockerfile/test/bazel/Dockerfile        | 78 +++++++++++++++++++
 tools/jenkins/run_bazel_basic.sh              | 38 +++++++++
 tools/jenkins/run_bazel_basic_in_docker.sh    | 42 ++++++++++
 tools/jenkins/run_bazel_full.sh               | 38 +++++++++
 tools/jenkins/run_bazel_full_in_docker.sh     | 42 ++++++++++
 6 files changed, 286 insertions(+)
 create mode 100644 templates/tools/dockerfile/test/bazel/Dockerfile.template
 create mode 100644 tools/dockerfile/test/bazel/Dockerfile
 create mode 100755 tools/jenkins/run_bazel_basic.sh
 create mode 100755 tools/jenkins/run_bazel_basic_in_docker.sh
 create mode 100755 tools/jenkins/run_bazel_full.sh
 create mode 100755 tools/jenkins/run_bazel_full_in_docker.sh

diff --git a/templates/tools/dockerfile/test/bazel/Dockerfile.template b/templates/tools/dockerfile/test/bazel/Dockerfile.template
new file mode 100644
index 0000000000..82f90bef68
--- /dev/null
+++ b/templates/tools/dockerfile/test/bazel/Dockerfile.template
@@ -0,0 +1,48 @@
+%YAML 1.2
+--- |
+  # 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.
+  
+  FROM ubuntu:15.10
+  
+  <%include file="../../apt_get_basic.include"/>
+
+  #========================
+  # Bazel installation
+  RUN apt-get install -y software-properties-common g++
+  RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list
+  RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
+  RUN apt-get -y update
+  RUN apt-get -y install bazel
+
+  RUN mkdir -p /var/local/jenkins
+  
+  # Define the default command.
+  CMD ["bash"]
+  
diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile
new file mode 100644
index 0000000000..cc41384833
--- /dev/null
+++ b/tools/dockerfile/test/bazel/Dockerfile
@@ -0,0 +1,78 @@
+# 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.
+
+FROM ubuntu:15.10
+
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  gyp \
+  lcov \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
+
+
+#========================
+# Bazel installation
+RUN apt-get install -y software-properties-common g++
+RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list
+RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
+RUN apt-get -y update
+RUN apt-get -y install bazel
+
+RUN mkdir -p /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/jenkins/run_bazel_basic.sh b/tools/jenkins/run_bazel_basic.sh
new file mode 100755
index 0000000000..648bc791bd
--- /dev/null
+++ b/tools/jenkins/run_bazel_basic.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# 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 basic Bazel features
+#
+# NOTE: No empty lines should appear in this file before igncr is set!
+set -ex -o igncr || set -ex
+
+export DOCKERFILE_DIR=tools/dockerfile/test/bazel
+export DOCKER_RUN_SCRIPT=tools/jenkins/run_bazel_basic_in_docker.sh
+exec tools/run_tests/dockerize/build_and_run_docker.sh
diff --git a/tools/jenkins/run_bazel_basic_in_docker.sh b/tools/jenkins/run_bazel_basic_in_docker.sh
new file mode 100755
index 0000000000..51aaa90ff8
--- /dev/null
+++ b/tools/jenkins/run_bazel_basic_in_docker.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+# 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 basic Bazel features
+#
+# NOTE: No empty lines should appear in this file before igncr is set!
+set -ex -o igncr || set -ex
+
+mkdir -p /var/local/git
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
+cd /var/local/git/grpc
+bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/...
diff --git a/tools/jenkins/run_bazel_full.sh b/tools/jenkins/run_bazel_full.sh
new file mode 100755
index 0000000000..53ed360c07
--- /dev/null
+++ b/tools/jenkins/run_bazel_full.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# 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 full Bazel
+#
+# NOTE: No empty lines should appear in this file before igncr is set!
+set -ex -o igncr || set -ex
+
+export DOCKERFILE_DIR=tools/dockerfile/test/bazel
+export DOCKER_RUN_SCRIPT=tools/jenkins/run_bazel_full_in_docker.sh
+exec tools/run_tests/dockerize/build_and_run_docker.sh
diff --git a/tools/jenkins/run_bazel_full_in_docker.sh b/tools/jenkins/run_bazel_full_in_docker.sh
new file mode 100755
index 0000000000..19502f19b7
--- /dev/null
+++ b/tools/jenkins/run_bazel_full_in_docker.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+# 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 full Bazel
+#
+# NOTE: No empty lines should appear in this file before igncr is set!
+set -ex -o igncr || set -ex
+
+mkdir -p /var/local/git
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
+cd /var/local/git/grpc/test
+bazel test --spawn_strategy=standalone --genrule_strategy=standalone ...
-- 
GitLab


From b5b4372670190e680520236c5f3c7d79058f5931 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Thu, 5 Jan 2017 15:07:26 -0800
Subject: [PATCH 237/344] Use `grpc_closure`s in `grpc_timer`s

---
 .../ext/client_channel/channel_connectivity.c |  5 ++-
 src/core/ext/client_channel/subchannel.c      |  6 ++-
 src/core/ext/lb_policy/grpclb/grpclb.c        |  7 ++-
 .../ext/resolver/dns/native/dns_resolver.c    |  6 ++-
 src/core/lib/channel/deadline_filter.c        |  7 ++-
 src/core/lib/channel/deadline_filter.h        |  1 +
 src/core/lib/channel/handshaker.c             |  5 ++-
 src/core/lib/iomgr/tcp_client_posix.c         |  4 +-
 src/core/lib/iomgr/tcp_client_uv.c            |  5 ++-
 src/core/lib/iomgr/tcp_client_windows.c       |  4 +-
 src/core/lib/iomgr/timer.h                    | 16 +++----
 src/core/lib/iomgr/timer_generic.c            | 15 +++----
 src/core/lib/iomgr/timer_generic.h            |  2 +-
 src/core/lib/iomgr/timer_uv.c                 | 13 +++---
 src/core/lib/iomgr/timer_uv.h                 |  2 +-
 src/core/lib/surface/alarm.c                  |  5 ++-
 test/core/end2end/fuzzers/api_fuzzer.c        | 18 ++++----
 test/core/iomgr/timer_list_test.c             | 43 ++++++++++++-------
 18 files changed, 104 insertions(+), 60 deletions(-)

diff --git a/src/core/ext/client_channel/channel_connectivity.c b/src/core/ext/client_channel/channel_connectivity.c
index b10f444b63..dd70bc2c6c 100644
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ b/src/core/ext/client_channel/channel_connectivity.c
@@ -76,6 +76,7 @@ typedef struct {
   gpr_mu mu;
   callback_phase phase;
   grpc_closure on_complete;
+  grpc_closure on_timeout;
   grpc_timer alarm;
   grpc_connectivity_state state;
   grpc_completion_queue *cq;
@@ -200,6 +201,8 @@ void grpc_channel_watch_connectivity_state(
   gpr_mu_init(&w->mu);
   grpc_closure_init(&w->on_complete, watch_complete, w,
                     grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&w->on_timeout, timeout_complete, w,
+                    grpc_schedule_on_exec_ctx);
   w->phase = WAITING;
   w->state = last_observed_state;
   w->cq = cq;
@@ -208,7 +211,7 @@ void grpc_channel_watch_connectivity_state(
 
   grpc_timer_init(&exec_ctx, &w->alarm,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
-                  timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC));
+                  &w->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC));
 
   if (client_channel_elem->filter == &grpc_client_channel_filter) {
     GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index fad5c69c83..1bac82b451 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -109,6 +109,9 @@ struct grpc_subchannel {
   /** callback for connection finishing */
   grpc_closure connected;
 
+  /** callback for our alarm */
+  grpc_closure on_alarm;
+
   /** pollset_set tracking who's interested in a connection
       being setup */
   grpc_pollset_set *pollset_set;
@@ -483,7 +486,8 @@ static void maybe_start_connecting_locked(grpc_exec_ctx *exec_ctx,
       gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
               time_til_next.tv_sec, time_til_next.tv_nsec);
     }
-    grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now);
+    grpc_closure_init(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
+    grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, &c->on_alarm, now);
   }
 }
 
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 2d48a3a9e7..97f98df03a 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -327,6 +327,9 @@ typedef struct glb_lb_policy {
   /* A response from the LB server has been received. Process it */
   grpc_closure lb_on_response_received;
 
+  /* LB call retry timer callback. */
+  grpc_closure lb_on_call_retry;
+
   grpc_call *lb_call; /* streaming call to the LB server, */
 
   grpc_metadata_array lb_initial_metadata_recv; /* initial MD from LB server */
@@ -1364,8 +1367,10 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
       }
     }
     GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "grpclb_retry_timer");
+    grpc_closure_init(&glb_policy->lb_on_call_retry, lb_call_on_retry_timer,
+                      glb_policy, grpc_schedule_on_exec_ctx);
     grpc_timer_init(exec_ctx, &glb_policy->lb_call_retry_timer, next_try,
-                    lb_call_on_retry_timer, glb_policy, now);
+                    &glb_policy->lb_on_call_retry, now);
   }
   gpr_mu_unlock(&glb_policy->mu);
   GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 124b16bbc3..bb2b012507 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -81,6 +81,7 @@ typedef struct {
   /** retry timer */
   bool have_retry_timer;
   grpc_timer retry_timer;
+  grpc_closure on_retry;
   /** retry backoff state */
   gpr_backoff backoff_state;
 
@@ -199,8 +200,9 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
     } else {
       gpr_log(GPR_DEBUG, "retrying immediately");
     }
-    grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r,
-                    now);
+    grpc_closure_init(&r->on_retry, dns_on_retry_timer, r,
+                      grpc_schedule_on_exec_ctx);
+    grpc_timer_init(exec_ctx, &r->retry_timer, next_try, &r->on_retry, now);
   }
   if (r->resolved_result != NULL) {
     grpc_channel_args_destroy(exec_ctx, r->resolved_result);
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 8dd6d099e1..a45a4d4b82 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -83,8 +83,11 @@ static void start_timer_if_needed_locked(grpc_exec_ctx* exec_ctx,
     // Take a reference to the call stack, to be owned by the timer.
     GRPC_CALL_STACK_REF(deadline_state->call_stack, "deadline_timer");
     deadline_state->timer_pending = true;
-    grpc_timer_init(exec_ctx, &deadline_state->timer, deadline, timer_callback,
-                    elem, gpr_now(GPR_CLOCK_MONOTONIC));
+    grpc_closure_init(&deadline_state->timer_callback, timer_callback, elem,
+                      grpc_schedule_on_exec_ctx);
+    grpc_timer_init(exec_ctx, &deadline_state->timer, deadline,
+                    &deadline_state->timer_callback,
+                    gpr_now(GPR_CLOCK_MONOTONIC));
   }
 }
 static void start_timer_if_needed(grpc_exec_ctx* exec_ctx,
diff --git a/src/core/lib/channel/deadline_filter.h b/src/core/lib/channel/deadline_filter.h
index 716a852565..bd2b84f79e 100644
--- a/src/core/lib/channel/deadline_filter.h
+++ b/src/core/lib/channel/deadline_filter.h
@@ -46,6 +46,7 @@ typedef struct grpc_deadline_state {
   bool timer_pending;
   // The deadline timer.
   grpc_timer timer;
+  grpc_closure timer_callback;
   // Closure to invoke when the call is complete.
   // We use this to cancel the timer.
   grpc_closure on_complete;
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index ff827527b3..c052ca5385 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -86,6 +86,7 @@ struct grpc_handshake_manager {
   grpc_tcp_server_acceptor* acceptor;
   // Deadline timer across all handshakers.
   grpc_timer deadline_timer;
+  grpc_closure on_timeout;
   // The final callback and user_data to invoke after the last handshaker.
   grpc_closure on_handshake_done;
   void* user_data;
@@ -224,9 +225,11 @@ void grpc_handshake_manager_do_handshake(
                     grpc_schedule_on_exec_ctx);
   // Start deadline timer, which owns a ref.
   gpr_ref(&mgr->refs);
+  grpc_closure_init(&mgr->on_timeout, on_timeout, mgr,
+                    grpc_schedule_on_exec_ctx);
   grpc_timer_init(exec_ctx, &mgr->deadline_timer,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
-                  on_timeout, mgr, gpr_now(GPR_CLOCK_MONOTONIC));
+                  &mgr->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC));
   // Start first handshaker, which also owns a ref.
   gpr_ref(&mgr->refs);
   bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE);
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index c8237dc38f..9a77c92016 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -65,6 +65,7 @@ typedef struct {
   grpc_fd *fd;
   gpr_timespec deadline;
   grpc_timer alarm;
+  grpc_closure on_alarm;
   int refs;
   grpc_closure write_closure;
   grpc_pollset_set *interested_parties;
@@ -352,9 +353,10 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
   }
 
   gpr_mu_lock(&ac->mu);
+  grpc_closure_init(&ac->on_alarm, tc_on_alarm, ac, grpc_schedule_on_exec_ctx);
   grpc_timer_init(exec_ctx, &ac->alarm,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
-                  tc_on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC));
+                  &ac->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
   grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure);
   gpr_mu_unlock(&ac->mu);
 
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index ed0de50fc1..5225a5402b 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -49,6 +49,7 @@
 typedef struct grpc_uv_tcp_connect {
   uv_connect_t connect_req;
   grpc_timer alarm;
+  grpc_closure on_alarm;
   uv_tcp_t *tcp_handle;
   grpc_closure *closure;
   grpc_endpoint **endpoint;
@@ -148,9 +149,11 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
   uv_tcp_connect(&connect->connect_req, connect->tcp_handle,
                  (const struct sockaddr *)resolved_addr->addr,
                  uv_tc_on_connect);
+  grpc_closure_init(&connect->on_alarm, uv_tc_on_alarm, connect,
+                    grpc_schedule_on_exec_ctx);
   grpc_timer_init(exec_ctx, &connect->alarm,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
-                  uv_tc_on_alarm, connect, gpr_now(GPR_CLOCK_MONOTONIC));
+                  &connect->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
 }
 
 // overridden by api_fuzzer.c
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 275258ebb5..1e84ec3a1e 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -58,6 +58,7 @@ typedef struct {
   grpc_winsocket *socket;
   gpr_timespec deadline;
   grpc_timer alarm;
+  grpc_closure on_alarm;
   char *addr_name;
   int refs;
   grpc_closure on_connect;
@@ -229,7 +230,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
   ac->resource_quota = resource_quota;
   grpc_closure_init(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx);
 
-  grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac,
+  grpc_closure_init(&ac->on_alarm, on_alarm, ac, grpc_schedule_on_exec_ctx);
+  grpc_timer_init(exec_ctx, &ac->alarm, deadline, &ac->on_alarm,
                   gpr_now(GPR_CLOCK_MONOTONIC));
   grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect);
   return;
diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h
index 20fe98c4a7..d84a278b18 100644
--- a/src/core/lib/iomgr/timer.h
+++ b/src/core/lib/iomgr/timer.h
@@ -49,15 +49,15 @@
 
 typedef struct grpc_timer grpc_timer;
 
-/* Initialize *timer. When expired or canceled, timer_cb will be called with
-   *timer_cb_arg and error set to indicate if it expired (GRPC_ERROR_NONE) or
-   was canceled (GRPC_ERROR_CANCELLED). timer_cb is guaranteed to be called
-   exactly once, and application code should check the error to determine
-   how it was invoked. The application callback is also responsible for
-   maintaining information about when to free up any user-level state. */
+/* Initialize *timer. When expired or canceled, closure will be called with
+   error set to indicate if it expired (GRPC_ERROR_NONE) or was canceled
+   (GRPC_ERROR_CANCELLED). timer_cb is guaranteed to be called exactly once, and
+   application code should check the error to determine how it was invoked. The
+   application callback is also responsible for maintaining information about
+   when to free up any user-level state. */
 void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
-                     gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
-                     void *timer_cb_arg, gpr_timespec now);
+                     gpr_timespec deadline, grpc_closure *closure,
+                     gpr_timespec now);
 
 /* Note that there is no timer destroy function. This is because the
    timer is a one-time occurrence with a guarantee that the callback will
diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c
index ecd3b284dc..40c8351472 100644
--- a/src/core/lib/iomgr/timer_generic.c
+++ b/src/core/lib/iomgr/timer_generic.c
@@ -178,28 +178,27 @@ static void note_deadline_change(shard_type *shard) {
 }
 
 void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
-                     gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
-                     void *timer_cb_arg, gpr_timespec now) {
+                     gpr_timespec deadline, grpc_closure *closure,
+                     gpr_timespec now) {
   int is_first_timer = 0;
   shard_type *shard = &g_shards[shard_idx(timer)];
   GPR_ASSERT(deadline.clock_type == g_clock_type);
   GPR_ASSERT(now.clock_type == g_clock_type);
-  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
-                    grpc_schedule_on_exec_ctx);
+  timer->closure = closure;
   timer->deadline = deadline;
   timer->triggered = 0;
 
   if (!g_initialized) {
     timer->triggered = 1;
     grpc_closure_sched(
-        exec_ctx, &timer->closure,
+        exec_ctx, timer->closure,
         GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
     return;
   }
 
   if (gpr_time_cmp(deadline, now) <= 0) {
     timer->triggered = 1;
-    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
+    grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_NONE);
     return;
   }
 
@@ -251,7 +250,7 @@ void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
   shard_type *shard = &g_shards[shard_idx(timer)];
   gpr_mu_lock(&shard->mu);
   if (!timer->triggered) {
-    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
+    grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
     timer->triggered = 1;
     if (timer->heap_index == INVALID_HEAP_INDEX) {
       list_remove(timer);
@@ -317,7 +316,7 @@ static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
   grpc_timer *timer;
   gpr_mu_lock(&shard->mu);
   while ((timer = pop_one(shard, now))) {
-    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_REF(error));
+    grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_REF(error));
     n++;
   }
   *new_min_deadline = compute_min_deadline(shard);
diff --git a/src/core/lib/iomgr/timer_generic.h b/src/core/lib/iomgr/timer_generic.h
index e4494adb5f..9d901c7e68 100644
--- a/src/core/lib/iomgr/timer_generic.h
+++ b/src/core/lib/iomgr/timer_generic.h
@@ -43,7 +43,7 @@ struct grpc_timer {
   int triggered;
   struct grpc_timer *next;
   struct grpc_timer *prev;
-  grpc_closure closure;
+  grpc_closure *closure;
 };
 
 #endif /* GRPC_CORE_LIB_IOMGR_TIMER_GENERIC_H */
diff --git a/src/core/lib/iomgr/timer_uv.c b/src/core/lib/iomgr/timer_uv.c
index 00b835ffb8..fa2cdee964 100644
--- a/src/core/lib/iomgr/timer_uv.c
+++ b/src/core/lib/iomgr/timer_uv.c
@@ -55,21 +55,20 @@ void run_expired_timer(uv_timer_t *handle) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GPR_ASSERT(!timer->triggered);
   timer->triggered = 1;
-  grpc_closure_sched(&exec_ctx, &timer->closure, GRPC_ERROR_NONE);
+  grpc_closure_sched(&exec_ctx, timer->closure, GRPC_ERROR_NONE);
   stop_uv_timer(handle);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
-                     gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
-                     void *timer_cb_arg, gpr_timespec now) {
+                     gpr_timespec deadline, grpc_closure *closure,
+                     gpr_timespec now) {
   uint64_t timeout;
   uv_timer_t *uv_timer;
-  grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
-                    grpc_schedule_on_exec_ctx);
+  timer->closure = closure;
   if (gpr_time_cmp(deadline, now) <= 0) {
     timer->triggered = 1;
-    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
+    grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_NONE);
     return;
   }
   timer->triggered = 0;
@@ -84,7 +83,7 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
 void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
   if (!timer->triggered) {
     timer->triggered = 1;
-    grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
+    grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
     stop_uv_timer((uv_timer_t *)timer->uv_timer);
   }
 }
diff --git a/src/core/lib/iomgr/timer_uv.h b/src/core/lib/iomgr/timer_uv.h
index 3de383ebd5..13cf8bd4fa 100644
--- a/src/core/lib/iomgr/timer_uv.h
+++ b/src/core/lib/iomgr/timer_uv.h
@@ -37,7 +37,7 @@
 #include "src/core/lib/iomgr/exec_ctx.h"
 
 struct grpc_timer {
-  grpc_closure closure;
+  grpc_closure *closure;
   /* This is actually a uv_timer_t*, but we want to keep platform-specific
      types out of headers */
   void *uv_timer;
diff --git a/src/core/lib/surface/alarm.c b/src/core/lib/surface/alarm.c
index aa9d60ee6a..e71c0ebfc5 100644
--- a/src/core/lib/surface/alarm.c
+++ b/src/core/lib/surface/alarm.c
@@ -38,6 +38,7 @@
 
 struct grpc_alarm {
   grpc_timer alarm;
+  grpc_closure on_alarm;
   grpc_cq_completion completion;
   /** completion queue where events about this alarm will be posted */
   grpc_completion_queue *cq;
@@ -64,9 +65,11 @@ grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline,
   alarm->tag = tag;
 
   grpc_cq_begin_op(cq, tag);
+  grpc_closure_init(&alarm->on_alarm, alarm_cb, alarm,
+                    grpc_schedule_on_exec_ctx);
   grpc_timer_init(&exec_ctx, &alarm->alarm,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
-                  alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC));
+                  &alarm->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
   grpc_exec_ctx_finish(&exec_ctx);
   return alarm;
 }
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 6c7cbadea3..200a51858a 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -369,10 +369,11 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
   r->addr = gpr_strdup(addr);
   r->on_done = on_done;
   r->addrs = addresses;
-  grpc_timer_init(exec_ctx, &r->timer,
-                  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                               gpr_time_from_seconds(1, GPR_TIMESPAN)),
-                  finish_resolve, r, gpr_now(GPR_CLOCK_MONOTONIC));
+  grpc_timer_init(
+      exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                                        gpr_time_from_seconds(1, GPR_TIMESPAN)),
+      grpc_closure_create(finish_resolve, r, grpc_schedule_on_exec_ctx),
+      gpr_now(GPR_CLOCK_MONOTONIC));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -430,10 +431,11 @@ static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
   fc->closure = closure;
   fc->ep = ep;
   fc->deadline = deadline;
-  grpc_timer_init(exec_ctx, &fc->timer,
-                  gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                               gpr_time_from_millis(1, GPR_TIMESPAN)),
-                  do_connect, fc, gpr_now(GPR_CLOCK_MONOTONIC));
+  grpc_timer_init(
+      exec_ctx, &fc->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                                         gpr_time_from_millis(1, GPR_TIMESPAN)),
+      grpc_closure_create(do_connect, fc, grpc_schedule_on_exec_ctx),
+      gpr_now(GPR_CLOCK_MONOTONIC));
 }
 
 static void my_tcp_client_connect(grpc_exec_ctx *exec_ctx,
diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c
index be8988ab75..8d7ac3fdaa 100644
--- a/test/core/iomgr/timer_list_test.c
+++ b/test/core/iomgr/timer_list_test.c
@@ -57,17 +57,20 @@ static void add_test(void) {
 
   /* 10 ms timers.  will expire in the current epoch */
   for (i = 0; i < 10; i++) {
-    grpc_timer_init(&exec_ctx, &timers[i],
-                    gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
-                    cb, (void *)(intptr_t)i, start);
+    grpc_timer_init(
+        &exec_ctx, &timers[i],
+        gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
+        grpc_closure_create(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx),
+        start);
   }
 
   /* 1010 ms timers.  will expire in the next epoch */
   for (i = 10; i < 20; i++) {
     grpc_timer_init(
         &exec_ctx, &timers[i],
-        gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)), cb,
-        (void *)(intptr_t)i, start);
+        gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)),
+        grpc_closure_create(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx),
+        start);
   }
 
   /* collect timers.  Only the first batch should be ready. */
@@ -125,16 +128,26 @@ void destruction_test(void) {
   grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
   memset(cb_called, 0, sizeof(cb_called));
 
-  grpc_timer_init(&exec_ctx, &timers[0], tfm(100), cb, (void *)(intptr_t)0,
-                  gpr_time_0(GPR_CLOCK_REALTIME));
-  grpc_timer_init(&exec_ctx, &timers[1], tfm(3), cb, (void *)(intptr_t)1,
-                  gpr_time_0(GPR_CLOCK_REALTIME));
-  grpc_timer_init(&exec_ctx, &timers[2], tfm(100), cb, (void *)(intptr_t)2,
-                  gpr_time_0(GPR_CLOCK_REALTIME));
-  grpc_timer_init(&exec_ctx, &timers[3], tfm(3), cb, (void *)(intptr_t)3,
-                  gpr_time_0(GPR_CLOCK_REALTIME));
-  grpc_timer_init(&exec_ctx, &timers[4], tfm(1), cb, (void *)(intptr_t)4,
-                  gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_init(
+      &exec_ctx, &timers[0], tfm(100),
+      grpc_closure_create(cb, (void *)(intptr_t)0, grpc_schedule_on_exec_ctx),
+      gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_init(
+      &exec_ctx, &timers[1], tfm(3),
+      grpc_closure_create(cb, (void *)(intptr_t)1, grpc_schedule_on_exec_ctx),
+      gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_init(
+      &exec_ctx, &timers[2], tfm(100),
+      grpc_closure_create(cb, (void *)(intptr_t)2, grpc_schedule_on_exec_ctx),
+      gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_init(
+      &exec_ctx, &timers[3], tfm(3),
+      grpc_closure_create(cb, (void *)(intptr_t)3, grpc_schedule_on_exec_ctx),
+      gpr_time_0(GPR_CLOCK_REALTIME));
+  grpc_timer_init(
+      &exec_ctx, &timers[4], tfm(1),
+      grpc_closure_create(cb, (void *)(intptr_t)4, grpc_schedule_on_exec_ctx),
+      gpr_time_0(GPR_CLOCK_REALTIME));
   GPR_ASSERT(1 == grpc_timer_check(&exec_ctx, tfm(2), NULL));
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(1 == cb_called[4][1]);
-- 
GitLab


From ced8702d1d184fe83bbdcdfc97868a9f94868986 Mon Sep 17 00:00:00 2001
From: Eric Gribkoff <ericgribkoff@google.com>
Date: Fri, 6 Jan 2017 09:16:29 -0800
Subject: [PATCH 238/344] Enable advanced Java interop tests.

Add response parameters to custom_metadata streaming request for Node and PHP
clients.

The Java server does not respond with separate initial and trailing
metadata when there is no response data - it is only emiting the
requested trailing metadata. Adding the response parameters to the test
(in accordance with the specification) avoids this, but I will open a
separate issue to investigate the Java behavior.
---
 src/node/interop/interop_client.js       |  3 +++
 src/php/tests/interop/interop_client.php | 11 +++++++++++
 tools/run_tests/run_interop_tests.py     |  4 ++--
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 46ddecfb1f..75cfb41342 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -312,6 +312,9 @@ function customMetadata(client, done) {
     }
   };
   var streaming_arg = {
+    response_parameters: [
+     {size: 314159}
+    ],
     payload: {
       body: zeroBuffer(271828)
     }
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index d201915d66..2acf5612c7 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -451,11 +451,22 @@ function customMetadata($stub)
 
     $streaming_request = new grpc\testing\StreamingOutputCallRequest();
     $streaming_request->setPayload($payload);
+    $response_parameters = new grpc\testing\ResponseParameters();
+    $response_parameters->setSize($response_len);
+    $streaming_request->getResponseParameters()[] = $response_parameters;
     $streaming_call->write($streaming_request);
     $streaming_call->writesDone();
+    $result = $streaming_call->read();
 
     hardAssertIfStatusOk($streaming_call->getStatus());
 
+    $streaming_initial_metadata = $streaming_call->getMetadata();
+    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $streaming_initial_metadata),
+               'Initial metadata does not contain expected key');
+    hardAssert(
+        $streaming_initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
+        'Incorrect initial metadata value');
+
     $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
     hardAssert(array_key_exists($ECHO_TRAILING_KEY,
                                 $streaming_trailing_metadata),
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index c14f18af81..981e38b813 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -179,10 +179,10 @@ class JavaLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def __str__(self):
     return 'java'
-- 
GitLab


From b408f9db313bc35f19bdaa274cd4be78f8e895c2 Mon Sep 17 00:00:00 2001
From: Eric Gribkoff <ericgribkoff@google.com>
Date: Fri, 6 Jan 2017 10:29:53 -0800
Subject: [PATCH 239/344] interop-test-descriptions.md: correct proto for
 custom_metadata's FullDuplexCall

---
 doc/interop-test-descriptions.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 96d1f2bd75..da3b976744 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -716,7 +716,9 @@ Procedure:
 
     ```
     {
-      response_size: 314159
+      response_parameters:{
+        size: 314159
+      }
       payload:{
         body: 271828 bytes of zeros
       }
-- 
GitLab


From e61b7d7b77f87442fc2fb63738b3e9a60a189887 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 6 Jan 2017 11:01:37 -0800
Subject: [PATCH 240/344] Start some performance notes

---
 doc/cpp/perf_notes.md | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 doc/cpp/perf_notes.md

diff --git a/doc/cpp/perf_notes.md b/doc/cpp/perf_notes.md
new file mode 100644
index 0000000000..805ead3638
--- /dev/null
+++ b/doc/cpp/perf_notes.md
@@ -0,0 +1,29 @@
+# C++ Performance Notes
+
+## Streaming write buffering
+
+Generally, each write operation (Write(), WritesDone()) implies a syscall.
+gRPC will try to batch together separate write operations from different
+threads, but currently cannot automatically infer batching in a single stream.
+
+If message k+1 in a stream does not rely on responses from message k, it's
+possible to enable write batching by passing a WriteOptions argument to Write
+with the buffer_hint set:
+
+```c++
+stream_writer->Write(message, WriteOptions().set_buffer_hint());
+```
+
+The write will be buffered until one of the following is true:
+- the per-stream buffer is filled (controllable with the channel argument
+  GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE) - this prevents infinite buffering leading
+  to OOM
+- a subsequent Write without buffer_hint set is posted
+- the call is finished for writing (WritesDone() called on the client,
+  or Finish() called on an async server stream, or the service handler returns
+  for a sync server stream)
+
+## Completion Queues and Threading in the Async API
+
+Right now, the best performance trade-off is having numcpu's threads and one
+completion queue per thread.
-- 
GitLab


From e519a03a1f0fc36849a5b80192ae2815902ba82b Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 6 Jan 2017 12:41:21 -0800
Subject: [PATCH 241/344] Small improvements to generated documentation

---
 doc/cpp/perf_notes.md                         |  4 +--
 include/grpc++/grpc++.h                       |  4 +++
 .../grpc++/impl/codegen/completion_queue.h    |  6 ++--
 templates/tools/doxygen/Doxyfile.include      | 22 +++++++++-----
 tools/doxygen/Doxyfile.c++                    | 30 ++++++++++++++++++-
 tools/doxygen/Doxyfile.c++.internal           | 30 ++++++++++++++++++-
 tools/doxygen/Doxyfile.core                   | 29 +++++++++++++++++-
 tools/doxygen/Doxyfile.core.internal          | 29 +++++++++++++++++-
 8 files changed, 139 insertions(+), 15 deletions(-)

diff --git a/doc/cpp/perf_notes.md b/doc/cpp/perf_notes.md
index 805ead3638..c87557558d 100644
--- a/doc/cpp/perf_notes.md
+++ b/doc/cpp/perf_notes.md
@@ -10,9 +10,9 @@ If message k+1 in a stream does not rely on responses from message k, it's
 possible to enable write batching by passing a WriteOptions argument to Write
 with the buffer_hint set:
 
-```c++
+~~~{.cpp}
 stream_writer->Write(message, WriteOptions().set_buffer_hint());
-```
+~~~
 
 The write will be buffered until one of the following is true:
 - the per-stream buffer is filled (controllable with the channel argument
diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h
index 36d65d6ee1..daecfea406 100644
--- a/include/grpc++/grpc++.h
+++ b/include/grpc++/grpc++.h
@@ -44,6 +44,10 @@
 /// peer, compression settings, authentication, etc.
 /// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
 ///
+/// Streaming calls are handled with the streaming classes in
+/// \ref sync_stream.h and
+/// \ref async_stream.h.
+///
 /// Refer to the
 /// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
 /// for code putting these pieces into play.
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 944f2c3919..03cecdc21c 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -94,8 +94,10 @@ class ServerContext;
 
 extern CoreCodegenInterface* g_core_codegen_interface;
 
-/// A thin wrapper around \a grpc_completion_queue (see / \a
-/// src/core/surface/completion_queue.h).
+/// A thin wrapper around \ref grpc_completion_queue (see \ref
+/// src/core/lib/surface/completion_queue.h).
+/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
+/// performance servers.
 class CompletionQueue : private GrpcLibraryCodegen {
  public:
   /// Default constructor. Implicitly creates a \a grpc_completion_queue
diff --git a/templates/tools/doxygen/Doxyfile.include b/templates/tools/doxygen/Doxyfile.include
index 8b0c528c1f..7fe8a29746 100644
--- a/templates/tools/doxygen/Doxyfile.include
+++ b/templates/tools/doxygen/Doxyfile.include
@@ -8,7 +8,9 @@
 <%def name="gen_doxyfile(libnames, packagename, collection, internal)">
 <%
   import itertools
+  import glob
   targets = []
+  docpackage = packagename.replace('+', 'p').lower()
   for libname in libnames:
     target = None
     for p in collection:
@@ -778,13 +780,19 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = ${' \\\n'.join(
-                               itertools.chain.from_iterable(
-			           target.public_headers +
-				   ([]
-				    if not internal
-				    else target.headers + target.src)
-			       for target in targets))}
+INPUT                  = ${
+    ' \\\n'.join(
+        itertools.chain(
+            itertools.chain.from_iterable(
+    			      target.public_headers +
+    				    ([]
+    				     if not internal
+    				     else target.headers + target.src)
+    			      for target in targets),
+            glob.glob('doc/*.md'),
+            glob.glob('doc/%s/*.md' % docpackage))
+    )
+}
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 0f3ebde666..2c16f6f24a 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -847,7 +847,35 @@ include/grpc/impl/codegen/slice.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_windows.h
+include/grpc/impl/codegen/sync_windows.h \
+doc/fail_fast.md \
+doc/compression.md \
+doc/environment_variables.md \
+doc/stress_test_framework.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/http-grpc-status-mapping.md \
+doc/wait-for-ready.md \
+doc/command_line_tool.md \
+doc/c-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
+doc/epoll-polling-engine.md \
+doc/naming.md \
+doc/binary-logging.md \
+doc/connectivity-semantics-and-api.md \
+doc/connection-backoff.md \
+doc/compression_cookbook.md \
+doc/PROTOCOL-HTTP2.md \
+doc/load-balancing.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/statuscodes.md \
+doc/g_stands_for.md \
+doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 73a4a090e1..e7fa25f1f1 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -893,7 +893,35 @@ src/cpp/util/slice_cc.cc \
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
-src/cpp/codegen/codegen_init.cc
+src/cpp/codegen/codegen_init.cc \
+doc/fail_fast.md \
+doc/compression.md \
+doc/environment_variables.md \
+doc/stress_test_framework.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/http-grpc-status-mapping.md \
+doc/wait-for-ready.md \
+doc/command_line_tool.md \
+doc/c-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
+doc/epoll-polling-engine.md \
+doc/naming.md \
+doc/binary-logging.md \
+doc/connectivity-semantics-and-api.md \
+doc/connection-backoff.md \
+doc/compression_cookbook.md \
+doc/PROTOCOL-HTTP2.md \
+doc/load-balancing.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/statuscodes.md \
+doc/g_stands_for.md \
+doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 6b6034a934..e7fc1dbc57 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -825,7 +825,34 @@ include/grpc/impl/codegen/slice.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_windows.h
+include/grpc/impl/codegen/sync_windows.h \
+doc/fail_fast.md \
+doc/compression.md \
+doc/environment_variables.md \
+doc/stress_test_framework.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/http-grpc-status-mapping.md \
+doc/wait-for-ready.md \
+doc/command_line_tool.md \
+doc/c-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
+doc/epoll-polling-engine.md \
+doc/naming.md \
+doc/binary-logging.md \
+doc/connectivity-semantics-and-api.md \
+doc/connection-backoff.md \
+doc/compression_cookbook.md \
+doc/PROTOCOL-HTTP2.md \
+doc/load-balancing.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/statuscodes.md \
+doc/g_stands_for.md \
+doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 3f83911a01..b13afdca99 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1276,7 +1276,34 @@ src/core/lib/support/tls_pthread.c \
 src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
-src/core/lib/support/wrap_memcpy.c
+src/core/lib/support/wrap_memcpy.c \
+doc/fail_fast.md \
+doc/compression.md \
+doc/environment_variables.md \
+doc/stress_test_framework.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/http-grpc-status-mapping.md \
+doc/wait-for-ready.md \
+doc/command_line_tool.md \
+doc/c-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
+doc/epoll-polling-engine.md \
+doc/naming.md \
+doc/binary-logging.md \
+doc/connectivity-semantics-and-api.md \
+doc/connection-backoff.md \
+doc/compression_cookbook.md \
+doc/PROTOCOL-HTTP2.md \
+doc/load-balancing.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/statuscodes.md \
+doc/g_stands_for.md \
+doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From 1f0f23cc5aa8f131b7ef3aae982cffb88d1f19fa Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 6 Jan 2017 13:07:19 -0800
Subject: [PATCH 242/344] Handshaker plugin mechanism.

---
 BUILD                                         |   4 +
 CMakeLists.txt                                |   8 ++
 Makefile                                      |  10 ++
 binding.gyp                                   |   2 +
 build.yaml                                    |   4 +
 config.m4                                     |   2 +
 gRPC-Core.podspec                             |   6 +
 grpc.gemspec                                  |   4 +
 package.xml                                   |   4 +
 .../client_channel/client_channel_plugin.c    |   2 +
 .../client_channel/http_connect_handshaker.c  |  30 +++++
 .../client_channel/http_connect_handshaker.h  |   5 +-
 .../chttp2/client/chttp2_connector.c          |  20 +---
 .../chttp2/client/chttp2_connector.h          |  12 +-
 .../chttp2/client/insecure/channel_create.c   |  12 +-
 .../client/secure/secure_channel_create.c     |  60 +++-------
 .../transport/chttp2/server/chttp2_server.c   |  36 ++----
 .../transport/chttp2/server/chttp2_server.h   |  39 +-----
 .../chttp2/server/insecure/server_chttp2.c    |   3 +-
 .../server/secure/server_secure_chttp2.c      |  49 ++------
 src/core/lib/channel/handshaker_factory.c     |  54 +++++++++
 src/core/lib/channel/handshaker_factory.h     |  66 ++++++++++
 src/core/lib/channel/handshaker_registry.c    | 113 ++++++++++++++++++
 src/core/lib/channel/handshaker_registry.h    |  63 ++++++++++
 .../security/transport/security_handshaker.c  |  47 ++++++++
 .../security/transport/security_handshaker.h  |   3 +
 src/core/lib/surface/init.c                   |   4 +
 src/core/lib/surface/init.h                   |   1 +
 src/core/lib/surface/init_secure.c            |   3 +
 src/core/lib/surface/init_unsecure.c          |   2 +
 src/python/grpcio/grpc_core_dependencies.py   |   2 +
 tools/doxygen/Doxyfile.core.internal          |   4 +
 .../generated/sources_and_headers.json        |   6 +
 vsprojects/vcxproj/grpc/grpc.vcxproj          |   6 +
 vsprojects/vcxproj/grpc/grpc.vcxproj.filters  |  12 ++
 .../grpc_test_util/grpc_test_util.vcxproj     |   6 +
 .../grpc_test_util.vcxproj.filters            |  12 ++
 .../grpc_unsecure/grpc_unsecure.vcxproj       |   6 +
 .../grpc_unsecure.vcxproj.filters             |  12 ++
 39 files changed, 549 insertions(+), 185 deletions(-)
 create mode 100644 src/core/lib/channel/handshaker_factory.c
 create mode 100644 src/core/lib/channel/handshaker_factory.h
 create mode 100644 src/core/lib/channel/handshaker_registry.c
 create mode 100644 src/core/lib/channel/handshaker_registry.h

diff --git a/BUILD b/BUILD
index 74de1fecd8..3122dc0a32 100644
--- a/BUILD
+++ b/BUILD
@@ -421,6 +421,8 @@ grpc_cc_library(
         "src/core/lib/channel/connected_channel.c",
         "src/core/lib/channel/deadline_filter.c",
         "src/core/lib/channel/handshaker.c",
+        "src/core/lib/channel/handshaker_factory.c",
+        "src/core/lib/channel/handshaker_registry.c",
         "src/core/lib/channel/http_client_filter.c",
         "src/core/lib/channel/http_server_filter.c",
         "src/core/lib/channel/message_size_filter.c",
@@ -536,6 +538,8 @@ grpc_cc_library(
         "src/core/lib/channel/context.h",
         "src/core/lib/channel/deadline_filter.h",
         "src/core/lib/channel/handshaker.h",
+        "src/core/lib/channel/handshaker_factory.h",
+        "src/core/lib/channel/handshaker_registry.h",
         "src/core/lib/channel/http_client_filter.h",
         "src/core/lib/channel/http_server_filter.h",
         "src/core/lib/channel/message_size_filter.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index acced2c759..fd271d472d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -292,6 +292,8 @@ add_library(grpc
   src/core/lib/channel/connected_channel.c
   src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
   src/core/lib/channel/message_size_filter.c
@@ -574,6 +576,8 @@ add_library(grpc_cronet
   src/core/lib/channel/connected_channel.c
   src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
   src/core/lib/channel/message_size_filter.c
@@ -827,6 +831,8 @@ add_library(grpc_unsecure
   src/core/lib/channel/connected_channel.c
   src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
   src/core/lib/channel/message_size_filter.c
@@ -1296,6 +1302,8 @@ add_library(grpc++_cronet
   src/core/lib/channel/connected_channel.c
   src/core/lib/channel/deadline_filter.c
   src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
   src/core/lib/channel/http_client_filter.c
   src/core/lib/channel/http_server_filter.c
   src/core/lib/channel/message_size_filter.c
diff --git a/Makefile b/Makefile
index 771d9881c9..a26842e71b 100644
--- a/Makefile
+++ b/Makefile
@@ -2631,6 +2631,8 @@ LIBGRPC_SRC = \
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
@@ -2931,6 +2933,8 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
@@ -3221,6 +3225,8 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
@@ -3439,6 +3445,8 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
@@ -4020,6 +4028,8 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
diff --git a/binding.gyp b/binding.gyp
index 516cbdce5d..3a80402c06 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -572,6 +572,8 @@
         'src/core/lib/channel/connected_channel.c',
         'src/core/lib/channel/deadline_filter.c',
         'src/core/lib/channel/handshaker.c',
+        'src/core/lib/channel/handshaker_factory.c',
+        'src/core/lib/channel/handshaker_registry.c',
         'src/core/lib/channel/http_client_filter.c',
         'src/core/lib/channel/http_server_filter.c',
         'src/core/lib/channel/message_size_filter.c',
diff --git a/build.yaml b/build.yaml
index f0d14a62ac..55aca52f68 100644
--- a/build.yaml
+++ b/build.yaml
@@ -171,6 +171,8 @@ filegroups:
   - src/core/lib/channel/context.h
   - src/core/lib/channel/deadline_filter.h
   - src/core/lib/channel/handshaker.h
+  - src/core/lib/channel/handshaker_factory.h
+  - src/core/lib/channel/handshaker_registry.h
   - src/core/lib/channel/http_client_filter.h
   - src/core/lib/channel/http_server_filter.h
   - src/core/lib/channel/message_size_filter.h
@@ -269,6 +271,8 @@ filegroups:
   - src/core/lib/channel/connected_channel.c
   - src/core/lib/channel/deadline_filter.c
   - src/core/lib/channel/handshaker.c
+  - src/core/lib/channel/handshaker_factory.c
+  - src/core/lib/channel/handshaker_registry.c
   - src/core/lib/channel/http_client_filter.c
   - src/core/lib/channel/http_server_filter.c
   - src/core/lib/channel/message_size_filter.c
diff --git a/config.m4 b/config.m4
index 4b86e25581..12b10578e8 100644
--- a/config.m4
+++ b/config.m4
@@ -88,6 +88,8 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/deadline_filter.c \
     src/core/lib/channel/handshaker.c \
+    src/core/lib/channel/handshaker_factory.c \
+    src/core/lib/channel/handshaker_registry.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
     src/core/lib/channel/message_size_filter.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 9d878d5474..e56eedd3a6 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -256,6 +256,8 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/context.h',
                       'src/core/lib/channel/deadline_filter.h',
                       'src/core/lib/channel/handshaker.h',
+                      'src/core/lib/channel/handshaker_factory.h',
+                      'src/core/lib/channel/handshaker_registry.h',
                       'src/core/lib/channel/http_client_filter.h',
                       'src/core/lib/channel/http_server_filter.h',
                       'src/core/lib/channel/message_size_filter.h',
@@ -436,6 +438,8 @@ Pod::Spec.new do |s|
                       'src/core/lib/channel/connected_channel.c',
                       'src/core/lib/channel/deadline_filter.c',
                       'src/core/lib/channel/handshaker.c',
+                      'src/core/lib/channel/handshaker_factory.c',
+                      'src/core/lib/channel/handshaker_registry.c',
                       'src/core/lib/channel/http_client_filter.c',
                       'src/core/lib/channel/http_server_filter.c',
                       'src/core/lib/channel/message_size_filter.c',
@@ -664,6 +668,8 @@ Pod::Spec.new do |s|
                               'src/core/lib/channel/context.h',
                               'src/core/lib/channel/deadline_filter.h',
                               'src/core/lib/channel/handshaker.h',
+                              'src/core/lib/channel/handshaker_factory.h',
+                              'src/core/lib/channel/handshaker_registry.h',
                               'src/core/lib/channel/http_client_filter.h',
                               'src/core/lib/channel/http_server_filter.h',
                               'src/core/lib/channel/message_size_filter.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index a6b0481405..d1dcb1de02 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -173,6 +173,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/context.h )
   s.files += %w( src/core/lib/channel/deadline_filter.h )
   s.files += %w( src/core/lib/channel/handshaker.h )
+  s.files += %w( src/core/lib/channel/handshaker_factory.h )
+  s.files += %w( src/core/lib/channel/handshaker_registry.h )
   s.files += %w( src/core/lib/channel/http_client_filter.h )
   s.files += %w( src/core/lib/channel/http_server_filter.h )
   s.files += %w( src/core/lib/channel/message_size_filter.h )
@@ -353,6 +355,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/channel/connected_channel.c )
   s.files += %w( src/core/lib/channel/deadline_filter.c )
   s.files += %w( src/core/lib/channel/handshaker.c )
+  s.files += %w( src/core/lib/channel/handshaker_factory.c )
+  s.files += %w( src/core/lib/channel/handshaker_registry.c )
   s.files += %w( src/core/lib/channel/http_client_filter.c )
   s.files += %w( src/core/lib/channel/http_server_filter.c )
   s.files += %w( src/core/lib/channel/message_size_filter.c )
diff --git a/package.xml b/package.xml
index 8798f5119a..4df1525827 100644
--- a/package.xml
+++ b/package.xml
@@ -181,6 +181,8 @@
     <file baseinstalldir="/" name="src/core/lib/channel/context.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/deadline_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.h" role="src" />
@@ -361,6 +363,8 @@
     <file baseinstalldir="/" name="src/core/lib/channel/connected_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/deadline_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/message_size_filter.c" role="src" />
diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c
index 988b7a1d5c..d50bba60f6 100644
--- a/src/core/ext/client_channel/client_channel_plugin.c
+++ b/src/core/ext/client_channel/client_channel_plugin.c
@@ -38,6 +38,7 @@
 #include <grpc/support/alloc.h>
 
 #include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/client_channel/http_connect_handshaker.h"
 #include "src/core/ext/client_channel/lb_policy_registry.h"
 #include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/client_channel/subchannel_index.h"
@@ -84,6 +85,7 @@ void grpc_client_channel_init(void) {
                                    set_default_host_if_unset, NULL);
   grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter,
                                    (void *)&grpc_client_channel_filter);
+  grpc_http_connect_register_handshaker_factory();
 }
 
 void grpc_client_channel_shutdown(void) {
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 27b117af84..ace804c47f 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -44,6 +44,7 @@
 #include "src/core/ext/client_channel/resolver_registry.h"
 #include "src/core/ext/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/http/format_request.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/slice/slice_internal.h"
@@ -347,3 +348,32 @@ done:
   grpc_uri_destroy(uri);
   return proxy_name;
 }
+
+//
+// handshaker factory
+//
+
+static void handshaker_factory_add_handshakers(
+    grpc_exec_ctx* exec_ctx, grpc_handshaker_factory* factory,
+    const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) {
+  char* proxy_name = grpc_get_http_proxy_server();
+  if (proxy_name != NULL) {
+    grpc_handshake_manager_add(handshake_mgr,
+                               grpc_http_connect_handshaker_create(proxy_name));
+    gpr_free(proxy_name);
+  }
+}
+
+static void handshaker_factory_destroy(grpc_exec_ctx* exec_ctx,
+                                       grpc_handshaker_factory* factory) {}
+
+static const grpc_handshaker_factory_vtable handshaker_factory_vtable = {
+    handshaker_factory_add_handshakers, handshaker_factory_destroy};
+
+static grpc_handshaker_factory handshaker_factory = {
+    &handshaker_factory_vtable};
+
+void grpc_http_connect_register_handshaker_factory() {
+  grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_CLIENT,
+                                   &handshaker_factory);
+}
diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/client_channel/http_connect_handshaker.h
index ea293852e6..56485f1373 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.h
+++ b/src/core/ext/client_channel/http_connect_handshaker.h
@@ -36,11 +36,14 @@
 
 #include "src/core/lib/channel/handshaker.h"
 
-/// Does NOT take ownership of \a proxy_server.
+/// Creates a new HTTP CONNECT handshaker.
 grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server);
 
 /// Returns the name of the proxy to use, or NULL if no proxy is configured.
 /// Caller takes ownership of result.
 char* grpc_get_http_proxy_server();
 
+/// Registers handshaker factory.
+void grpc_http_connect_register_handshaker_factory();
+
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H */
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 2385f91dbd..2c5dfaea60 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -46,6 +46,7 @@
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/slice/slice_internal.h"
 
@@ -58,9 +59,6 @@ typedef struct {
   bool shutdown;
   bool connecting;
 
-  grpc_chttp2_add_handshakers_func add_handshakers;
-  void *add_handshakers_user_data;
-
   grpc_closure *notify;
   grpc_connect_in_args args;
   grpc_connect_out_args *result;
@@ -151,16 +149,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
 static void start_handshake_locked(grpc_exec_ctx *exec_ctx,
                                    chttp2_connector *c) {
   c->handshake_mgr = grpc_handshake_manager_create();
-  char *proxy_name = grpc_get_http_proxy_server();
-  if (proxy_name != NULL) {
-    grpc_handshake_manager_add(c->handshake_mgr,
-                               grpc_http_connect_handshaker_create(proxy_name));
-    gpr_free(proxy_name);
-  }
-  if (c->add_handshakers != NULL) {
-    c->add_handshakers(exec_ctx, c->add_handshakers_user_data,
+  grpc_handshakers_add(exec_ctx, HANDSHAKER_CLIENT, c->args.channel_args,
                        c->handshake_mgr);
-  }
   grpc_handshake_manager_do_handshake(
       exec_ctx, c->handshake_mgr, c->endpoint, c->args.channel_args,
       c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
@@ -250,15 +240,11 @@ static const grpc_connector_vtable chttp2_connector_vtable = {
     chttp2_connector_ref, chttp2_connector_unref, chttp2_connector_shutdown,
     chttp2_connector_connect};
 
-grpc_connector *grpc_chttp2_connector_create(
-    grpc_exec_ctx *exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers,
-    void *add_handshakers_user_data) {
+grpc_connector *grpc_chttp2_connector_create() {
   chttp2_connector *c = gpr_malloc(sizeof(*c));
   memset(c, 0, sizeof(*c));
   c->base.vtable = &chttp2_connector_vtable;
   gpr_mu_init(&c->mu);
   gpr_ref_init(&c->refs, 1);
-  c->add_handshakers = add_handshakers;
-  c->add_handshakers_user_data = add_handshakers_user_data;
   return &c->base;
 }
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h
index 58eba22417..f5d1025432 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.h
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h
@@ -35,17 +35,7 @@
 #define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
 
 #include "src/core/ext/client_channel/connector.h"
-#include "src/core/lib/channel/handshaker.h"
-#include "src/core/lib/iomgr/exec_ctx.h"
 
-typedef void (*grpc_chttp2_add_handshakers_func)(
-    grpc_exec_ctx* exec_ctx, void* user_data,
-    grpc_handshake_manager* handshake_mgr);
-
-/// If \a add_handshakers is non-NULL, it will be called with
-/// \a add_handshakers_user_data to add handshakers.
-grpc_connector* grpc_chttp2_connector_create(
-    grpc_exec_ctx* exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers,
-    void* add_handshakers_user_data);
+grpc_connector* grpc_chttp2_connector_create();
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 1d3592ef06..c9f4021216 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -53,8 +53,7 @@ static void client_channel_factory_unref(
 static grpc_subchannel *client_channel_factory_create_subchannel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const grpc_subchannel_args *args) {
-  grpc_connector *connector = grpc_chttp2_connector_create(
-      exec_ctx, NULL /* add_handshakers */, NULL /* user_data */);
+  grpc_connector *connector = grpc_chttp2_connector_create();
   grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
   grpc_connector_unref(exec_ctx, connector);
   return s;
@@ -96,17 +95,16 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
       "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
       (target, args, reserved));
   GPR_ASSERT(reserved == NULL);
-  grpc_client_channel_factory *factory =
-      (grpc_client_channel_factory *)&client_channel_factory;
   // Add channel arg containing the client channel factory.
-  grpc_arg arg = grpc_client_channel_factory_create_channel_arg(factory);
+  grpc_arg arg =
+      grpc_client_channel_factory_create_channel_arg(&client_channel_factory);
   grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
   // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
-      &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
+      &exec_ctx, &client_channel_factory, target,
+      GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
   // Clean up.
   grpc_channel_args_destroy(&exec_ctx, new_args);
-  grpc_client_channel_factory_unref(&exec_ctx, factory);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel != NULL ? channel : grpc_lame_client_channel_create(
                                          target, GRPC_STATUS_INTERNAL,
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 54663ef6a4..f979d9bad5 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -46,40 +46,16 @@
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/channel.h"
 
-typedef struct {
-  grpc_client_channel_factory base;
-  gpr_refcount refs;
-  grpc_channel_security_connector *security_connector;
-} client_channel_factory;
-
 static void client_channel_factory_ref(
-    grpc_client_channel_factory *cc_factory) {
-  client_channel_factory *f = (client_channel_factory *)cc_factory;
-  gpr_ref(&f->refs);
-}
+    grpc_client_channel_factory *cc_factory) {}
 
 static void client_channel_factory_unref(
-    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
-  client_channel_factory *f = (client_channel_factory *)cc_factory;
-  if (gpr_unref(&f->refs)) {
-    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &f->security_connector->base,
-                                  "client_channel_factory");
-    gpr_free(f);
-  }
-}
-
-static void add_handshakers(grpc_exec_ctx *exec_ctx, void *security_connector,
-                            grpc_handshake_manager *handshake_mgr) {
-  grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector,
-                                                  handshake_mgr);
-}
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {}
 
 static grpc_subchannel *client_channel_factory_create_subchannel(
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     const grpc_subchannel_args *args) {
-  client_channel_factory *f = (client_channel_factory *)cc_factory;
-  grpc_connector *connector = grpc_chttp2_connector_create(
-      exec_ctx, add_handshakers, f->security_connector);
+  grpc_connector *connector = grpc_chttp2_connector_create();
   grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
   grpc_connector_unref(exec_ctx, connector);
   return s;
@@ -106,6 +82,9 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
      client_channel_factory_create_subchannel,
      client_channel_factory_create_channel};
 
+static grpc_client_channel_factory client_channel_factory = {
+    &client_channel_factory_vtable};
+
 /* Create a secure client channel:
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
@@ -138,33 +117,26 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
   }
-  // Create client channel factory.
-  client_channel_factory *f = gpr_malloc(sizeof(*f));
-  memset(f, 0, sizeof(*f));
-  f->base.vtable = &client_channel_factory_vtable;
-  gpr_ref_init(&f->refs, 1);
-  GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
-                              "grpc_secure_channel_create");
-  f->security_connector = security_connector;
   // Add channel args containing the client channel factory and security
   // connector.
-  grpc_arg new_args[2];
-  new_args[0] = grpc_client_channel_factory_create_channel_arg(&f->base);
-  new_args[1] = grpc_security_connector_to_arg(&security_connector->base);
-  grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
+  grpc_arg args_to_add[2];
+  args_to_add[0] =
+      grpc_client_channel_factory_create_channel_arg(&client_channel_factory);
+  args_to_add[1] = grpc_security_connector_to_arg(&security_connector->base);
+  grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
       new_args_from_connector != NULL ? new_args_from_connector : args,
-      new_args, GPR_ARRAY_SIZE(new_args));
+      args_to_add, GPR_ARRAY_SIZE(args_to_add));
   if (new_args_from_connector != NULL) {
     grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
   }
   // Create channel.
   grpc_channel *channel = client_channel_factory_create_channel(
-      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
+      &exec_ctx, &client_channel_factory, target,
+      GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
   // Clean up.
-  GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &f->security_connector->base,
+  GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &security_connector->base,
                                 "secure_client_channel_factory_create_channel");
-  grpc_channel_args_destroy(&exec_ctx, args_copy);
-  grpc_client_channel_factory_unref(&exec_ctx, &f->base);
+  grpc_channel_args_destroy(&exec_ctx, new_args);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel; /* may be NULL */
 }
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index 86f5a198c2..574d1a7710 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -46,6 +46,7 @@
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/resolve_address.h"
@@ -54,24 +55,6 @@
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/server.h"
 
-void grpc_chttp2_server_handshaker_factory_add_handshakers(
-    grpc_exec_ctx *exec_ctx,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory,
-    grpc_handshake_manager *handshake_mgr) {
-  if (handshaker_factory != NULL) {
-    handshaker_factory->vtable->add_handshakers(exec_ctx, handshaker_factory,
-                                                handshake_mgr);
-  }
-}
-
-void grpc_chttp2_server_handshaker_factory_destroy(
-    grpc_exec_ctx *exec_ctx,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory) {
-  if (handshaker_factory != NULL) {
-    handshaker_factory->vtable->destroy(exec_ctx, handshaker_factory);
-  }
-}
-
 typedef struct pending_handshake_manager_node {
   grpc_handshake_manager *handshake_mgr;
   struct pending_handshake_manager_node *next;
@@ -81,7 +64,6 @@ typedef struct {
   grpc_server *server;
   grpc_tcp_server *tcp_server;
   grpc_channel_args *args;
-  grpc_chttp2_server_handshaker_factory *handshaker_factory;
   gpr_mu mu;
   bool shutdown;
   grpc_closure tcp_server_shutdown_complete;
@@ -198,8 +180,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
   connection_state->accepting_pollset = accepting_pollset;
   connection_state->acceptor = acceptor;
   connection_state->handshake_mgr = handshake_mgr;
-  grpc_chttp2_server_handshaker_factory_add_handshakers(
-      exec_ctx, state->handshaker_factory, connection_state->handshake_mgr);
+  grpc_handshakers_add(exec_ctx, HANDSHAKER_SERVER, state->args,
+                       connection_state->handshake_mgr);
   // TODO(roth): We should really get this timeout value from channel
   // args instead of hard-coding it.
   const gpr_timespec deadline = gpr_time_add(
@@ -233,8 +215,6 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *arg,
   // Flush queued work before destroying handshaker factory, since that
   // may do a synchronous unref.
   grpc_exec_ctx_flush(exec_ctx);
-  grpc_chttp2_server_handshaker_factory_destroy(exec_ctx,
-                                                state->handshaker_factory);
   if (destroy_done != NULL) {
     destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
     grpc_exec_ctx_flush(exec_ctx);
@@ -259,10 +239,10 @@ static void server_destroy_listener(grpc_exec_ctx *exec_ctx,
   grpc_tcp_server_unref(exec_ctx, tcp_server);
 }
 
-grpc_error *grpc_chttp2_server_add_port(
-    grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr,
-    grpc_channel_args *args,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory, int *port_num) {
+grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
+                                        grpc_server *server, const char *addr,
+                                        grpc_channel_args *args,
+                                        int *port_num) {
   grpc_resolved_addresses *resolved = NULL;
   grpc_tcp_server *tcp_server = NULL;
   size_t i;
@@ -293,7 +273,6 @@ grpc_error *grpc_chttp2_server_add_port(
   state->server = server;
   state->tcp_server = tcp_server;
   state->args = args;
-  state->handshaker_factory = handshaker_factory;
   state->shutdown = true;
   gpr_mu_init(&state->mu);
 
@@ -348,7 +327,6 @@ error:
     grpc_tcp_server_unref(exec_ctx, tcp_server);
   } else {
     grpc_channel_args_destroy(exec_ctx, args);
-    grpc_chttp2_server_handshaker_factory_destroy(exec_ctx, handshaker_factory);
     gpr_free(state);
   }
   *port_num = 0;
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h
index aa364b565d..2581ebaae9 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.h
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.h
@@ -36,43 +36,12 @@
 
 #include <grpc/impl/codegen/grpc_types.h>
 
-#include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 
-/// A server handshaker factory is used to create handshakers for server
-/// connections.
-typedef struct grpc_chttp2_server_handshaker_factory
-    grpc_chttp2_server_handshaker_factory;
-
-typedef struct {
-  void (*add_handshakers)(
-      grpc_exec_ctx *exec_ctx,
-      grpc_chttp2_server_handshaker_factory *handshaker_factory,
-      grpc_handshake_manager *handshake_mgr);
-  void (*destroy)(grpc_exec_ctx *exec_ctx,
-                  grpc_chttp2_server_handshaker_factory *handshaker_factory);
-} grpc_chttp2_server_handshaker_factory_vtable;
-
-struct grpc_chttp2_server_handshaker_factory {
-  const grpc_chttp2_server_handshaker_factory_vtable *vtable;
-};
-
-void grpc_chttp2_server_handshaker_factory_add_handshakers(
-    grpc_exec_ctx *exec_ctx,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory,
-    grpc_handshake_manager *handshake_mgr);
-
-void grpc_chttp2_server_handshaker_factory_destroy(
-    grpc_exec_ctx *exec_ctx,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory);
-
 /// Adds a port to \a server.  Sets \a port_num to the port number.
-/// If \a handshaker_factory is not NULL, it will be used to create
-/// handshakers for the port.
-/// Takes ownership of \a args and \a handshaker_factory.
-grpc_error *grpc_chttp2_server_add_port(
-    grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr,
-    grpc_channel_args *args,
-    grpc_chttp2_server_handshaker_factory *handshaker_factory, int *port_num);
+/// Takes ownership of \a args.
+grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
+                                        grpc_server *server, const char *addr,
+                                        grpc_channel_args *args, int *port_num);
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H */
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
index 7e286d4e46..bf5026bea6 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -47,8 +47,7 @@ int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
                  (server, addr));
   grpc_error *err = grpc_chttp2_server_add_port(
       &exec_ctx, server, addr,
-      grpc_channel_args_copy(grpc_server_get_channel_args(server)),
-      NULL /* handshaker_factory */, &port_num);
+      grpc_channel_args_copy(grpc_server_get_channel_args(server)), &port_num);
   if (err != GRPC_ERROR_NONE) {
     const char *msg = grpc_error_string(err);
     gpr_log(GPR_ERROR, "%s", msg);
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index b5e4996b16..395c79a71d 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -49,34 +49,6 @@
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/server.h"
 
-typedef struct {
-  grpc_chttp2_server_handshaker_factory base;
-  grpc_server_security_connector *security_connector;
-} server_security_handshaker_factory;
-
-static void server_security_handshaker_factory_add_handshakers(
-    grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf,
-    grpc_handshake_manager *handshake_mgr) {
-  server_security_handshaker_factory *handshaker_factory =
-      (server_security_handshaker_factory *)hf;
-  grpc_server_security_connector_add_handshakers(
-      exec_ctx, handshaker_factory->security_connector, handshake_mgr);
-}
-
-static void server_security_handshaker_factory_destroy(
-    grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf) {
-  server_security_handshaker_factory *handshaker_factory =
-      (server_security_handshaker_factory *)hf;
-  GRPC_SECURITY_CONNECTOR_UNREF(
-      exec_ctx, &handshaker_factory->security_connector->base, "server");
-  gpr_free(hf);
-}
-
-static const grpc_chttp2_server_handshaker_factory_vtable
-    server_security_handshaker_factory_vtable = {
-        server_security_handshaker_factory_add_handshakers,
-        server_security_handshaker_factory_destroy};
-
 int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
                                       grpc_server_credentials *creds) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -105,20 +77,19 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
     gpr_free(msg);
     goto done;
   }
-  // Create handshaker factory.
-  server_security_handshaker_factory *handshaker_factory =
-      gpr_malloc(sizeof(*handshaker_factory));
-  memset(handshaker_factory, 0, sizeof(*handshaker_factory));
-  handshaker_factory->base.vtable = &server_security_handshaker_factory_vtable;
-  handshaker_factory->security_connector = sc;
   // Create channel args.
-  grpc_arg channel_arg = grpc_server_credentials_to_arg(creds);
-  grpc_channel_args *args = grpc_channel_args_copy_and_add(
-      grpc_server_get_channel_args(server), &channel_arg, 1);
+  grpc_arg args_to_add[2];
+  args_to_add[0] = grpc_server_credentials_to_arg(creds);
+  args_to_add[1] = grpc_security_connector_to_arg(&sc->base);
+  grpc_channel_args *args =
+      grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server),
+                                     args_to_add, GPR_ARRAY_SIZE(args_to_add));
   // Add server port.
-  err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args,
-                                    &handshaker_factory->base, &port_num);
+  err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args, &port_num);
 done:
+  if (sc != NULL) {
+    GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server");
+  }
   grpc_exec_ctx_finish(&exec_ctx);
   if (err != GRPC_ERROR_NONE) {
     const char *msg = grpc_error_string(err);
diff --git a/src/core/lib/channel/handshaker_factory.c b/src/core/lib/channel/handshaker_factory.c
new file mode 100644
index 0000000000..3c30a4e1d2
--- /dev/null
+++ b/src/core/lib/channel/handshaker_factory.c
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#include "src/core/lib/channel/handshaker_factory.h"
+
+#include <grpc/support/log.h>
+
+void grpc_handshaker_factory_add_handshakers(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory,
+    const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) {
+  if (handshaker_factory != NULL) {
+    GPR_ASSERT(handshaker_factory->vtable != NULL);
+    handshaker_factory->vtable->add_handshakers(exec_ctx, handshaker_factory,
+                                                args, handshake_mgr);
+  }
+}
+
+void grpc_handshaker_factory_destroy(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory) {
+  if (handshaker_factory != NULL) {
+    GPR_ASSERT(handshaker_factory->vtable != NULL);
+    handshaker_factory->vtable->destroy(exec_ctx, handshaker_factory);
+  }
+}
diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h
new file mode 100644
index 0000000000..1984546104
--- /dev/null
+++ b/src/core/lib/channel/handshaker_factory.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H
+#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+// A handshaker factory is used to create handshakers.
+
+typedef struct grpc_handshaker_factory grpc_handshaker_factory;
+
+typedef struct {
+  void (*add_handshakers)(grpc_exec_ctx *exec_ctx,
+                          grpc_handshaker_factory *handshaker_factory,
+                          const grpc_channel_args *args,
+                          grpc_handshake_manager *handshake_mgr);
+  void (*destroy)(grpc_exec_ctx *exec_ctx,
+                  grpc_handshaker_factory *handshaker_factory);
+} grpc_handshaker_factory_vtable;
+
+struct grpc_handshaker_factory {
+  const grpc_handshaker_factory_vtable *vtable;
+};
+
+void grpc_handshaker_factory_add_handshakers(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory,
+    const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr);
+
+void grpc_handshaker_factory_destroy(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory);
+
+#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H */
diff --git a/src/core/lib/channel/handshaker_registry.c b/src/core/lib/channel/handshaker_registry.c
new file mode 100644
index 0000000000..2e5f04064c
--- /dev/null
+++ b/src/core/lib/channel/handshaker_registry.c
@@ -0,0 +1,113 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#include "src/core/lib/channel/handshaker_registry.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
+//
+// grpc_handshaker_factory_list
+//
+
+typedef struct {
+  grpc_handshaker_factory** list;
+  size_t num_factories;
+} grpc_handshaker_factory_list;
+
+static void grpc_handshaker_factory_list_register(
+    grpc_handshaker_factory_list* list, bool at_start,
+    grpc_handshaker_factory* factory) {
+  list->list = gpr_realloc(
+      list->list, (list->num_factories + 1) * sizeof(grpc_handshaker_factory*));
+  if (at_start) {
+    memmove(list->list + 1, list->list,
+            sizeof(grpc_handshaker_factory*) * list->num_factories);
+    list->list[0] = factory;
+  } else {
+    list->list[list->num_factories] = factory;
+  }
+  ++list->num_factories;
+}
+
+static void grpc_handshaker_factory_list_add_handshakers(
+    grpc_exec_ctx* exec_ctx, grpc_handshaker_factory_list* list,
+    const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) {
+  for (size_t i = 0; i < list->num_factories; ++i) {
+    grpc_handshaker_factory_add_handshakers(exec_ctx, list->list[i], args,
+                                            handshake_mgr);
+  }
+}
+
+static void grpc_handshaker_factory_list_destroy(
+    grpc_exec_ctx* exec_ctx, grpc_handshaker_factory_list* list) {
+  for (size_t i = 0; i < list->num_factories; ++i) {
+    grpc_handshaker_factory_destroy(exec_ctx, list->list[i]);
+  }
+  gpr_free(list->list);
+}
+
+//
+// plugin
+//
+
+static grpc_handshaker_factory_list
+    g_handshaker_factory_lists[NUM_HANDSHAKER_TYPES];
+
+void grpc_handshaker_factory_registry_init() {
+  memset(g_handshaker_factory_lists, 0, sizeof(g_handshaker_factory_lists));
+}
+
+void grpc_handshaker_factory_registry_shutdown(grpc_exec_ctx* exec_ctx) {
+  for (size_t i = 0; i < NUM_HANDSHAKER_TYPES; ++i) {
+    grpc_handshaker_factory_list_destroy(exec_ctx,
+                                         &g_handshaker_factory_lists[i]);
+  }
+}
+
+void grpc_handshaker_factory_register(bool at_start,
+                                      grpc_handshaker_type handshaker_type,
+                                      grpc_handshaker_factory* factory) {
+  grpc_handshaker_factory_list_register(
+      &g_handshaker_factory_lists[handshaker_type], at_start, factory);
+}
+
+void grpc_handshakers_add(grpc_exec_ctx* exec_ctx,
+                          grpc_handshaker_type handshaker_type,
+                          const grpc_channel_args* args,
+                          grpc_handshake_manager* handshake_mgr) {
+  grpc_handshaker_factory_list_add_handshakers(
+      exec_ctx, &g_handshaker_factory_lists[handshaker_type], args,
+      handshake_mgr);
+}
diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h
new file mode 100644
index 0000000000..53c1b173af
--- /dev/null
+++ b/src/core/lib/channel/handshaker_registry.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H
+#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/lib/channel/handshaker_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+typedef enum {
+  HANDSHAKER_CLIENT = 0,
+  HANDSHAKER_SERVER,
+  NUM_HANDSHAKER_TYPES,  // Must be last.
+} grpc_handshaker_type;
+
+void grpc_handshaker_factory_registry_init();
+void grpc_handshaker_factory_registry_shutdown(grpc_exec_ctx* exec_ctx);
+
+/// Registers a new handshaker factory.  Takes ownership.
+/// If \a at_start is true, the new handshaker will be at the beginning of
+/// the list.  Otherwise, it will be added to the end.
+void grpc_handshaker_factory_register(bool at_start,
+                                      grpc_handshaker_type handshaker_type,
+                                      grpc_handshaker_factory* factory);
+
+void grpc_handshakers_add(grpc_exec_ctx* exec_ctx,
+                          grpc_handshaker_type handshaker_type,
+                          const grpc_channel_args* args,
+                          grpc_handshake_manager* handshake_mgr);
+
+#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index e886cc59a0..5e75856c7a 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -42,6 +42,7 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
@@ -437,6 +438,45 @@ static grpc_handshaker *fail_handshaker_create() {
   return h;
 }
 
+//
+// handshaker factories
+//
+
+static void client_handshaker_factory_add_handshakers(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory,
+    const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) {
+  grpc_channel_security_connector *security_connector =
+      (grpc_channel_security_connector *)grpc_find_security_connector_in_args(
+          args);
+  grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector,
+                                                  handshake_mgr);
+}
+
+static void server_handshaker_factory_add_handshakers(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *hf,
+    const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) {
+  grpc_server_security_connector *security_connector =
+      (grpc_server_security_connector *)grpc_find_security_connector_in_args(
+          args);
+  grpc_server_security_connector_add_handshakers(exec_ctx, security_connector,
+                                                 handshake_mgr);
+}
+
+static void handshaker_factory_destroy(
+    grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory) {}
+
+static const grpc_handshaker_factory_vtable client_handshaker_factory_vtable = {
+    client_handshaker_factory_add_handshakers, handshaker_factory_destroy};
+
+static grpc_handshaker_factory client_handshaker_factory = {
+    &client_handshaker_factory_vtable};
+
+static const grpc_handshaker_factory_vtable server_handshaker_factory_vtable = {
+    server_handshaker_factory_add_handshakers, handshaker_factory_destroy};
+
+static grpc_handshaker_factory server_handshaker_factory = {
+    &server_handshaker_factory_vtable};
+
 //
 // exported functions
 //
@@ -452,3 +492,10 @@ grpc_handshaker *grpc_security_handshaker_create(
     return security_handshaker_create(exec_ctx, handshaker, connector);
   }
 }
+
+void grpc_security_register_handshaker_factories() {
+  grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_CLIENT,
+                                   &client_handshaker_factory);
+  grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_SERVER,
+                                   &server_handshaker_factory);
+}
diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h
index 5ddbf4b451..0b9eda178f 100644
--- a/src/core/lib/security/transport/security_handshaker.h
+++ b/src/core/lib/security/transport/security_handshaker.h
@@ -43,4 +43,7 @@ grpc_handshaker *grpc_security_handshaker_create(
     grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
     grpc_security_connector *connector);
 
+/// Registers security handshaker factories.
+void grpc_security_register_handshaker_factories();
+
 #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index e20e602547..f61bf1582e 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/channel/deadline_filter.h"
+#include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/channel/http_client_filter.h"
 #include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/channel/message_size_filter.h"
@@ -204,6 +205,8 @@ void grpc_init(void) {
     grpc_executor_init();
     gpr_timers_global_init();
     grpc_cq_global_init();
+    grpc_handshaker_factory_registry_init();
+    grpc_security_init();
     for (i = 0; i < g_number_of_plugins; i++) {
       if (g_all_of_the_plugins[i].init != NULL) {
         g_all_of_the_plugins[i].init();
@@ -238,6 +241,7 @@ void grpc_shutdown(void) {
       }
     }
     grpc_mdctx_global_shutdown(&exec_ctx);
+    grpc_handshaker_factory_registry_shutdown(&exec_ctx);
   }
   gpr_mu_unlock(&g_init_mu);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h
index b1bf57c10d..3d1c528be0 100644
--- a/src/core/lib/surface/init.h
+++ b/src/core/lib/surface/init.h
@@ -36,6 +36,7 @@
 
 void grpc_register_security_filters(void);
 void grpc_security_pre_init(void);
+void grpc_security_init(void);
 int grpc_is_initialized(void);
 
 #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */
diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c
index 520a8aa84f..a44407d3bb 100644
--- a/src/core/lib/surface/init_secure.c
+++ b/src/core/lib/surface/init_secure.c
@@ -41,6 +41,7 @@
 #include "src/core/lib/security/transport/auth_filters.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/transport/security_handshaker.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/tsi/transport_security_interface.h"
 
@@ -87,3 +88,5 @@ void grpc_register_security_filters(void) {
   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
                                    maybe_prepend_server_auth_filter, NULL);
 }
+
+void grpc_security_init() { grpc_security_register_handshaker_factories(); }
diff --git a/src/core/lib/surface/init_unsecure.c b/src/core/lib/surface/init_unsecure.c
index f952739e0a..dbc9223ae0 100644
--- a/src/core/lib/surface/init_unsecure.c
+++ b/src/core/lib/surface/init_unsecure.c
@@ -36,3 +36,5 @@
 void grpc_security_pre_init(void) {}
 
 void grpc_register_security_filters(void) {}
+
+void grpc_security_init(void) {}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index d43f93b94f..e27e9e181d 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -82,6 +82,8 @@ CORE_SOURCE_FILES = [
   'src/core/lib/channel/connected_channel.c',
   'src/core/lib/channel/deadline_filter.c',
   'src/core/lib/channel/handshaker.c',
+  'src/core/lib/channel/handshaker_factory.c',
+  'src/core/lib/channel/handshaker_registry.c',
   'src/core/lib/channel/http_client_filter.c',
   'src/core/lib/channel/http_server_filter.c',
   'src/core/lib/channel/message_size_filter.c',
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 3f83911a01..c47dcbe9c6 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -797,6 +797,8 @@ src/core/lib/channel/connected_channel.h \
 src/core/lib/channel/context.h \
 src/core/lib/channel/deadline_filter.h \
 src/core/lib/channel/handshaker.h \
+src/core/lib/channel/handshaker_factory.h \
+src/core/lib/channel/handshaker_registry.h \
 src/core/lib/channel/http_client_filter.h \
 src/core/lib/channel/http_server_filter.h \
 src/core/lib/channel/message_size_filter.h \
@@ -977,6 +979,8 @@ src/core/lib/channel/compress_filter.c \
 src/core/lib/channel/connected_channel.c \
 src/core/lib/channel/deadline_filter.c \
 src/core/lib/channel/handshaker.c \
+src/core/lib/channel/handshaker_factory.c \
+src/core/lib/channel/handshaker_registry.c \
 src/core/lib/channel/http_client_filter.c \
 src/core/lib/channel/http_server_filter.c \
 src/core/lib/channel/message_size_filter.c \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 55ec1e748f..8849dcc600 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6681,6 +6681,8 @@
       "src/core/lib/channel/context.h", 
       "src/core/lib/channel/deadline_filter.h", 
       "src/core/lib/channel/handshaker.h", 
+      "src/core/lib/channel/handshaker_factory.h", 
+      "src/core/lib/channel/handshaker_registry.h", 
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.h", 
       "src/core/lib/channel/message_size_filter.h", 
@@ -6800,6 +6802,10 @@
       "src/core/lib/channel/deadline_filter.h", 
       "src/core/lib/channel/handshaker.c", 
       "src/core/lib/channel/handshaker.h", 
+      "src/core/lib/channel/handshaker_factory.c", 
+      "src/core/lib/channel/handshaker_factory.h", 
+      "src/core/lib/channel/handshaker_registry.c", 
+      "src/core/lib/channel/handshaker_registry.h", 
       "src/core/lib/channel/http_client_filter.c", 
       "src/core/lib/channel/http_client_filter.h", 
       "src/core/lib/channel/http_server_filter.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 12535b2fea..2550d1ed97 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -306,6 +306,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
@@ -496,6 +498,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index d5a8ac31c3..642ace6f40 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -25,6 +25,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -761,6 +767,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index a37587ca66..15e3097743 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -199,6 +199,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
@@ -345,6 +347,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 90c718faec..43b7eaad0e 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -82,6 +82,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -551,6 +557,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 7eb562f0b0..d1d3cb2a36 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -296,6 +296,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\deadline_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\message_size_filter.h" />
@@ -464,6 +466,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 25295f7679..7741c62ecb 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -28,6 +28,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
@@ -674,6 +680,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_factory.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker_registry.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
       <Filter>src\core\lib\channel</Filter>
     </ClInclude>
-- 
GitLab


From d9ed57c0d75f872ca8e6a767046f8814db9dfde4 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 6 Jan 2017 13:14:06 -0800
Subject: [PATCH 243/344] Stub documentation for some gRPC Core modules

---
 templates/tools/doxygen/Doxyfile.include |  9 ++++++++-
 tools/doxygen/Doxyfile.c++.internal      |  3 ++-
 tools/doxygen/Doxyfile.core.internal     | 23 ++++++++++++++++++++++-
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/templates/tools/doxygen/Doxyfile.include b/templates/tools/doxygen/Doxyfile.include
index 7fe8a29746..a22f07f33f 100644
--- a/templates/tools/doxygen/Doxyfile.include
+++ b/templates/tools/doxygen/Doxyfile.include
@@ -9,6 +9,7 @@
 <%
   import itertools
   import glob
+  import os
   targets = []
   docpackage = packagename.replace('+', 'p').lower()
   for libname in libnames:
@@ -18,6 +19,11 @@
         target = p
     assert(target)
     targets.append(target)
+  srcdoc = []
+  for dirpath, dirnames, filenames in os.walk('src/%s' % docpackage):
+    for filename in filenames:
+      if os.path.splitext(filename)[1] == '.md':
+        srcdoc.append(os.path.join(dirpath, filename))
 %>
 # Doxyfile 1.8.9.1
 
@@ -790,7 +796,8 @@ INPUT                  = ${
     				     else target.headers + target.src)
     			      for target in targets),
             glob.glob('doc/*.md'),
-            glob.glob('doc/%s/*.md' % docpackage))
+            glob.glob('doc/%s/*.md' % docpackage),
+            [] if not internal else srcdoc)
     )
 }
 
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index e7fa25f1f1..89915d7b08 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -921,7 +921,8 @@ doc/interop-test-descriptions.md \
 doc/statuscodes.md \
 doc/g_stands_for.md \
 doc/cpp/perf_notes.md \
-doc/cpp/pending_api_cleanups.md
+doc/cpp/pending_api_cleanups.md \
+src/cpp/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b13afdca99..7048e0d601 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1303,7 +1303,28 @@ doc/server-reflection.md \
 doc/interop-test-descriptions.md \
 doc/statuscodes.md \
 doc/g_stands_for.md \
-doc/core/pending_api_cleanups.md
+doc/core/pending_api_cleanups.md \
+src/core/README.md \
+src/core/ext/README.md \
+src/core/ext/transport/README.md \
+src/core/ext/transport/chttp2/README.md \
+src/core/ext/transport/chttp2/client/secure/README.md \
+src/core/ext/transport/chttp2/client/insecure/README.md \
+src/core/ext/transport/chttp2/transport/README.md \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/server/insecure/README.md \
+src/core/ext/client_channel/README.md \
+src/core/ext/resolver/README.md \
+src/core/ext/resolver/sockaddr/README.md \
+src/core/ext/resolver/dns/native/README.md \
+src/core/ext/census/README.md \
+src/core/ext/census/gen/README.md \
+src/core/lib/README.md \
+src/core/lib/tsi/README.md \
+src/core/lib/channel/README.md \
+src/core/lib/transport/README.md \
+src/core/lib/iomgr/README.md \
+src/core/lib/surface/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From f687cb89f4ad2fab85a3c2448e42e25293139ef8 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 6 Jan 2017 13:15:27 -0800
Subject: [PATCH 244/344] Actually add the documentation

---
 src/core/ext/README.md                  | 5 +++++
 src/core/ext/resolver/README.md         | 3 +++
 src/core/ext/transport/README.md        | 1 +
 src/core/ext/transport/chttp2/README.md | 1 +
 src/core/lib/README.md                  | 5 +++++
 src/core/lib/channel/README.md          | 4 ++++
 src/core/lib/iomgr/README.md            | 6 ++++++
 src/core/lib/surface/README.md          | 4 ++++
 src/core/lib/transport/README.md        | 7 +++++++
 src/core/lib/tsi/README.md              | 2 ++
 10 files changed, 38 insertions(+)
 create mode 100644 src/core/ext/README.md
 create mode 100644 src/core/ext/resolver/README.md
 create mode 100644 src/core/ext/transport/README.md
 create mode 100644 src/core/ext/transport/chttp2/README.md
 create mode 100644 src/core/lib/README.md
 create mode 100644 src/core/lib/channel/README.md
 create mode 100644 src/core/lib/iomgr/README.md
 create mode 100644 src/core/lib/surface/README.md
 create mode 100644 src/core/lib/transport/README.md
 create mode 100644 src/core/lib/tsi/README.md

diff --git a/src/core/ext/README.md b/src/core/ext/README.md
new file mode 100644
index 0000000000..9f7d19df68
--- /dev/null
+++ b/src/core/ext/README.md
@@ -0,0 +1,5 @@
+Optional plugins for gRPC Core: Modules in this directory extend gRPC Core in
+useful ways.
+
+NOTE: The movement of code between lib and ext is an ongoing effort, so this
+directory currently contains too much of the core library.
diff --git a/src/core/ext/resolver/README.md b/src/core/ext/resolver/README.md
new file mode 100644
index 0000000000..0f49032a5f
--- /dev/null
+++ b/src/core/ext/resolver/README.md
@@ -0,0 +1,3 @@
+# Resolver
+
+Implementations of various name resolution schemes.
diff --git a/src/core/ext/transport/README.md b/src/core/ext/transport/README.md
new file mode 100644
index 0000000000..2290568784
--- /dev/null
+++ b/src/core/ext/transport/README.md
@@ -0,0 +1 @@
+Transports for gRPC
diff --git a/src/core/ext/transport/chttp2/README.md b/src/core/ext/transport/chttp2/README.md
new file mode 100644
index 0000000000..8880a47460
--- /dev/null
+++ b/src/core/ext/transport/chttp2/README.md
@@ -0,0 +1 @@
+CHTTP2 - gRPC's implementation of a HTTP2 based transport
diff --git a/src/core/lib/README.md b/src/core/lib/README.md
new file mode 100644
index 0000000000..fa9335d154
--- /dev/null
+++ b/src/core/lib/README.md
@@ -0,0 +1,5 @@
+Required elements of gRPC Core: Each module in this directory is required to
+build gRPC.
+
+NOTE: The movement of code between lib and ext is an ongoing effort, so this
+directory currently contains too much of the core library.
diff --git a/src/core/lib/channel/README.md b/src/core/lib/channel/README.md
new file mode 100644
index 0000000000..2dfcfe6e66
--- /dev/null
+++ b/src/core/lib/channel/README.md
@@ -0,0 +1,4 @@
+# Channel
+
+Provides channel/call stack implementation, and implementation of common filters
+for that implementation.
diff --git a/src/core/lib/iomgr/README.md b/src/core/lib/iomgr/README.md
new file mode 100644
index 0000000000..9b22b76ceb
--- /dev/null
+++ b/src/core/lib/iomgr/README.md
@@ -0,0 +1,6 @@
+# iomgr
+
+Platform abstractions for I/O (mostly network).
+
+Provides abstractions over TCP/UDP I/O, file loading, polling, and concurrency
+management for various operating systems.
diff --git a/src/core/lib/surface/README.md b/src/core/lib/surface/README.md
new file mode 100644
index 0000000000..74cbd71131
--- /dev/null
+++ b/src/core/lib/surface/README.md
@@ -0,0 +1,4 @@
+# Surface
+
+Surface provides the bulk of the gRPC Core public API, and translates it into
+calls against core components.
diff --git a/src/core/lib/transport/README.md b/src/core/lib/transport/README.md
new file mode 100644
index 0000000000..e7e135edeb
--- /dev/null
+++ b/src/core/lib/transport/README.md
@@ -0,0 +1,7 @@
+# Transport
+
+Common implementation details for gRPC Transports.
+
+Transports multiplex messages across some single connection. In ext/ there are
+implementations atop [a custom http2 implementation](/src/core/ext/transport/chttp2/README.md)
+and atop [cronet](/src/core/ext/transport/cronet/README.md).
diff --git a/src/core/lib/tsi/README.md b/src/core/lib/tsi/README.md
new file mode 100644
index 0000000000..3ca3c1ef38
--- /dev/null
+++ b/src/core/lib/tsi/README.md
@@ -0,0 +1,2 @@
+# Transport Security Interface
+An abstraction library over crypto and auth modules (typically OpenSSL)
-- 
GitLab


From cbf5447a0dc0516925b54f2d0af896f53ea46250 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 6 Jan 2017 13:55:44 -0800
Subject: [PATCH 245/344] Review feedback

---
 src/core/ext/README.md          | 2 +-
 src/core/ext/resolver/README.md | 1 +
 src/core/lib/README.md          | 3 ++-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/README.md b/src/core/ext/README.md
index 9f7d19df68..0812b20823 100644
--- a/src/core/ext/README.md
+++ b/src/core/ext/README.md
@@ -1,5 +1,5 @@
 Optional plugins for gRPC Core: Modules in this directory extend gRPC Core in
-useful ways.
+useful ways. All optional code belongs here.
 
 NOTE: The movement of code between lib and ext is an ongoing effort, so this
 directory currently contains too much of the core library.
diff --git a/src/core/ext/resolver/README.md b/src/core/ext/resolver/README.md
index 0f49032a5f..b0e234e96a 100644
--- a/src/core/ext/resolver/README.md
+++ b/src/core/ext/resolver/README.md
@@ -1,3 +1,4 @@
 # Resolver
 
 Implementations of various name resolution schemes.
+See the [naming spec](/doc/naming.md).
diff --git a/src/core/lib/README.md b/src/core/lib/README.md
index fa9335d154..69b6bce2d9 100644
--- a/src/core/lib/README.md
+++ b/src/core/lib/README.md
@@ -1,5 +1,6 @@
 Required elements of gRPC Core: Each module in this directory is required to
-build gRPC.
+build gRPC. If it's possible to envisage a configuration where code is not
+required, then that code belongs in ext/ instead.
 
 NOTE: The movement of code between lib and ext is an ongoing effort, so this
 directory currently contains too much of the core library.
-- 
GitLab


From afb23e51b2bb514a29aff4966add0d2e0422b0c2 Mon Sep 17 00:00:00 2001
From: Eric Gribkoff <ericgribkoff@google.com>
Date: Fri, 6 Jan 2017 14:15:54 -0800
Subject: [PATCH 246/344] Note to help diagnose errors with docker's default
 location for building images.

---
 tools/run_tests/README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/run_tests/README.md b/tools/run_tests/README.md
index dd727f4309..e709ddd2c0 100644
--- a/tools/run_tests/README.md
+++ b/tools/run_tests/README.md
@@ -22,6 +22,10 @@ The script is also capable of running interop tests for grpc-java and grpc-go, u
 ######Example
 `tools/run_tests/run_interop_tests.py -l csharp -s c++ --use_docker` (run interop tests with C# client and C++ server)
 
+Note: if you see an error like `no space left on device` when running the
+interop tests using Docker, make sure that Docker is building the image files in
+a location with sufficient disk space.
+
 #Performance benchmarks (run_performance_tests.py)
 
 Runs predefined benchmark scenarios for given languages. Besides the simple configuration of running all the scenarios locally,
-- 
GitLab


From fd9f53a20fc87d1ff70f38c850eb7f03296cfb60 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 6 Jan 2017 15:33:04 -0800
Subject: [PATCH 247/344] clang-format

---
 include/grpc/impl/codegen/slice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 9c226f78c4..00781bb76b 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,8 +37,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include <grpc/impl/codegen/gpr_slice.h>
 #include <grpc/impl/codegen/exec_ctx_fwd.h>
+#include <grpc/impl/codegen/gpr_slice.h>
 
 /* Slice API
 
-- 
GitLab


From c17ed124eca8fc6bed31c6e0d192fde386bdb3c2 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 9 Jan 2017 09:37:43 -0800
Subject: [PATCH 248/344] Ran generate-projects.sh

---
 tools/doxygen/Doxyfile.c++           | 32 ++++++++---------
 tools/doxygen/Doxyfile.c++.internal  | 32 ++++++++---------
 tools/doxygen/Doxyfile.core          | 32 ++++++++---------
 tools/doxygen/Doxyfile.core.internal | 52 ++++++++++++++--------------
 4 files changed, 74 insertions(+), 74 deletions(-)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 2cd59863b6..13f440441b 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -850,31 +850,31 @@ include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
 doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
+doc/binary-logging.md \
 doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
+doc/c-style-guide.md \
 doc/PROTOCOL-WEB.md \
 doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
-doc/c-style-guide.md \
 doc/server_reflection_tutorial.md \
-doc/health-checking.md \
-doc/connection-backoff-interop-test-description.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/compression_cookbook.md \
+doc/connection-backoff.md \
 doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
 doc/connectivity-semantics-and-api.md \
-doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
+doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
 doc/cpp/perf_notes.md \
 doc/cpp/pending_api_cleanups.md
 
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 6ab452eaba..a86dfde172 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -896,31 +896,31 @@ src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
 src/cpp/codegen/codegen_init.cc \
 doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
+doc/binary-logging.md \
 doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
+doc/c-style-guide.md \
 doc/PROTOCOL-WEB.md \
 doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
-doc/c-style-guide.md \
 doc/server_reflection_tutorial.md \
-doc/health-checking.md \
-doc/connection-backoff-interop-test-description.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/compression_cookbook.md \
+doc/connection-backoff.md \
 doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
 doc/connectivity-semantics-and-api.md \
-doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
+doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
 doc/cpp/perf_notes.md \
 doc/cpp/pending_api_cleanups.md \
 src/cpp/README.md
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 16f8dcc29e..ec4d6813e8 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -829,31 +829,31 @@ include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
 doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
+doc/binary-logging.md \
 doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
+doc/c-style-guide.md \
 doc/PROTOCOL-WEB.md \
 doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
-doc/c-style-guide.md \
 doc/server_reflection_tutorial.md \
-doc/health-checking.md \
-doc/connection-backoff-interop-test-description.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/compression_cookbook.md \
+doc/connection-backoff.md \
 doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
 doc/connectivity-semantics-and-api.md \
-doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
+doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
 doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index d9f69427b1..34e5304ce4 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1280,53 +1280,53 @@ src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
 doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
+doc/binary-logging.md \
 doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
+doc/c-style-guide.md \
 doc/PROTOCOL-WEB.md \
 doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
-doc/c-style-guide.md \
 doc/server_reflection_tutorial.md \
-doc/health-checking.md \
-doc/connection-backoff-interop-test-description.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/compression_cookbook.md \
+doc/connection-backoff.md \
 doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
 doc/connectivity-semantics-and-api.md \
-doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
+doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
 doc/core/pending_api_cleanups.md \
 src/core/README.md \
 src/core/ext/README.md \
+src/core/ext/resolver/README.md \
+src/core/ext/resolver/dns/native/README.md \
+src/core/ext/resolver/sockaddr/README.md \
+src/core/ext/client_channel/README.md \
 src/core/ext/transport/README.md \
 src/core/ext/transport/chttp2/README.md \
-src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/client/insecure/README.md \
-src/core/ext/transport/chttp2/transport/README.md \
-src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/server/insecure/README.md \
-src/core/ext/client_channel/README.md \
-src/core/ext/resolver/README.md \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/resolver/dns/native/README.md \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/transport/README.md \
 src/core/ext/census/README.md \
 src/core/ext/census/gen/README.md \
 src/core/lib/README.md \
+src/core/lib/iomgr/README.md \
 src/core/lib/tsi/README.md \
-src/core/lib/channel/README.md \
+src/core/lib/surface/README.md \
 src/core/lib/transport/README.md \
-src/core/lib/iomgr/README.md \
-src/core/lib/surface/README.md
+src/core/lib/channel/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From 7fc6f3be56a285bea98c9c2e980fa2720edf87b9 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Mon, 9 Jan 2017 10:55:51 -0800
Subject: [PATCH 249/344] changes to http2 test server

Not kill the server on disconnect
Spawn one server per test case
---
 test/http2_test/http2_base_server.py |  1 -
 test/http2_test/http2_test_server.py | 34 ++++++++++++++++++++--------
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/test/http2_test/http2_base_server.py b/test/http2_test/http2_base_server.py
index ee7719b1a8..8de028ceb1 100644
--- a/test/http2_test/http2_base_server.py
+++ b/test/http2_test/http2_base_server.py
@@ -73,7 +73,6 @@ class H2ProtocolBaseServer(twisted.internet.protocol.Protocol):
 
   def on_connection_lost(self, reason):
     logging.info('Disconnected %s' % reason)
-    twisted.internet.reactor.callFromThread(twisted.internet.reactor.stop)
 
   def dataReceived(self, data):
     try:
diff --git a/test/http2_test/http2_test_server.py b/test/http2_test/http2_test_server.py
index 44e36d34b6..abde3433ad 100644
--- a/test/http2_test/http2_test_server.py
+++ b/test/http2_test/http2_test_server.py
@@ -73,18 +73,32 @@ class H2Factory(twisted.internet.protocol.Factory):
     else:
       return t().get_base_server()
 
+def parse_arguments():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--base_port', type=int, default=8080,
+    help='base port to run the servers (default: 8080). One test server is '
+    'started on each incrementing port, beginning with base_port, in the '
+    'following order: goaway,max_streams,ping,rst_after_data,rst_after_header,'
+    'rst_during_data'
+    )
+  return parser.parse_args()
+
+def start_test_servers(base_port):
+  """ Start one server per test case on incrementing port numbers
+  beginning with base_port """
+  index = 0
+  for test_case in sorted(_TEST_CASE_MAPPING.keys()):
+    portnum = base_port + index
+    logging.warning('serving on port %d : %s'%(portnum, test_case))
+    endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(
+      twisted.internet.reactor, portnum, backlog=128)
+    endpoint.listen(H2Factory(test_case))
+    index += 1
+
 if __name__ == '__main__':
   logging.basicConfig(
     format='%(levelname) -10s %(asctime)s %(module)s:%(lineno)s | %(message)s',
     level=logging.INFO)
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--test_case', choices=sorted(_TEST_CASE_MAPPING.keys()),
-    help='test case to run', required=True)
-  parser.add_argument('--port', type=int, default=8080,
-    help='port to run the server (default: 8080)')
-  args = parser.parse_args()
-  logging.info('Running test case %s on port %d' % (args.test_case, args.port))
-  endpoint = twisted.internet.endpoints.TCP4ServerEndpoint(
-    twisted.internet.reactor, args.port, backlog=128)
-  endpoint.listen(H2Factory(args.test_case))
+  args = parse_arguments()
+  start_test_servers(args.base_port)
   twisted.internet.reactor.run()
-- 
GitLab


From 56610d4706593cca120ac62c41489438ae589293 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Mon, 9 Jan 2017 11:44:27 -0800
Subject: [PATCH 250/344] Address github comments

---
 src/ruby/pb/test/client.rb | 42 +++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 26 deletions(-)

diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index 756c68c422..e051676463 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -517,35 +517,30 @@ class NamedTests
   def unimplemented_method
     begin
       resp = @stub.unimplemented_call(Empty.new)
-    rescue GRPC::BadStatus => e
-      if e.code != GRPC::Core::StatusCodes::UNIMPLEMENTED
-        fail AssertionError,
-          "Expected status 12 (UNIMPLEMENTED). Received: #{e.code}"
-      end
+    rescue GRPC::Unimplemented => e
+      return
     rescue Exception => e
       fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
     end
+    fail AssertionError, "GRPC::Unimplemented should have been raised. Was not."
   end
 
   def unimplemented_service
     begin
       resp = @stub.unimplemented_call(Empty.new)
-    rescue GRPC::BadStatus => e
-      if e.code != GRPC::Core::StatusCodes::UNIMPLEMENTED
-        fail AssertionError,
-          "Expected status 12 (UNIMPLEMENTED). Received: #{e.code}"
-      end
+    rescue GRPC::Unimplemented => e
+      return
     rescue Exception => e
       fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
     end
+    fail AssertionError, "GRPC::Unimplemented should have been raised. Was not."
   end
 
   def status_code_and_message
 
     # Function wide constants.
     message = "test status method"
-    code = 2
-    status = GRPC::Core::StatusCodes::UNKNOWN
+    code = GRPC::Core::StatusCodes::UNKNOWN
 
     # Testing with UnaryCall.
     payload = Payload.new(type: :COMPRESSABLE, body: nulls(1))
@@ -557,11 +552,8 @@ class NamedTests
     seen_correct_exception = false
     begin
       resp = @stub.unary_call(req)
-    rescue GRPC::BadStatus => e
-      if e.code != status
-        fail AssertionError,
-	        "Expected status 2 (UNKOWN). Received: #{e.code}"
-      elsif e.details != message
+    rescue GRPC::Unknown => e
+      if e.details != message
 	      fail AssertionError,
 	        "Expected message #{message}. Received: #{e.details}"
       end
@@ -584,11 +576,8 @@ class NamedTests
     begin
       resp = @stub.full_duplex_call([duplex_req])
       resp.next # triggers initial req to be sent
-    rescue GRPC::BadStatus => e
-      if e.code != status
-        fail AssertionError,
-          "Expected status 2 (UNKOWN). Received: #{e.code}"
-      elsif e.details != message
+    rescue GRPC::Unknown => e
+      if e.details != message
         fail AssertionError,
           "Expected message #{message}. Received: #{e.details}"
       end
@@ -607,6 +596,7 @@ class NamedTests
   def custom_metadata
 
     # Function wide constants
+    req_size, wanted_response_size = 271_828, 314_159
     initial_metadata_key = "x-grpc-test-echo-initial"
     initial_metadata_value = "test_initial_metadata_value"
     trailing_metadata_key = "x-grpc-test-echo-trailing-bin"
@@ -618,9 +608,9 @@ class NamedTests
     }
 
     # Testing with UnaryCall
-    payload = Payload.new(type: :COMPRESSABLE, body: nulls(1))
+    payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
     req = SimpleRequest.new(response_type: :COMPRESSABLE,
-			    response_size: 1,
+			    response_size: wanted_response_size,
 			    payload: payload)
 
     op = @stub.unary_call(req, metadata: metadata, return_op: true)
@@ -643,9 +633,9 @@ class NamedTests
 
     # Testing with FullDuplex
     req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters
-    duplex_req = req_cls.new(payload: Payload.new(body: nulls(1)),
+    duplex_req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
                   response_type: :COMPRESSABLE,
-                  response_parameters: [p_cls.new(size: 1)])
+                  response_parameters: [p_cls.new(size: wanted_response_size)])
 
     duplex_op = @stub.full_duplex_call([duplex_req], metadata: metadata,
                                         return_op: true)
-- 
GitLab


From 49f02d3697ed109b514edc7e746088b8e5d7b819 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 9 Jan 2017 14:54:46 -0800
Subject: [PATCH 251/344] Add support for sending custom headers in HTTP
 CONNECT request.

---
 .../client_channel/http_connect_handshaker.c  | 24 +++++++++++++++++--
 .../client_channel/http_connect_handshaker.h  |  5 +++-
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index ace804c47f..0561c81aa5 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -55,6 +55,8 @@ typedef struct http_connect_handshaker {
   grpc_handshaker base;
 
   char* proxy_server;
+  grpc_http_header* headers;
+  size_t num_headers;
 
   gpr_refcount refcount;
   gpr_mu mu;
@@ -90,6 +92,11 @@ static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
       gpr_free(handshaker->read_buffer_to_destroy);
     }
     gpr_free(handshaker->proxy_server);
+    for (size_t i = 0; i < handshaker->num_headers; ++i) {
+      gpr_free(handshaker->headers[i].key);
+      gpr_free(handshaker->headers[i].value);
+    }
+    gpr_free(handshaker->headers);
     grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
     grpc_http_parser_destroy(&handshaker->http_parser);
     grpc_http_response_destroy(&handshaker->http_response);
@@ -290,6 +297,8 @@ static void http_connect_handshaker_do_handshake(
   request.host = server_name;
   request.http.method = "CONNECT";
   request.http.path = server_name;
+  request.http.hdrs = handshaker->headers;
+  request.http.hdr_count = handshaker->num_headers;
   request.handshaker = &grpc_httpcli_plaintext;
   grpc_slice request_slice = grpc_httpcli_format_connect_request(&request);
   grpc_slice_buffer_add(&handshaker->write_buffer, request_slice);
@@ -307,7 +316,9 @@ static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
     http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
     http_connect_handshaker_do_handshake};
 
-grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) {
+grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
+                                                     grpc_http_header* headers,
+                                                     size_t num_headers) {
   GPR_ASSERT(proxy_server != NULL);
   http_connect_handshaker* handshaker = gpr_malloc(sizeof(*handshaker));
   memset(handshaker, 0, sizeof(*handshaker));
@@ -315,6 +326,14 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) {
   gpr_mu_init(&handshaker->mu);
   gpr_ref_init(&handshaker->refcount, 1);
   handshaker->proxy_server = gpr_strdup(proxy_server);
+  if (num_headers > 0) {
+    handshaker->headers = gpr_malloc(sizeof(grpc_http_header) * num_headers);
+    for (size_t i = 0; i < num_headers; ++i) {
+      handshaker->headers[i].key = gpr_strdup(headers[i].key);
+      handshaker->headers[i].value = gpr_strdup(headers[i].value);
+    }
+    handshaker->num_headers = num_headers;
+  }
   grpc_slice_buffer_init(&handshaker->write_buffer);
   grpc_closure_init(&handshaker->request_done_closure, on_write_done,
                     handshaker, grpc_schedule_on_exec_ctx);
@@ -359,7 +378,8 @@ static void handshaker_factory_add_handshakers(
   char* proxy_name = grpc_get_http_proxy_server();
   if (proxy_name != NULL) {
     grpc_handshake_manager_add(handshake_mgr,
-                               grpc_http_connect_handshaker_create(proxy_name));
+                               grpc_http_connect_handshaker_create(proxy_name,
+                                                                   NULL, 0));
     gpr_free(proxy_name);
   }
 }
diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/client_channel/http_connect_handshaker.h
index 56485f1373..c2e68de716 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.h
+++ b/src/core/ext/client_channel/http_connect_handshaker.h
@@ -35,9 +35,12 @@
 #define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
 
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/http/parser.h"
 
 /// Creates a new HTTP CONNECT handshaker.
-grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server);
+grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
+                                                     grpc_http_header* headers,
+                                                     size_t num_headers);
 
 /// Returns the name of the proxy to use, or NULL if no proxy is configured.
 /// Caller takes ownership of result.
-- 
GitLab


From 466589606a933bfcc453c51daef8fc7f689001e0 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Mon, 9 Jan 2017 14:56:18 -0800
Subject: [PATCH 252/344] clang-format

---
 src/core/ext/client_channel/http_connect_handshaker.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 0561c81aa5..fba32561ac 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -377,9 +377,9 @@ static void handshaker_factory_add_handshakers(
     const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) {
   char* proxy_name = grpc_get_http_proxy_server();
   if (proxy_name != NULL) {
-    grpc_handshake_manager_add(handshake_mgr,
-                               grpc_http_connect_handshaker_create(proxy_name,
-                                                                   NULL, 0));
+    grpc_handshake_manager_add(
+        handshake_mgr,
+        grpc_http_connect_handshaker_create(proxy_name, NULL, 0));
     gpr_free(proxy_name);
   }
 }
-- 
GitLab


From dc29074997772b757934ffd7eccb6f7cb43ff9f3 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Mon, 9 Jan 2017 15:16:36 -0800
Subject: [PATCH 253/344] Incorperate new build changes

---
 tools/doxygen/Doxyfile.c++           | 42 +++++++++----------
 tools/doxygen/Doxyfile.c++.internal  | 40 +++++++++---------
 tools/doxygen/Doxyfile.core          | 38 ++++++++---------
 tools/doxygen/Doxyfile.core.internal | 62 ++++++++++++++--------------
 4 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 2c16f6f24a..6539f96565 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -848,34 +848,34 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
-doc/cpp/perf_notes.md \
-doc/cpp/pending_api_cleanups.md
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 89915d7b08..ffef534fe2 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -894,34 +894,34 @@ src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
 src/cpp/codegen/codegen_init.cc \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
-doc/cpp/perf_notes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md \
 src/cpp/README.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index e7fc1dbc57..f8a3970416 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -826,32 +826,32 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 8b60152009..1a945bec49 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1281,54 +1281,54 @@ src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md \
 src/core/README.md \
 src/core/ext/README.md \
+src/core/ext/census/README.md \
+src/core/ext/census/gen/README.md \
+src/core/ext/client_channel/README.md \
+src/core/ext/resolver/README.md \
+src/core/ext/resolver/dns/native/README.md \
+src/core/ext/resolver/sockaddr/README.md \
 src/core/ext/transport/README.md \
 src/core/ext/transport/chttp2/README.md \
-src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/client/insecure/README.md \
-src/core/ext/transport/chttp2/transport/README.md \
-src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/server/insecure/README.md \
-src/core/ext/client_channel/README.md \
-src/core/ext/resolver/README.md \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/resolver/dns/native/README.md \
-src/core/ext/census/README.md \
-src/core/ext/census/gen/README.md \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/transport/README.md \
 src/core/lib/README.md \
-src/core/lib/tsi/README.md \
 src/core/lib/channel/README.md \
-src/core/lib/transport/README.md \
 src/core/lib/iomgr/README.md \
-src/core/lib/surface/README.md
+src/core/lib/surface/README.md \
+src/core/lib/transport/README.md \
+src/core/lib/tsi/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From 7429fd57e79713a5f3233081baea1fa9ab84d7e3 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Mon, 9 Jan 2017 15:26:05 -0800
Subject: [PATCH 254/344] Regenerate project to make jenkins happy

---
 tools/doxygen/Doxyfile.c++           | 42 +++++++++----------
 tools/doxygen/Doxyfile.c++.internal  | 40 +++++++++---------
 tools/doxygen/Doxyfile.core          | 38 ++++++++---------
 tools/doxygen/Doxyfile.core.internal | 62 ++++++++++++++--------------
 4 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 2c16f6f24a..6539f96565 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -848,34 +848,34 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
-doc/cpp/perf_notes.md \
-doc/cpp/pending_api_cleanups.md
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 89915d7b08..ffef534fe2 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -894,34 +894,34 @@ src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
 src/cpp/codegen/codegen_init.cc \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
-doc/cpp/perf_notes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md \
 src/cpp/README.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index e7fc1dbc57..f8a3970416 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -826,32 +826,32 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 8b60152009..1a945bec49 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1281,54 +1281,54 @@ src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
-doc/fail_fast.md \
-doc/compression.md \
-doc/environment_variables.md \
-doc/stress_test_framework.md \
-doc/PROTOCOL-WEB.md \
-doc/cpp-style-guide.md \
-doc/http-grpc-status-mapping.md \
-doc/wait-for-ready.md \
-doc/command_line_tool.md \
+doc/binary-logging.md \
 doc/c-style-guide.md \
-doc/server_reflection_tutorial.md \
-doc/health-checking.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
 doc/connection-backoff-interop-test-description.md \
-doc/epoll-polling-engine.md \
-doc/naming.md \
-doc/binary-logging.md \
-doc/connectivity-semantics-and-api.md \
 doc/connection-backoff.md \
-doc/compression_cookbook.md \
-doc/PROTOCOL-HTTP2.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
 doc/load-balancing.md \
+doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
 doc/server-reflection.md \
-doc/interop-test-descriptions.md \
+doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/g_stands_for.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md \
 src/core/README.md \
 src/core/ext/README.md \
+src/core/ext/census/README.md \
+src/core/ext/census/gen/README.md \
+src/core/ext/client_channel/README.md \
+src/core/ext/resolver/README.md \
+src/core/ext/resolver/dns/native/README.md \
+src/core/ext/resolver/sockaddr/README.md \
 src/core/ext/transport/README.md \
 src/core/ext/transport/chttp2/README.md \
-src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/client/insecure/README.md \
-src/core/ext/transport/chttp2/transport/README.md \
-src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/server/insecure/README.md \
-src/core/ext/client_channel/README.md \
-src/core/ext/resolver/README.md \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/resolver/dns/native/README.md \
-src/core/ext/census/README.md \
-src/core/ext/census/gen/README.md \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/transport/README.md \
 src/core/lib/README.md \
-src/core/lib/tsi/README.md \
 src/core/lib/channel/README.md \
-src/core/lib/transport/README.md \
 src/core/lib/iomgr/README.md \
-src/core/lib/surface/README.md
+src/core/lib/surface/README.md \
+src/core/lib/transport/README.md \
+src/core/lib/tsi/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From 871626ff160b6431c3b20ba906d80f4aa7edc0c1 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Mon, 9 Jan 2017 18:06:49 -0800
Subject: [PATCH 255/344] clang-format

---
 src/core/ext/transport/cronet/transport/cronet_transport.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 099f50b406..06c7e41dad 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -1001,7 +1001,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
       stream_state->rs.length_field_received = false;
       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->rs.remaining_bytes);
       result = ACTION_TAKEN_NO_CALLBACK;
     }
   } else if (stream_op->recv_trailing_metadata &&
-- 
GitLab


From a52032ed09924f4e939ee4b87ad4e39854fe7a59 Mon Sep 17 00:00:00 2001
From: Muxi Yan <mxyan@google.com>
Date: Tue, 10 Jan 2017 03:35:41 +0000
Subject: [PATCH 256/344] Build fix

---
 Makefile                                      |  13 ++
 .../generated/sources_and_headers.json        |  23 +++-
 .../vcxproj/benchmark/benchmark.vcxproj       |  48 ++++++-
 .../benchmark/benchmark.vcxproj.filters       | 118 ++++++++++++++++++
 4 files changed, 200 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 6e690a46eb..a26842e71b 100644
--- a/Makefile
+++ b/Makefile
@@ -7017,6 +7017,19 @@ endif
 
 
 LIBBENCHMARK_SRC = \
+    third_party/benchmark/src/benchmark.cc \
+    third_party/benchmark/src/benchmark_register.cc \
+    third_party/benchmark/src/colorprint.cc \
+    third_party/benchmark/src/commandlineflags.cc \
+    third_party/benchmark/src/complexity.cc \
+    third_party/benchmark/src/console_reporter.cc \
+    third_party/benchmark/src/csv_reporter.cc \
+    third_party/benchmark/src/json_reporter.cc \
+    third_party/benchmark/src/reporter.cc \
+    third_party/benchmark/src/sleep.cc \
+    third_party/benchmark/src/string_util.cc \
+    third_party/benchmark/src/sysinfo.cc \
+    third_party/benchmark/src/timers.cc \
 
 PUBLIC_HEADERS_CXX += \
 
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index bd5b76ec1d..e80937be17 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -6206,7 +6206,28 @@
   }, 
   {
     "deps": [], 
-    "headers": [], 
+    "headers": [
+      "third_party/benchmark/include/benchmark/benchmark.h", 
+      "third_party/benchmark/include/benchmark/benchmark_api.h", 
+      "third_party/benchmark/include/benchmark/macros.h", 
+      "third_party/benchmark/include/benchmark/reporter.h", 
+      "third_party/benchmark/src/arraysize.h", 
+      "third_party/benchmark/src/benchmark_api_internal.h", 
+      "third_party/benchmark/src/check.h", 
+      "third_party/benchmark/src/colorprint.h", 
+      "third_party/benchmark/src/commandlineflags.h", 
+      "third_party/benchmark/src/complexity.h", 
+      "third_party/benchmark/src/cycleclock.h", 
+      "third_party/benchmark/src/internal_macros.h", 
+      "third_party/benchmark/src/log.h", 
+      "third_party/benchmark/src/mutex.h", 
+      "third_party/benchmark/src/re.h", 
+      "third_party/benchmark/src/sleep.h", 
+      "third_party/benchmark/src/stat.h", 
+      "third_party/benchmark/src/string_util.h", 
+      "third_party/benchmark/src/sysinfo.h", 
+      "third_party/benchmark/src/timers.h"
+    ], 
     "is_filegroup": false, 
     "language": "c++", 
     "name": "benchmark", 
diff --git a/vsprojects/vcxproj/benchmark/benchmark.vcxproj b/vsprojects/vcxproj/benchmark/benchmark.vcxproj
index 811317595f..9f262b3b00 100644
--- a/vsprojects/vcxproj/benchmark/benchmark.vcxproj
+++ b/vsprojects/vcxproj/benchmark/benchmark.vcxproj
@@ -147,7 +147,53 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\vsprojects\dummy.c">
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\benchmark.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\benchmark_api.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\macros.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\reporter.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\arraysize.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark_api_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\check.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\colorprint.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\commandlineflags.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\complexity.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\cycleclock.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\internal_macros.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\mutex.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\re.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\sleep.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\stat.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\string_util.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\sysinfo.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\timers.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark_register.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\colorprint.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\commandlineflags.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\complexity.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\console_reporter.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\csv_reporter.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\json_reporter.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\reporter.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\sleep.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\string_util.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\sysinfo.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\timers.cc">
     </ClCompile>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/vsprojects/vcxproj/benchmark/benchmark.vcxproj.filters b/vsprojects/vcxproj/benchmark/benchmark.vcxproj.filters
index 00e4276f1d..ccc9ca2cae 100644
--- a/vsprojects/vcxproj/benchmark/benchmark.vcxproj.filters
+++ b/vsprojects/vcxproj/benchmark/benchmark.vcxproj.filters
@@ -1,7 +1,125 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark_register.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\colorprint.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\commandlineflags.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\complexity.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\console_reporter.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\csv_reporter.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\json_reporter.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\reporter.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\sleep.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\string_util.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\sysinfo.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\benchmark\src\timers.cc">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\benchmark.h">
+      <Filter>third_party\benchmark\include\benchmark</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\benchmark_api.h">
+      <Filter>third_party\benchmark\include\benchmark</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\macros.h">
+      <Filter>third_party\benchmark\include\benchmark</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\include\benchmark\reporter.h">
+      <Filter>third_party\benchmark\include\benchmark</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\arraysize.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\benchmark_api_internal.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\check.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\colorprint.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\commandlineflags.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\complexity.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\cycleclock.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\internal_macros.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\log.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\mutex.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\re.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\sleep.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\stat.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\string_util.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\sysinfo.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\benchmark\src\timers.h">
+      <Filter>third_party\benchmark\src</Filter>
+    </ClInclude>
+  </ItemGroup>
 
   <ItemGroup>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{7b593518-9fee-107e-6b64-24bdce73f939}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\benchmark">
+      <UniqueIdentifier>{f0d35de1-6b41-778d-0ba0-faad514fb0f4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\benchmark\include">
+      <UniqueIdentifier>{cbc02dfa-face-8cc6-0efb-efacc0c3369c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\benchmark\include\benchmark">
+      <UniqueIdentifier>{4f2f03fc-b82d-df33-63ee-bedebeb2c0ee}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\benchmark\src">
+      <UniqueIdentifier>{f42a8e0a-5a76-0e6f-d708-f0306858f673}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
-- 
GitLab


From 8d770144c259abbd7a307e96f9aec5e9bda1c4ea Mon Sep 17 00:00:00 2001
From: thinkerou <thinkerou@gmail.com>
Date: Tue, 10 Jan 2017 13:26:42 +0800
Subject: [PATCH 257/344] attempt to fix mem leaks

---
 src/php/ext/grpc/call.c                |  2 ++
 src/php/ext/grpc/call_credentials.c    | 10 +++---
 src/php/ext/grpc/channel_credentials.c | 12 ++------
 src/php/ext/grpc/php7_wrapper.h        | 12 ++++++++
 src/php/ext/grpc/php_grpc.h            |  4 ---
 src/php/ext/grpc/server_credentials.c  |  4 +--
 src/php/ext/grpc/timeval.c             | 42 +++++++++-----------------
 7 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 3a49ea8708..64b1137c2a 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -478,6 +478,7 @@ PHP_METHOD(Call, startBatch) {
                                    true);
       add_property_zval(result, "status", recv_status);
       PHP_GRPC_DELREF(recv_status);
+      PHP_GRPC_FREE_STD_ZVAL(recv_status);
       break;
     case GRPC_OP_RECV_CLOSE_ON_SERVER:
       add_property_bool(result, "cancelled", cancelled);
@@ -501,6 +502,7 @@ cleanup:
     }
     if (ops[i].op == GRPC_OP_RECV_MESSAGE) {
       grpc_byte_buffer_destroy(message);
+      PHP_GRPC_FREE_STD_ZVAL(message_str);
     }
   }
   RETURN_DESTROY_ZVAL(result);
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index 3aafc3a19b..043817facd 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -111,9 +111,7 @@ PHP_METHOD(CallCredentials, createComposite) {
   grpc_call_credentials *creds =
       grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped,
                                              NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -155,9 +153,7 @@ PHP_METHOD(CallCredentials, createFromPlugin) {
 
   grpc_call_credentials *creds =
     grpc_metadata_credentials_create_from_plugin(plugin, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -211,6 +207,8 @@ void plugin_destroy_state(void *ptr) {
   plugin_state *state = (plugin_state *)ptr;
   efree(state->fci);
   efree(state->fci_cache);
+  PHP_GRPC_FREE_STD_ZVAL(state->fci->params);
+  PHP_GRPC_FREE_STD_ZVAL(state->fci->retval);
   efree(state);
 }
 
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index a32c4a4ea2..36a8223b88 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -121,9 +121,7 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) {
  */
 PHP_METHOD(ChannelCredentials, createDefault) {
   grpc_channel_credentials *creds = grpc_google_default_credentials_create();
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -160,9 +158,7 @@ PHP_METHOD(ChannelCredentials, createSsl) {
   grpc_channel_credentials *creds = grpc_ssl_credentials_create(
       pem_root_certs,
       pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -191,9 +187,7 @@ PHP_METHOD(ChannelCredentials, createComposite) {
   grpc_channel_credentials *creds =
       grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
                                                 NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index 1d7824113f..72e982d6fc 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -50,8 +50,13 @@
 
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
+#define PHP_GRPC_FREE_STD_ZVAL(pzv)
 #define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv)
 
+#define RETURN_DESTROY_ZVAL(val) \
+  RETURN_ZVAL(val, false /* Don't execute copy constructor */, \
+              true /* Dealloc original before returning */)
+
 #define PHP_GRPC_WRAP_OBJECT_START(name) \
   typedef struct name { \
     zend_object std;
@@ -144,8 +149,15 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
   pzv = (zval *)emalloc(sizeof(zval));
+#define PHP_GRPC_FREE_STD_ZVAL(pzv) efree(pzv);
 #define PHP_GRPC_DELREF(zv)
 
+#define RETURN_DESTROY_ZVAL(val) \
+  RETVAL_ZVAL(val, false /* Don't execute copy constructor */, \
+              true /* Dealloc original before returning */); \
+  efree(val); \
+  return
+
 #define PHP_GRPC_WRAP_OBJECT_START(name) \
   typedef struct name {
 #define PHP_GRPC_WRAP_OBJECT_END(name) \
diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h
index e57a06545e..13083b0bc7 100644
--- a/src/php/ext/grpc/php_grpc.h
+++ b/src/php/ext/grpc/php_grpc.h
@@ -61,10 +61,6 @@ extern zend_module_entry grpc_module_entry;
 
 #include "grpc/grpc.h"
 
-#define RETURN_DESTROY_ZVAL(val)                               \
-  RETURN_ZVAL(val, false /* Don't execute copy constructor */, \
-              true /* Dealloc original before returning */)
-
 /* These are all function declarations */
 /* Code that runs at module initialization */
 PHP_MINIT_FUNCTION(grpc);
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index 1610c8ebb0..3e39fee246 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -113,9 +113,7 @@ PHP_METHOD(ServerCredentials, createSsl) {
   grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
       pem_root_certs, &pem_key_cert_pair, 1,
       GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index 945231b47f..7ada915aad 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -115,11 +115,9 @@ PHP_METHOD(Timeval, add) {
   }
   wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
   wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-  zval *sum;
-  PHP_GRPC_MAKE_STD_ZVAL(sum);
-  sum =
-      grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped)
-                            TSRMLS_CC);
+  zval *sum =
+    grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped)
+                          TSRMLS_CC);
   RETURN_DESTROY_ZVAL(sum);
 }
 
@@ -141,11 +139,9 @@ PHP_METHOD(Timeval, subtract) {
   }
   wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
   wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-  zval *diff;
-  PHP_GRPC_MAKE_STD_ZVAL(diff);
-  diff =
-      grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped)
-                            TSRMLS_CC);
+  zval *diff =
+    grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped)
+                          TSRMLS_CC);
   RETURN_DESTROY_ZVAL(diff);
 }
 
@@ -206,9 +202,7 @@ PHP_METHOD(Timeval, similar) {
  * @return Timeval The current time
  */
 PHP_METHOD(Timeval, now) {
-  zval *now;
-  PHP_GRPC_MAKE_STD_ZVAL(now);
-  now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(now);
 }
 
@@ -217,13 +211,9 @@ PHP_METHOD(Timeval, now) {
  * @return Timeval Zero length time interval
  */
 PHP_METHOD(Timeval, zero) {
-  zval *grpc_php_timeval_zero;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_zero);
-  grpc_php_timeval_zero =
-      grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC);
-  RETURN_ZVAL(grpc_php_timeval_zero,
-              false, /* Copy original before returning? */
-              true /* Destroy original before returning */);
+  zval *grpc_php_timeval_zero =
+    grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  RETURN_DESTROY_ZVAL(grpc_php_timeval_zero);
 }
 
 /**
@@ -231,10 +221,8 @@ PHP_METHOD(Timeval, zero) {
  * @return Timeval Infinite future time value
  */
 PHP_METHOD(Timeval, infFuture) {
-  zval *grpc_php_timeval_inf_future;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_future);
-  grpc_php_timeval_inf_future =
-      grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *grpc_php_timeval_inf_future =
+    grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future);
 }
 
@@ -243,10 +231,8 @@ PHP_METHOD(Timeval, infFuture) {
  * @return Timeval Infinite past time value
  */
 PHP_METHOD(Timeval, infPast) {
-  zval *grpc_php_timeval_inf_past;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_past);
-  grpc_php_timeval_inf_past =
-      grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *grpc_php_timeval_inf_past =
+    grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past);
 }
 
-- 
GitLab


From bf07d75311b5b5a988913572853ec6dc75cd07c0 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Tue, 10 Jan 2017 11:03:46 -0800
Subject: [PATCH 258/344] Ran generate_projects.sh

---
 tools/doxygen/Doxyfile.c++           | 38 ++++++++++++------------
 tools/doxygen/Doxyfile.c++.internal  | 36 +++++++++++------------
 tools/doxygen/Doxyfile.core          | 34 ++++++++++-----------
 tools/doxygen/Doxyfile.core.internal | 44 ++++++++++++++--------------
 4 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 6539f96565..eef7ff4d5d 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -848,34 +848,34 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
 doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
 doc/compression.md \
+doc/c-style-guide.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
 doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
 doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
+doc/connectivity-semantics-and-api.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
 doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
-doc/cpp/perf_notes.md
+doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ffef534fe2..e8c47237ca 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -894,34 +894,34 @@ src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
 src/cpp/codegen/codegen_init.cc \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
 doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
 doc/compression.md \
+doc/c-style-guide.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
 doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
 doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
+doc/connectivity-semantics-and-api.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
 doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
 doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md \
 src/cpp/README.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index f8a3970416..92b57610dc 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -826,32 +826,32 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
 doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
 doc/compression.md \
+doc/c-style-guide.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
 doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
 doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
+doc/connectivity-semantics-and-api.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
 doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 1a945bec49..04acd4ff1e 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1281,41 +1281,39 @@ src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/wait-for-ready.md \
 doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
 doc/compression.md \
+doc/c-style-guide.md \
+doc/PROTOCOL-WEB.md \
+doc/cpp-style-guide.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/interop-test-descriptions.md \
+doc/PROTOCOL-HTTP2.md \
 doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
 doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
+doc/connectivity-semantics-and-api.md \
 doc/load-balancing.md \
+doc/environment_variables.md \
 doc/naming.md \
+doc/stress_test_framework.md \
+doc/http-grpc-status-mapping.md \
+doc/health-checking.md \
+doc/connection-backoff-interop-test-description.md \
 doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
+doc/command_line_tool.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
 doc/core/pending_api_cleanups.md \
 src/core/README.md \
 src/core/ext/README.md \
-src/core/ext/census/README.md \
-src/core/ext/census/gen/README.md \
-src/core/ext/client_channel/README.md \
 src/core/ext/resolver/README.md \
 src/core/ext/resolver/dns/native/README.md \
 src/core/ext/resolver/sockaddr/README.md \
+src/core/ext/client_channel/README.md \
 src/core/ext/transport/README.md \
 src/core/ext/transport/chttp2/README.md \
 src/core/ext/transport/chttp2/client/insecure/README.md \
@@ -1323,12 +1321,14 @@ src/core/ext/transport/chttp2/client/secure/README.md \
 src/core/ext/transport/chttp2/server/insecure/README.md \
 src/core/ext/transport/chttp2/server/secure/README.md \
 src/core/ext/transport/chttp2/transport/README.md \
+src/core/ext/census/README.md \
+src/core/ext/census/gen/README.md \
 src/core/lib/README.md \
-src/core/lib/channel/README.md \
 src/core/lib/iomgr/README.md \
+src/core/lib/tsi/README.md \
 src/core/lib/surface/README.md \
 src/core/lib/transport/README.md \
-src/core/lib/tsi/README.md
+src/core/lib/channel/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From d70c8bb871c68d8d8fd96660236c96e48d71c00a Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 11:58:40 -0800
Subject: [PATCH 259/344] Implement wait-for-ready behavior in Python stress
 and qps client

The clients now block until the channel is in the READY state. This
fixes some test flakiness issues we have had.
---
 src/python/grpcio_tests/tests/qps/benchmark_client.py | 8 ++------
 src/python/grpcio_tests/tests/stress/client.py        | 9 ++++++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py
index 83b46c914e..650e4756e7 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_client.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py
@@ -68,12 +68,8 @@ class BenchmarkClient:
     else:
       channel = grpc.insecure_channel(server)
 
-    connected_event = threading.Event()
-    def wait_for_ready(connectivity):
-      if connectivity == grpc.ChannelConnectivity.READY:
-        connected_event.set()
-    channel.subscribe(wait_for_ready, try_to_connect=True)
-    connected_event.wait()
+    # waits for the channel to be ready before we start sending messages
+    grpc.channel_ready_future(channel).result()
 
     if config.payload_config.WhichOneof('payload') == 'simple_params':
       self._generic = False
diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py
index 390ea13021..b8116729b5 100644
--- a/src/python/grpcio_tests/tests/stress/client.py
+++ b/src/python/grpcio_tests/tests/stress/client.py
@@ -110,10 +110,13 @@ def _get_channel(target, args):
     channel_credentials = grpc.ssl_channel_credentials(
         root_certificates=root_certificates)
     options = (('grpc.ssl_target_name_override', args.server_host_override,),)
-    return grpc.secure_channel(
-        target, channel_credentials, options=options)
+    channel = grpc.secure_channel(target, channel_credentials, options=options)
   else:
-    return grpc.insecure_channel(target)
+    channel = grpc.insecure_channel(target)
+
+  # waits for the channel to be ready before we start sending messages
+  grpc.channel_ready_future(channel).result()
+  return channel
 
 def run_test(args):
   test_cases = _parse_weighted_test_cases(args.test_cases)
-- 
GitLab


From aa272bcf7b573a84e171ee7c01bf2ad13d47fb25 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 10 Jan 2017 12:48:52 -0800
Subject: [PATCH 260/344] Always sort code generated outputs

---
 templates/tools/doxygen/Doxyfile.include |   4 +-
 tools/doxygen/Doxyfile.c++               | 130 ++--
 tools/doxygen/Doxyfile.c++.internal      | 168 ++---
 tools/doxygen/Doxyfile.core              | 104 +--
 tools/doxygen/Doxyfile.core.internal     | 772 +++++++++++------------
 5 files changed, 589 insertions(+), 589 deletions(-)

diff --git a/templates/tools/doxygen/Doxyfile.include b/templates/tools/doxygen/Doxyfile.include
index a22f07f33f..e26ae2b948 100644
--- a/templates/tools/doxygen/Doxyfile.include
+++ b/templates/tools/doxygen/Doxyfile.include
@@ -787,7 +787,7 @@ WARN_LOGFILE           =
 # Note: If this tag is empty the current directory is searched.
 
 INPUT                  = ${
-    ' \\\n'.join(
+    ' \\\n'.join(sorted(
         itertools.chain(
             itertools.chain.from_iterable(
     			      target.public_headers +
@@ -798,7 +798,7 @@ INPUT                  = ${
             glob.glob('doc/*.md'),
             glob.glob('doc/%s/*.md' % docpackage),
             [] if not internal else srcdoc)
-    )
+    ))
 }
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 6539f96565..fa9b7057c5 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -760,7 +760,35 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc++/alarm.h \
+INPUT                  = doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
+doc/binary-logging.md \
+doc/c-style-guide.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
+doc/connection-backoff-interop-test-description.md \
+doc/connection-backoff.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
+doc/load-balancing.md \
+doc/naming.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/server_reflection_tutorial.md \
+doc/statuscodes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+include/grpc++/alarm.h \
 include/grpc++/channel.h \
 include/grpc++/client_context.h \
 include/grpc++/completion_queue.h \
@@ -771,7 +799,35 @@ include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
+include/grpc++/impl/codegen/async_stream.h \
+include/grpc++/impl/codegen/async_unary_call.h \
+include/grpc++/impl/codegen/call.h \
+include/grpc++/impl/codegen/call_hook.h \
+include/grpc++/impl/codegen/channel_interface.h \
+include/grpc++/impl/codegen/client_context.h \
+include/grpc++/impl/codegen/client_unary_call.h \
+include/grpc++/impl/codegen/completion_queue.h \
+include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
 include/grpc++/impl/codegen/core_codegen.h \
+include/grpc++/impl/codegen/core_codegen_interface.h \
+include/grpc++/impl/codegen/create_auth_context.h \
+include/grpc++/impl/codegen/grpc_library.h \
+include/grpc++/impl/codegen/method_handler_impl.h \
+include/grpc++/impl/codegen/rpc_method.h \
+include/grpc++/impl/codegen/rpc_service_method.h \
+include/grpc++/impl/codegen/security/auth_context.h \
+include/grpc++/impl/codegen/serialization_traits.h \
+include/grpc++/impl/codegen/server_context.h \
+include/grpc++/impl/codegen/server_interface.h \
+include/grpc++/impl/codegen/service_type.h \
+include/grpc++/impl/codegen/status.h \
+include/grpc++/impl/codegen/status_code_enum.h \
+include/grpc++/impl/codegen/status_helper.h \
+include/grpc++/impl/codegen/string_ref.h \
+include/grpc++/impl/codegen/stub_options.h \
+include/grpc++/impl/codegen/sync_stream.h \
+include/grpc++/impl/codegen/time.h \
 include/grpc++/impl/grpc_library.h \
 include/grpc++/impl/method_handler_impl.h \
 include/grpc++/impl/rpc_method.h \
@@ -802,80 +858,24 @@ include/grpc++/support/string_ref.h \
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
-include/grpc++/impl/codegen/async_stream.h \
-include/grpc++/impl/codegen/async_unary_call.h \
-include/grpc++/impl/codegen/call.h \
-include/grpc++/impl/codegen/call_hook.h \
-include/grpc++/impl/codegen/channel_interface.h \
-include/grpc++/impl/codegen/client_context.h \
-include/grpc++/impl/codegen/client_unary_call.h \
-include/grpc++/impl/codegen/completion_queue.h \
-include/grpc++/impl/codegen/completion_queue_tag.h \
-include/grpc++/impl/codegen/config.h \
-include/grpc++/impl/codegen/core_codegen_interface.h \
-include/grpc++/impl/codegen/create_auth_context.h \
-include/grpc++/impl/codegen/grpc_library.h \
-include/grpc++/impl/codegen/method_handler_impl.h \
-include/grpc++/impl/codegen/rpc_method.h \
-include/grpc++/impl/codegen/rpc_service_method.h \
-include/grpc++/impl/codegen/security/auth_context.h \
-include/grpc++/impl/codegen/serialization_traits.h \
-include/grpc++/impl/codegen/server_context.h \
-include/grpc++/impl/codegen/server_interface.h \
-include/grpc++/impl/codegen/service_type.h \
-include/grpc++/impl/codegen/status.h \
-include/grpc++/impl/codegen/status_code_enum.h \
-include/grpc++/impl/codegen/status_helper.h \
-include/grpc++/impl/codegen/string_ref.h \
-include/grpc++/impl/codegen/stub_options.h \
-include/grpc++/impl/codegen/sync_stream.h \
-include/grpc++/impl/codegen/time.h \
-include/grpc/impl/codegen/byte_buffer_reader.h \
-include/grpc/impl/codegen/compression_types.h \
-include/grpc/impl/codegen/connectivity_state.h \
-include/grpc/impl/codegen/exec_ctx_fwd.h \
-include/grpc/impl/codegen/grpc_types.h \
-include/grpc/impl/codegen/propagation_bits.h \
-include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_windows.h \
-doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
-doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
-doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
-doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
-doc/cpp/perf_notes.md
+include/grpc/impl/codegen/sync_windows.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ffef534fe2..bca5652a46 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -760,7 +760,35 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc++/alarm.h \
+INPUT                  = doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
+doc/binary-logging.md \
+doc/c-style-guide.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
+doc/connection-backoff-interop-test-description.md \
+doc/connection-backoff.md \
+doc/connectivity-semantics-and-api.md \
+doc/cpp-style-guide.md \
+doc/cpp/pending_api_cleanups.md \
+doc/cpp/perf_notes.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
+doc/load-balancing.md \
+doc/naming.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/server_reflection_tutorial.md \
+doc/statuscodes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+include/grpc++/alarm.h \
 include/grpc++/channel.h \
 include/grpc++/client_context.h \
 include/grpc++/completion_queue.h \
@@ -771,7 +799,36 @@ include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
+include/grpc++/impl/codegen/async_stream.h \
+include/grpc++/impl/codegen/async_unary_call.h \
+include/grpc++/impl/codegen/call.h \
+include/grpc++/impl/codegen/call_hook.h \
+include/grpc++/impl/codegen/channel_interface.h \
+include/grpc++/impl/codegen/client_context.h \
+include/grpc++/impl/codegen/client_unary_call.h \
+include/grpc++/impl/codegen/completion_queue.h \
+include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/codegen/core_codegen.h \
+include/grpc++/impl/codegen/core_codegen_interface.h \
+include/grpc++/impl/codegen/create_auth_context.h \
+include/grpc++/impl/codegen/grpc_library.h \
+include/grpc++/impl/codegen/method_handler_impl.h \
+include/grpc++/impl/codegen/rpc_method.h \
+include/grpc++/impl/codegen/rpc_service_method.h \
+include/grpc++/impl/codegen/security/auth_context.h \
+include/grpc++/impl/codegen/serialization_traits.h \
+include/grpc++/impl/codegen/server_context.h \
+include/grpc++/impl/codegen/server_interface.h \
+include/grpc++/impl/codegen/service_type.h \
+include/grpc++/impl/codegen/status.h \
+include/grpc++/impl/codegen/status_code_enum.h \
+include/grpc++/impl/codegen/status_helper.h \
+include/grpc++/impl/codegen/string_ref.h \
+include/grpc++/impl/codegen/stub_options.h \
+include/grpc++/impl/codegen/sync_stream.h \
+include/grpc++/impl/codegen/time.h \
 include/grpc++/impl/grpc_library.h \
 include/grpc++/impl/method_handler_impl.h \
 include/grpc++/impl/rpc_method.h \
@@ -802,127 +859,70 @@ include/grpc++/support/string_ref.h \
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
-include/grpc++/impl/codegen/async_stream.h \
-include/grpc++/impl/codegen/async_unary_call.h \
-include/grpc++/impl/codegen/call.h \
-include/grpc++/impl/codegen/call_hook.h \
-include/grpc++/impl/codegen/channel_interface.h \
-include/grpc++/impl/codegen/client_context.h \
-include/grpc++/impl/codegen/client_unary_call.h \
-include/grpc++/impl/codegen/completion_queue.h \
-include/grpc++/impl/codegen/completion_queue_tag.h \
-include/grpc++/impl/codegen/config.h \
-include/grpc++/impl/codegen/core_codegen_interface.h \
-include/grpc++/impl/codegen/create_auth_context.h \
-include/grpc++/impl/codegen/grpc_library.h \
-include/grpc++/impl/codegen/method_handler_impl.h \
-include/grpc++/impl/codegen/rpc_method.h \
-include/grpc++/impl/codegen/rpc_service_method.h \
-include/grpc++/impl/codegen/security/auth_context.h \
-include/grpc++/impl/codegen/serialization_traits.h \
-include/grpc++/impl/codegen/server_context.h \
-include/grpc++/impl/codegen/server_interface.h \
-include/grpc++/impl/codegen/service_type.h \
-include/grpc++/impl/codegen/status.h \
-include/grpc++/impl/codegen/status_code_enum.h \
-include/grpc++/impl/codegen/status_helper.h \
-include/grpc++/impl/codegen/string_ref.h \
-include/grpc++/impl/codegen/stub_options.h \
-include/grpc++/impl/codegen/sync_stream.h \
-include/grpc++/impl/codegen/time.h \
-include/grpc/impl/codegen/byte_buffer_reader.h \
-include/grpc/impl/codegen/compression_types.h \
-include/grpc/impl/codegen/connectivity_state.h \
-include/grpc/impl/codegen/exec_ctx_fwd.h \
-include/grpc/impl/codegen/grpc_types.h \
-include/grpc/impl/codegen/propagation_bits.h \
-include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-include/grpc++/impl/codegen/core_codegen.h \
-src/cpp/client/secure_credentials.h \
-src/cpp/common/secure_auth_context.h \
-src/cpp/server/secure_server_credentials.h \
-src/cpp/client/create_channel_internal.h \
-src/cpp/common/channel_filter.h \
-src/cpp/server/dynamic_thread_pool.h \
-src/cpp/server/thread_pool_interface.h \
-src/cpp/thread_manager/thread_manager.h \
-src/cpp/client/insecure_credentials.cc \
-src/cpp/client/secure_credentials.cc \
-src/cpp/common/auth_property_iterator.cc \
-src/cpp/common/secure_auth_context.cc \
-src/cpp/common/secure_channel_arguments.cc \
-src/cpp/common/secure_create_auth_context.cc \
-src/cpp/server/insecure_server_credentials.cc \
-src/cpp/server/secure_server_credentials.cc \
+src/cpp/README.md \
 src/cpp/client/channel_cc.cc \
 src/cpp/client/client_context.cc \
 src/cpp/client/create_channel.cc \
 src/cpp/client/create_channel_internal.cc \
+src/cpp/client/create_channel_internal.h \
 src/cpp/client/create_channel_posix.cc \
 src/cpp/client/credentials_cc.cc \
 src/cpp/client/generic_stub.cc \
+src/cpp/client/insecure_credentials.cc \
+src/cpp/client/secure_credentials.cc \
+src/cpp/client/secure_credentials.h \
+src/cpp/codegen/codegen_init.cc \
+src/cpp/common/auth_property_iterator.cc \
 src/cpp/common/channel_arguments.cc \
 src/cpp/common/channel_filter.cc \
+src/cpp/common/channel_filter.h \
 src/cpp/common/completion_queue_cc.cc \
 src/cpp/common/core_codegen.cc \
 src/cpp/common/resource_quota_cc.cc \
 src/cpp/common/rpc_method.cc \
+src/cpp/common/secure_auth_context.cc \
+src/cpp/common/secure_auth_context.h \
+src/cpp/common/secure_channel_arguments.cc \
+src/cpp/common/secure_create_auth_context.cc \
 src/cpp/common/version_cc.cc \
 src/cpp/server/async_generic_service.cc \
 src/cpp/server/create_default_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.cc \
+src/cpp/server/dynamic_thread_pool.h \
+src/cpp/server/insecure_server_credentials.cc \
+src/cpp/server/secure_server_credentials.cc \
+src/cpp/server/secure_server_credentials.h \
 src/cpp/server/server_builder.cc \
 src/cpp/server/server_cc.cc \
 src/cpp/server/server_context.cc \
 src/cpp/server/server_credentials.cc \
 src/cpp/server/server_posix.cc \
+src/cpp/server/thread_pool_interface.h \
 src/cpp/thread_manager/thread_manager.cc \
+src/cpp/thread_manager/thread_manager.h \
 src/cpp/util/byte_buffer_cc.cc \
 src/cpp/util/slice_cc.cc \
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
-src/cpp/util/time_cc.cc \
-src/cpp/codegen/codegen_init.cc \
-doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
-doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
-doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
-doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
-doc/cpp/perf_notes.md \
-src/cpp/README.md
+src/cpp/util/time_cc.cc
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index f8a3970416..ccbfe3a4e6 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -760,35 +760,73 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc/byte_buffer.h \
+INPUT                  = doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
+doc/binary-logging.md \
+doc/c-style-guide.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
+doc/connection-backoff-interop-test-description.md \
+doc/connection-backoff.md \
+doc/connectivity-semantics-and-api.md \
+doc/core/pending_api_cleanups.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
+doc/load-balancing.md \
+doc/naming.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/server_reflection_tutorial.md \
+doc/statuscodes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+include/grpc/byte_buffer.h \
 include/grpc/byte_buffer_reader.h \
+include/grpc/census.h \
 include/grpc/compression.h \
 include/grpc/grpc.h \
 include/grpc/grpc_posix.h \
+include/grpc/grpc_security.h \
 include/grpc/grpc_security_constants.h \
-include/grpc/slice.h \
-include/grpc/slice_buffer.h \
-include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer_reader.h \
-include/grpc/impl/codegen/compression_types.h \
-include/grpc/impl/codegen/connectivity_state.h \
-include/grpc/impl/codegen/exec_ctx_fwd.h \
-include/grpc/impl/codegen/grpc_types.h \
-include/grpc/impl/codegen/propagation_bits.h \
-include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/grpc_types.h \
+include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/propagation_bits.h \
+include/grpc/impl/codegen/slice.h \
 include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
+include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-include/grpc/grpc_security.h \
-include/grpc/census.h \
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/slice.h \
+include/grpc/slice_buffer.h \
+include/grpc/status.h \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
 include/grpc/support/atm_gcc_atomic.h \
@@ -814,45 +852,7 @@ include/grpc/support/tls.h \
 include/grpc/support/tls_gcc.h \
 include/grpc/support/tls_msvc.h \
 include/grpc/support/tls_pthread.h \
-include/grpc/support/useful.h \
-include/grpc/impl/codegen/atm.h \
-include/grpc/impl/codegen/atm_gcc_atomic.h \
-include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/gpr_types.h \
-include/grpc/impl/codegen/port_platform.h \
-include/grpc/impl/codegen/slice.h \
-include/grpc/impl/codegen/sync.h \
-include/grpc/impl/codegen/sync_generic.h \
-include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_windows.h \
-doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
-doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
-doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
-doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/core/pending_api_cleanups.md
+include/grpc/support/useful.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 1a945bec49..fc8fac32f0 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -760,493 +760,461 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc/byte_buffer.h \
+INPUT                  = doc/PROTOCOL-HTTP2.md \
+doc/PROTOCOL-WEB.md \
+doc/binary-logging.md \
+doc/c-style-guide.md \
+doc/command_line_tool.md \
+doc/compression.md \
+doc/compression_cookbook.md \
+doc/connection-backoff-interop-test-description.md \
+doc/connection-backoff.md \
+doc/connectivity-semantics-and-api.md \
+doc/core/pending_api_cleanups.md \
+doc/cpp-style-guide.md \
+doc/environment_variables.md \
+doc/epoll-polling-engine.md \
+doc/fail_fast.md \
+doc/g_stands_for.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
+doc/interop-test-descriptions.md \
+doc/load-balancing.md \
+doc/naming.md \
+doc/negative-http2-interop-test-descriptions.md \
+doc/server-reflection.md \
+doc/server_reflection_tutorial.md \
+doc/statuscodes.md \
+doc/stress_test_framework.md \
+doc/wait-for-ready.md \
+include/grpc/byte_buffer.h \
 include/grpc/byte_buffer_reader.h \
+include/grpc/census.h \
 include/grpc/compression.h \
 include/grpc/grpc.h \
 include/grpc/grpc_posix.h \
+include/grpc/grpc_security.h \
 include/grpc/grpc_security_constants.h \
-include/grpc/slice.h \
-include/grpc/slice_buffer.h \
-include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer_reader.h \
-include/grpc/impl/codegen/compression_types.h \
-include/grpc/impl/codegen/connectivity_state.h \
-include/grpc/impl/codegen/exec_ctx_fwd.h \
-include/grpc/impl/codegen/grpc_types.h \
-include/grpc/impl/codegen/propagation_bits.h \
-include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/gpr_types.h \
+include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/status.h \
 include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
+include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
-include/grpc/grpc_security.h \
-include/grpc/census.h \
-src/core/lib/channel/channel_args.h \
-src/core/lib/channel/channel_stack.h \
-src/core/lib/channel/channel_stack_builder.h \
-src/core/lib/channel/compress_filter.h \
-src/core/lib/channel/connected_channel.h \
-src/core/lib/channel/context.h \
-src/core/lib/channel/deadline_filter.h \
-src/core/lib/channel/handshaker.h \
-src/core/lib/channel/handshaker_factory.h \
-src/core/lib/channel/handshaker_registry.h \
-src/core/lib/channel/http_client_filter.h \
-src/core/lib/channel/http_server_filter.h \
-src/core/lib/channel/message_size_filter.h \
-src/core/lib/compression/algorithm_metadata.h \
-src/core/lib/compression/message_compress.h \
-src/core/lib/debug/trace.h \
-src/core/lib/http/format_request.h \
-src/core/lib/http/httpcli.h \
-src/core/lib/http/parser.h \
-src/core/lib/iomgr/closure.h \
-src/core/lib/iomgr/combiner.h \
-src/core/lib/iomgr/endpoint.h \
-src/core/lib/iomgr/endpoint_pair.h \
-src/core/lib/iomgr/error.h \
-src/core/lib/iomgr/ev_epoll_linux.h \
-src/core/lib/iomgr/ev_poll_posix.h \
-src/core/lib/iomgr/ev_posix.h \
-src/core/lib/iomgr/exec_ctx.h \
-src/core/lib/iomgr/executor.h \
-src/core/lib/iomgr/iocp_windows.h \
-src/core/lib/iomgr/iomgr.h \
-src/core/lib/iomgr/iomgr_internal.h \
-src/core/lib/iomgr/iomgr_posix.h \
-src/core/lib/iomgr/load_file.h \
-src/core/lib/iomgr/network_status_tracker.h \
-src/core/lib/iomgr/polling_entity.h \
-src/core/lib/iomgr/pollset.h \
-src/core/lib/iomgr/pollset_set.h \
-src/core/lib/iomgr/pollset_set_windows.h \
-src/core/lib/iomgr/pollset_uv.h \
-src/core/lib/iomgr/pollset_windows.h \
-src/core/lib/iomgr/port.h \
-src/core/lib/iomgr/resolve_address.h \
-src/core/lib/iomgr/resource_quota.h \
-src/core/lib/iomgr/sockaddr.h \
-src/core/lib/iomgr/sockaddr_posix.h \
-src/core/lib/iomgr/sockaddr_utils.h \
-src/core/lib/iomgr/sockaddr_windows.h \
-src/core/lib/iomgr/socket_mutator.h \
-src/core/lib/iomgr/socket_utils.h \
-src/core/lib/iomgr/socket_utils_posix.h \
-src/core/lib/iomgr/socket_windows.h \
-src/core/lib/iomgr/tcp_client.h \
-src/core/lib/iomgr/tcp_client_posix.h \
-src/core/lib/iomgr/tcp_posix.h \
-src/core/lib/iomgr/tcp_server.h \
-src/core/lib/iomgr/tcp_uv.h \
-src/core/lib/iomgr/tcp_windows.h \
-src/core/lib/iomgr/time_averaged_stats.h \
-src/core/lib/iomgr/timer.h \
-src/core/lib/iomgr/timer_generic.h \
-src/core/lib/iomgr/timer_heap.h \
-src/core/lib/iomgr/timer_uv.h \
-src/core/lib/iomgr/udp_server.h \
-src/core/lib/iomgr/unix_sockets_posix.h \
-src/core/lib/iomgr/wakeup_fd_cv.h \
-src/core/lib/iomgr/wakeup_fd_pipe.h \
-src/core/lib/iomgr/wakeup_fd_posix.h \
-src/core/lib/iomgr/workqueue.h \
-src/core/lib/iomgr/workqueue_uv.h \
-src/core/lib/iomgr/workqueue_windows.h \
-src/core/lib/json/json.h \
-src/core/lib/json/json_common.h \
-src/core/lib/json/json_reader.h \
-src/core/lib/json/json_writer.h \
-src/core/lib/slice/percent_encoding.h \
-src/core/lib/slice/slice_internal.h \
-src/core/lib/slice/slice_string_helpers.h \
-src/core/lib/surface/api_trace.h \
-src/core/lib/surface/call.h \
-src/core/lib/surface/call_test_only.h \
-src/core/lib/surface/channel.h \
-src/core/lib/surface/channel_init.h \
-src/core/lib/surface/channel_stack_type.h \
-src/core/lib/surface/completion_queue.h \
-src/core/lib/surface/event_string.h \
-src/core/lib/surface/init.h \
-src/core/lib/surface/lame_client.h \
-src/core/lib/surface/server.h \
-src/core/lib/transport/byte_stream.h \
-src/core/lib/transport/connectivity_state.h \
-src/core/lib/transport/mdstr_hash_table.h \
-src/core/lib/transport/metadata.h \
-src/core/lib/transport/metadata_batch.h \
-src/core/lib/transport/pid_controller.h \
-src/core/lib/transport/service_config.h \
-src/core/lib/transport/static_metadata.h \
-src/core/lib/transport/timeout_encoding.h \
-src/core/lib/transport/transport.h \
-src/core/lib/transport/transport_impl.h \
-src/core/ext/transport/chttp2/transport/bin_decoder.h \
-src/core/ext/transport/chttp2/transport/bin_encoder.h \
-src/core/ext/transport/chttp2/transport/chttp2_transport.h \
-src/core/ext/transport/chttp2/transport/frame.h \
-src/core/ext/transport/chttp2/transport/frame_data.h \
-src/core/ext/transport/chttp2/transport/frame_goaway.h \
-src/core/ext/transport/chttp2/transport/frame_ping.h \
-src/core/ext/transport/chttp2/transport/frame_rst_stream.h \
-src/core/ext/transport/chttp2/transport/frame_settings.h \
-src/core/ext/transport/chttp2/transport/frame_window_update.h \
-src/core/ext/transport/chttp2/transport/hpack_encoder.h \
-src/core/ext/transport/chttp2/transport/hpack_parser.h \
-src/core/ext/transport/chttp2/transport/hpack_table.h \
-src/core/ext/transport/chttp2/transport/http2_errors.h \
-src/core/ext/transport/chttp2/transport/huffsyms.h \
-src/core/ext/transport/chttp2/transport/incoming_metadata.h \
-src/core/ext/transport/chttp2/transport/internal.h \
-src/core/ext/transport/chttp2/transport/status_conversion.h \
-src/core/ext/transport/chttp2/transport/stream_map.h \
-src/core/ext/transport/chttp2/transport/varint.h \
-src/core/ext/transport/chttp2/alpn/alpn.h \
-src/core/lib/security/context/security_context.h \
-src/core/lib/security/credentials/composite/composite_credentials.h \
-src/core/lib/security/credentials/credentials.h \
-src/core/lib/security/credentials/fake/fake_credentials.h \
-src/core/lib/security/credentials/google_default/google_default_credentials.h \
-src/core/lib/security/credentials/iam/iam_credentials.h \
-src/core/lib/security/credentials/jwt/json_token.h \
-src/core/lib/security/credentials/jwt/jwt_credentials.h \
-src/core/lib/security/credentials/jwt/jwt_verifier.h \
-src/core/lib/security/credentials/oauth2/oauth2_credentials.h \
-src/core/lib/security/credentials/plugin/plugin_credentials.h \
-src/core/lib/security/credentials/ssl/ssl_credentials.h \
-src/core/lib/security/transport/auth_filters.h \
-src/core/lib/security/transport/secure_endpoint.h \
-src/core/lib/security/transport/security_connector.h \
-src/core/lib/security/transport/security_handshaker.h \
-src/core/lib/security/transport/tsi_error.h \
-src/core/lib/security/util/b64.h \
-src/core/lib/security/util/json_util.h \
-src/core/lib/tsi/fake_transport_security.h \
-src/core/lib/tsi/ssl_transport_security.h \
-src/core/lib/tsi/ssl_types.h \
-src/core/lib/tsi/transport_security.h \
-src/core/lib/tsi/transport_security_interface.h \
-src/core/ext/transport/chttp2/server/chttp2_server.h \
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/slice.h \
+include/grpc/slice_buffer.h \
+include/grpc/status.h \
+include/grpc/support/alloc.h \
+include/grpc/support/atm.h \
+include/grpc/support/atm_gcc_atomic.h \
+include/grpc/support/atm_gcc_sync.h \
+include/grpc/support/atm_windows.h \
+include/grpc/support/avl.h \
+include/grpc/support/cmdline.h \
+include/grpc/support/cpu.h \
+include/grpc/support/histogram.h \
+include/grpc/support/host_port.h \
+include/grpc/support/log.h \
+include/grpc/support/log_windows.h \
+include/grpc/support/port_platform.h \
+include/grpc/support/string_util.h \
+include/grpc/support/subprocess.h \
+include/grpc/support/sync.h \
+include/grpc/support/sync_generic.h \
+include/grpc/support/sync_posix.h \
+include/grpc/support/sync_windows.h \
+include/grpc/support/thd.h \
+include/grpc/support/time.h \
+include/grpc/support/tls.h \
+include/grpc/support/tls_gcc.h \
+include/grpc/support/tls_msvc.h \
+include/grpc/support/tls_pthread.h \
+include/grpc/support/useful.h \
+src/core/README.md \
+src/core/ext/README.md \
+src/core/ext/census/README.md \
+src/core/ext/census/aggregation.h \
+src/core/ext/census/base_resources.c \
+src/core/ext/census/base_resources.h \
+src/core/ext/census/census_interface.h \
+src/core/ext/census/census_rpc_stats.h \
+src/core/ext/census/context.c \
+src/core/ext/census/gen/README.md \
+src/core/ext/census/gen/census.pb.c \
+src/core/ext/census/gen/census.pb.h \
+src/core/ext/census/gen/trace_context.pb.c \
+src/core/ext/census/gen/trace_context.pb.h \
+src/core/ext/census/grpc_context.c \
+src/core/ext/census/grpc_filter.c \
+src/core/ext/census/grpc_filter.h \
+src/core/ext/census/grpc_plugin.c \
+src/core/ext/census/initialize.c \
+src/core/ext/census/mlog.c \
+src/core/ext/census/mlog.h \
+src/core/ext/census/operation.c \
+src/core/ext/census/placeholders.c \
+src/core/ext/census/resource.c \
+src/core/ext/census/resource.h \
+src/core/ext/census/rpc_metric_id.h \
+src/core/ext/census/trace_context.c \
+src/core/ext/census/trace_context.h \
+src/core/ext/census/tracing.c \
+src/core/ext/client_channel/README.md \
+src/core/ext/client_channel/channel_connectivity.c \
+src/core/ext/client_channel/client_channel.c \
 src/core/ext/client_channel/client_channel.h \
+src/core/ext/client_channel/client_channel_factory.c \
 src/core/ext/client_channel/client_channel_factory.h \
+src/core/ext/client_channel/client_channel_plugin.c \
+src/core/ext/client_channel/connector.c \
 src/core/ext/client_channel/connector.h \
+src/core/ext/client_channel/default_initial_connect_string.c \
+src/core/ext/client_channel/http_connect_handshaker.c \
 src/core/ext/client_channel/http_connect_handshaker.h \
+src/core/ext/client_channel/initial_connect_string.c \
 src/core/ext/client_channel/initial_connect_string.h \
+src/core/ext/client_channel/lb_policy.c \
 src/core/ext/client_channel/lb_policy.h \
+src/core/ext/client_channel/lb_policy_factory.c \
 src/core/ext/client_channel/lb_policy_factory.h \
+src/core/ext/client_channel/lb_policy_registry.c \
 src/core/ext/client_channel/lb_policy_registry.h \
+src/core/ext/client_channel/parse_address.c \
 src/core/ext/client_channel/parse_address.h \
+src/core/ext/client_channel/resolver.c \
 src/core/ext/client_channel/resolver.h \
+src/core/ext/client_channel/resolver_factory.c \
 src/core/ext/client_channel/resolver_factory.h \
+src/core/ext/client_channel/resolver_registry.c \
 src/core/ext/client_channel/resolver_registry.h \
+src/core/ext/client_channel/subchannel.c \
 src/core/ext/client_channel/subchannel.h \
+src/core/ext/client_channel/subchannel_index.c \
 src/core/ext/client_channel/subchannel_index.h \
+src/core/ext/client_channel/uri_parser.c \
 src/core/ext/client_channel/uri_parser.h \
-src/core/ext/transport/chttp2/client/chttp2_connector.h \
+src/core/ext/lb_policy/grpclb/grpclb.c \
 src/core/ext/lb_policy/grpclb/grpclb.h \
+src/core/ext/lb_policy/grpclb/load_balancer_api.c \
 src/core/ext/lb_policy/grpclb/load_balancer_api.h \
+src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
 src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
-third_party/nanopb/pb.h \
-third_party/nanopb/pb_common.h \
-third_party/nanopb/pb_decode.h \
-third_party/nanopb/pb_encode.h \
+src/core/ext/lb_policy/pick_first/pick_first.c \
+src/core/ext/lb_policy/round_robin/round_robin.c \
+src/core/ext/load_reporting/load_reporting.c \
 src/core/ext/load_reporting/load_reporting.h \
+src/core/ext/load_reporting/load_reporting_filter.c \
 src/core/ext/load_reporting/load_reporting_filter.h \
-src/core/ext/census/aggregation.h \
-src/core/ext/census/base_resources.h \
-src/core/ext/census/census_interface.h \
-src/core/ext/census/census_rpc_stats.h \
-src/core/ext/census/gen/census.pb.h \
-src/core/ext/census/gen/trace_context.pb.h \
-src/core/ext/census/grpc_filter.h \
-src/core/ext/census/mlog.h \
-src/core/ext/census/resource.h \
-src/core/ext/census/rpc_metric_id.h \
-src/core/ext/census/trace_context.h \
-src/core/lib/surface/init.c \
+src/core/ext/resolver/README.md \
+src/core/ext/resolver/dns/native/README.md \
+src/core/ext/resolver/dns/native/dns_resolver.c \
+src/core/ext/resolver/sockaddr/README.md \
+src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+src/core/ext/transport/README.md \
+src/core/ext/transport/chttp2/README.md \
+src/core/ext/transport/chttp2/alpn/alpn.c \
+src/core/ext/transport/chttp2/alpn/alpn.h \
+src/core/ext/transport/chttp2/client/chttp2_connector.c \
+src/core/ext/transport/chttp2/client/chttp2_connector.h \
+src/core/ext/transport/chttp2/client/insecure/README.md \
+src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
+src/core/ext/transport/chttp2/client/secure/README.md \
+src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
+src/core/ext/transport/chttp2/server/chttp2_server.c \
+src/core/ext/transport/chttp2/server/chttp2_server.h \
+src/core/ext/transport/chttp2/server/insecure/README.md \
+src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \
+src/core/ext/transport/chttp2/transport/README.md \
+src/core/ext/transport/chttp2/transport/bin_decoder.c \
+src/core/ext/transport/chttp2/transport/bin_decoder.h \
+src/core/ext/transport/chttp2/transport/bin_encoder.c \
+src/core/ext/transport/chttp2/transport/bin_encoder.h \
+src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
+src/core/ext/transport/chttp2/transport/chttp2_transport.c \
+src/core/ext/transport/chttp2/transport/chttp2_transport.h \
+src/core/ext/transport/chttp2/transport/frame.h \
+src/core/ext/transport/chttp2/transport/frame_data.c \
+src/core/ext/transport/chttp2/transport/frame_data.h \
+src/core/ext/transport/chttp2/transport/frame_goaway.c \
+src/core/ext/transport/chttp2/transport/frame_goaway.h \
+src/core/ext/transport/chttp2/transport/frame_ping.c \
+src/core/ext/transport/chttp2/transport/frame_ping.h \
+src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
+src/core/ext/transport/chttp2/transport/frame_rst_stream.h \
+src/core/ext/transport/chttp2/transport/frame_settings.c \
+src/core/ext/transport/chttp2/transport/frame_settings.h \
+src/core/ext/transport/chttp2/transport/frame_window_update.c \
+src/core/ext/transport/chttp2/transport/frame_window_update.h \
+src/core/ext/transport/chttp2/transport/hpack_encoder.c \
+src/core/ext/transport/chttp2/transport/hpack_encoder.h \
+src/core/ext/transport/chttp2/transport/hpack_parser.c \
+src/core/ext/transport/chttp2/transport/hpack_parser.h \
+src/core/ext/transport/chttp2/transport/hpack_table.c \
+src/core/ext/transport/chttp2/transport/hpack_table.h \
+src/core/ext/transport/chttp2/transport/http2_errors.h \
+src/core/ext/transport/chttp2/transport/huffsyms.c \
+src/core/ext/transport/chttp2/transport/huffsyms.h \
+src/core/ext/transport/chttp2/transport/incoming_metadata.c \
+src/core/ext/transport/chttp2/transport/incoming_metadata.h \
+src/core/ext/transport/chttp2/transport/internal.h \
+src/core/ext/transport/chttp2/transport/parsing.c \
+src/core/ext/transport/chttp2/transport/status_conversion.c \
+src/core/ext/transport/chttp2/transport/status_conversion.h \
+src/core/ext/transport/chttp2/transport/stream_lists.c \
+src/core/ext/transport/chttp2/transport/stream_map.c \
+src/core/ext/transport/chttp2/transport/stream_map.h \
+src/core/ext/transport/chttp2/transport/varint.c \
+src/core/ext/transport/chttp2/transport/varint.h \
+src/core/ext/transport/chttp2/transport/writing.c \
+src/core/lib/README.md \
+src/core/lib/channel/README.md \
 src/core/lib/channel/channel_args.c \
+src/core/lib/channel/channel_args.h \
 src/core/lib/channel/channel_stack.c \
+src/core/lib/channel/channel_stack.h \
 src/core/lib/channel/channel_stack_builder.c \
+src/core/lib/channel/channel_stack_builder.h \
 src/core/lib/channel/compress_filter.c \
+src/core/lib/channel/compress_filter.h \
 src/core/lib/channel/connected_channel.c \
+src/core/lib/channel/connected_channel.h \
+src/core/lib/channel/context.h \
 src/core/lib/channel/deadline_filter.c \
+src/core/lib/channel/deadline_filter.h \
 src/core/lib/channel/handshaker.c \
+src/core/lib/channel/handshaker.h \
 src/core/lib/channel/handshaker_factory.c \
+src/core/lib/channel/handshaker_factory.h \
 src/core/lib/channel/handshaker_registry.c \
+src/core/lib/channel/handshaker_registry.h \
 src/core/lib/channel/http_client_filter.c \
+src/core/lib/channel/http_client_filter.h \
 src/core/lib/channel/http_server_filter.c \
+src/core/lib/channel/http_server_filter.h \
 src/core/lib/channel/message_size_filter.c \
+src/core/lib/channel/message_size_filter.h \
+src/core/lib/compression/algorithm_metadata.h \
 src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
+src/core/lib/compression/message_compress.h \
 src/core/lib/debug/trace.c \
+src/core/lib/debug/trace.h \
 src/core/lib/http/format_request.c \
+src/core/lib/http/format_request.h \
 src/core/lib/http/httpcli.c \
+src/core/lib/http/httpcli.h \
+src/core/lib/http/httpcli_security_connector.c \
 src/core/lib/http/parser.c \
+src/core/lib/http/parser.h \
+src/core/lib/iomgr/README.md \
 src/core/lib/iomgr/closure.c \
+src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/combiner.c \
+src/core/lib/iomgr/combiner.h \
 src/core/lib/iomgr/endpoint.c \
+src/core/lib/iomgr/endpoint.h \
+src/core/lib/iomgr/endpoint_pair.h \
 src/core/lib/iomgr/endpoint_pair_posix.c \
 src/core/lib/iomgr/endpoint_pair_uv.c \
 src/core/lib/iomgr/endpoint_pair_windows.c \
 src/core/lib/iomgr/error.c \
+src/core/lib/iomgr/error.h \
 src/core/lib/iomgr/ev_epoll_linux.c \
+src/core/lib/iomgr/ev_epoll_linux.h \
 src/core/lib/iomgr/ev_poll_posix.c \
+src/core/lib/iomgr/ev_poll_posix.h \
 src/core/lib/iomgr/ev_posix.c \
+src/core/lib/iomgr/ev_posix.h \
 src/core/lib/iomgr/exec_ctx.c \
+src/core/lib/iomgr/exec_ctx.h \
 src/core/lib/iomgr/executor.c \
+src/core/lib/iomgr/executor.h \
 src/core/lib/iomgr/iocp_windows.c \
+src/core/lib/iomgr/iocp_windows.h \
 src/core/lib/iomgr/iomgr.c \
+src/core/lib/iomgr/iomgr.h \
+src/core/lib/iomgr/iomgr_internal.h \
 src/core/lib/iomgr/iomgr_posix.c \
+src/core/lib/iomgr/iomgr_posix.h \
 src/core/lib/iomgr/iomgr_uv.c \
 src/core/lib/iomgr/iomgr_windows.c \
 src/core/lib/iomgr/load_file.c \
+src/core/lib/iomgr/load_file.h \
 src/core/lib/iomgr/network_status_tracker.c \
+src/core/lib/iomgr/network_status_tracker.h \
 src/core/lib/iomgr/polling_entity.c \
+src/core/lib/iomgr/polling_entity.h \
+src/core/lib/iomgr/pollset.h \
+src/core/lib/iomgr/pollset_set.h \
 src/core/lib/iomgr/pollset_set_uv.c \
 src/core/lib/iomgr/pollset_set_windows.c \
+src/core/lib/iomgr/pollset_set_windows.h \
 src/core/lib/iomgr/pollset_uv.c \
+src/core/lib/iomgr/pollset_uv.h \
 src/core/lib/iomgr/pollset_windows.c \
+src/core/lib/iomgr/pollset_windows.h \
+src/core/lib/iomgr/port.h \
+src/core/lib/iomgr/resolve_address.h \
 src/core/lib/iomgr/resolve_address_posix.c \
 src/core/lib/iomgr/resolve_address_uv.c \
 src/core/lib/iomgr/resolve_address_windows.c \
 src/core/lib/iomgr/resource_quota.c \
+src/core/lib/iomgr/resource_quota.h \
+src/core/lib/iomgr/sockaddr.h \
+src/core/lib/iomgr/sockaddr_posix.h \
 src/core/lib/iomgr/sockaddr_utils.c \
+src/core/lib/iomgr/sockaddr_utils.h \
+src/core/lib/iomgr/sockaddr_windows.h \
 src/core/lib/iomgr/socket_mutator.c \
+src/core/lib/iomgr/socket_mutator.h \
+src/core/lib/iomgr/socket_utils.h \
 src/core/lib/iomgr/socket_utils_common_posix.c \
 src/core/lib/iomgr/socket_utils_linux.c \
 src/core/lib/iomgr/socket_utils_posix.c \
+src/core/lib/iomgr/socket_utils_posix.h \
 src/core/lib/iomgr/socket_utils_uv.c \
 src/core/lib/iomgr/socket_utils_windows.c \
 src/core/lib/iomgr/socket_windows.c \
+src/core/lib/iomgr/socket_windows.h \
+src/core/lib/iomgr/tcp_client.h \
 src/core/lib/iomgr/tcp_client_posix.c \
+src/core/lib/iomgr/tcp_client_posix.h \
 src/core/lib/iomgr/tcp_client_uv.c \
 src/core/lib/iomgr/tcp_client_windows.c \
 src/core/lib/iomgr/tcp_posix.c \
+src/core/lib/iomgr/tcp_posix.h \
+src/core/lib/iomgr/tcp_server.h \
 src/core/lib/iomgr/tcp_server_posix.c \
 src/core/lib/iomgr/tcp_server_uv.c \
 src/core/lib/iomgr/tcp_server_windows.c \
 src/core/lib/iomgr/tcp_uv.c \
+src/core/lib/iomgr/tcp_uv.h \
 src/core/lib/iomgr/tcp_windows.c \
+src/core/lib/iomgr/tcp_windows.h \
 src/core/lib/iomgr/time_averaged_stats.c \
+src/core/lib/iomgr/time_averaged_stats.h \
+src/core/lib/iomgr/timer.h \
 src/core/lib/iomgr/timer_generic.c \
+src/core/lib/iomgr/timer_generic.h \
 src/core/lib/iomgr/timer_heap.c \
+src/core/lib/iomgr/timer_heap.h \
 src/core/lib/iomgr/timer_uv.c \
+src/core/lib/iomgr/timer_uv.h \
 src/core/lib/iomgr/udp_server.c \
+src/core/lib/iomgr/udp_server.h \
 src/core/lib/iomgr/unix_sockets_posix.c \
+src/core/lib/iomgr/unix_sockets_posix.h \
 src/core/lib/iomgr/unix_sockets_posix_noop.c \
 src/core/lib/iomgr/wakeup_fd_cv.c \
+src/core/lib/iomgr/wakeup_fd_cv.h \
 src/core/lib/iomgr/wakeup_fd_eventfd.c \
 src/core/lib/iomgr/wakeup_fd_nospecial.c \
 src/core/lib/iomgr/wakeup_fd_pipe.c \
+src/core/lib/iomgr/wakeup_fd_pipe.h \
 src/core/lib/iomgr/wakeup_fd_posix.c \
+src/core/lib/iomgr/wakeup_fd_posix.h \
+src/core/lib/iomgr/workqueue.h \
 src/core/lib/iomgr/workqueue_uv.c \
+src/core/lib/iomgr/workqueue_uv.h \
 src/core/lib/iomgr/workqueue_windows.c \
+src/core/lib/iomgr/workqueue_windows.h \
 src/core/lib/json/json.c \
+src/core/lib/json/json.h \
+src/core/lib/json/json_common.h \
 src/core/lib/json/json_reader.c \
+src/core/lib/json/json_reader.h \
 src/core/lib/json/json_string.c \
 src/core/lib/json/json_writer.c \
-src/core/lib/slice/percent_encoding.c \
-src/core/lib/slice/slice.c \
-src/core/lib/slice/slice_buffer.c \
-src/core/lib/slice/slice_string_helpers.c \
-src/core/lib/surface/alarm.c \
-src/core/lib/surface/api_trace.c \
-src/core/lib/surface/byte_buffer.c \
-src/core/lib/surface/byte_buffer_reader.c \
-src/core/lib/surface/call.c \
-src/core/lib/surface/call_details.c \
-src/core/lib/surface/call_log_batch.c \
-src/core/lib/surface/channel.c \
-src/core/lib/surface/channel_init.c \
-src/core/lib/surface/channel_ping.c \
-src/core/lib/surface/channel_stack_type.c \
-src/core/lib/surface/completion_queue.c \
-src/core/lib/surface/event_string.c \
-src/core/lib/surface/lame_client.c \
-src/core/lib/surface/metadata_array.c \
-src/core/lib/surface/server.c \
-src/core/lib/surface/validate_metadata.c \
-src/core/lib/surface/version.c \
-src/core/lib/transport/byte_stream.c \
-src/core/lib/transport/connectivity_state.c \
-src/core/lib/transport/mdstr_hash_table.c \
-src/core/lib/transport/metadata.c \
-src/core/lib/transport/metadata_batch.c \
-src/core/lib/transport/pid_controller.c \
-src/core/lib/transport/service_config.c \
-src/core/lib/transport/static_metadata.c \
-src/core/lib/transport/timeout_encoding.c \
-src/core/lib/transport/transport.c \
-src/core/lib/transport/transport_op_string.c \
-src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \
-src/core/ext/transport/chttp2/transport/bin_decoder.c \
-src/core/ext/transport/chttp2/transport/bin_encoder.c \
-src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
-src/core/ext/transport/chttp2/transport/chttp2_transport.c \
-src/core/ext/transport/chttp2/transport/frame_data.c \
-src/core/ext/transport/chttp2/transport/frame_goaway.c \
-src/core/ext/transport/chttp2/transport/frame_ping.c \
-src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
-src/core/ext/transport/chttp2/transport/frame_settings.c \
-src/core/ext/transport/chttp2/transport/frame_window_update.c \
-src/core/ext/transport/chttp2/transport/hpack_encoder.c \
-src/core/ext/transport/chttp2/transport/hpack_parser.c \
-src/core/ext/transport/chttp2/transport/hpack_table.c \
-src/core/ext/transport/chttp2/transport/huffsyms.c \
-src/core/ext/transport/chttp2/transport/incoming_metadata.c \
-src/core/ext/transport/chttp2/transport/parsing.c \
-src/core/ext/transport/chttp2/transport/status_conversion.c \
-src/core/ext/transport/chttp2/transport/stream_lists.c \
-src/core/ext/transport/chttp2/transport/stream_map.c \
-src/core/ext/transport/chttp2/transport/varint.c \
-src/core/ext/transport/chttp2/transport/writing.c \
-src/core/ext/transport/chttp2/alpn/alpn.c \
-src/core/lib/http/httpcli_security_connector.c \
+src/core/lib/json/json_writer.h \
+src/core/lib/profiling/basic_timers.c \
+src/core/lib/profiling/stap_timers.c \
+src/core/lib/profiling/timers.h \
 src/core/lib/security/context/security_context.c \
+src/core/lib/security/context/security_context.h \
 src/core/lib/security/credentials/composite/composite_credentials.c \
+src/core/lib/security/credentials/composite/composite_credentials.h \
 src/core/lib/security/credentials/credentials.c \
+src/core/lib/security/credentials/credentials.h \
 src/core/lib/security/credentials/credentials_metadata.c \
 src/core/lib/security/credentials/fake/fake_credentials.c \
+src/core/lib/security/credentials/fake/fake_credentials.h \
 src/core/lib/security/credentials/google_default/credentials_generic.c \
 src/core/lib/security/credentials/google_default/google_default_credentials.c \
+src/core/lib/security/credentials/google_default/google_default_credentials.h \
 src/core/lib/security/credentials/iam/iam_credentials.c \
+src/core/lib/security/credentials/iam/iam_credentials.h \
 src/core/lib/security/credentials/jwt/json_token.c \
+src/core/lib/security/credentials/jwt/json_token.h \
 src/core/lib/security/credentials/jwt/jwt_credentials.c \
+src/core/lib/security/credentials/jwt/jwt_credentials.h \
 src/core/lib/security/credentials/jwt/jwt_verifier.c \
+src/core/lib/security/credentials/jwt/jwt_verifier.h \
 src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
+src/core/lib/security/credentials/oauth2/oauth2_credentials.h \
 src/core/lib/security/credentials/plugin/plugin_credentials.c \
+src/core/lib/security/credentials/plugin/plugin_credentials.h \
 src/core/lib/security/credentials/ssl/ssl_credentials.c \
+src/core/lib/security/credentials/ssl/ssl_credentials.h \
+src/core/lib/security/transport/auth_filters.h \
 src/core/lib/security/transport/client_auth_filter.c \
 src/core/lib/security/transport/secure_endpoint.c \
+src/core/lib/security/transport/secure_endpoint.h \
 src/core/lib/security/transport/security_connector.c \
+src/core/lib/security/transport/security_connector.h \
 src/core/lib/security/transport/security_handshaker.c \
+src/core/lib/security/transport/security_handshaker.h \
 src/core/lib/security/transport/server_auth_filter.c \
 src/core/lib/security/transport/tsi_error.c \
+src/core/lib/security/transport/tsi_error.h \
 src/core/lib/security/util/b64.c \
+src/core/lib/security/util/b64.h \
 src/core/lib/security/util/json_util.c \
-src/core/lib/surface/init_secure.c \
-src/core/lib/tsi/fake_transport_security.c \
-src/core/lib/tsi/ssl_transport_security.c \
-src/core/lib/tsi/transport_security.c \
-src/core/ext/transport/chttp2/server/chttp2_server.c \
-src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
-src/core/ext/client_channel/channel_connectivity.c \
-src/core/ext/client_channel/client_channel.c \
-src/core/ext/client_channel/client_channel_factory.c \
-src/core/ext/client_channel/client_channel_plugin.c \
-src/core/ext/client_channel/connector.c \
-src/core/ext/client_channel/default_initial_connect_string.c \
-src/core/ext/client_channel/http_connect_handshaker.c \
-src/core/ext/client_channel/initial_connect_string.c \
-src/core/ext/client_channel/lb_policy.c \
-src/core/ext/client_channel/lb_policy_factory.c \
-src/core/ext/client_channel/lb_policy_registry.c \
-src/core/ext/client_channel/parse_address.c \
-src/core/ext/client_channel/resolver.c \
-src/core/ext/client_channel/resolver_factory.c \
-src/core/ext/client_channel/resolver_registry.c \
-src/core/ext/client_channel/subchannel.c \
-src/core/ext/client_channel/subchannel_index.c \
-src/core/ext/client_channel/uri_parser.c \
-src/core/ext/transport/chttp2/client/chttp2_connector.c \
-src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
-src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
-src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
-src/core/ext/lb_policy/grpclb/grpclb.c \
-src/core/ext/lb_policy/grpclb/load_balancer_api.c \
-src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
-third_party/nanopb/pb_common.c \
-third_party/nanopb/pb_decode.c \
-third_party/nanopb/pb_encode.c \
-src/core/ext/lb_policy/pick_first/pick_first.c \
-src/core/ext/lb_policy/round_robin/round_robin.c \
-src/core/ext/resolver/dns/native/dns_resolver.c \
-src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
-src/core/ext/load_reporting/load_reporting.c \
-src/core/ext/load_reporting/load_reporting_filter.c \
-src/core/ext/census/base_resources.c \
-src/core/ext/census/context.c \
-src/core/ext/census/gen/census.pb.c \
-src/core/ext/census/gen/trace_context.pb.c \
-src/core/ext/census/grpc_context.c \
-src/core/ext/census/grpc_filter.c \
-src/core/ext/census/grpc_plugin.c \
-src/core/ext/census/initialize.c \
-src/core/ext/census/mlog.c \
-src/core/ext/census/operation.c \
-src/core/ext/census/placeholders.c \
-src/core/ext/census/resource.c \
-src/core/ext/census/trace_context.c \
-src/core/ext/census/tracing.c \
-src/core/plugin_registry/grpc_plugin_registry.c \
-include/grpc/support/alloc.h \
-include/grpc/support/atm.h \
-include/grpc/support/atm_gcc_atomic.h \
-include/grpc/support/atm_gcc_sync.h \
-include/grpc/support/atm_windows.h \
-include/grpc/support/avl.h \
-include/grpc/support/cmdline.h \
-include/grpc/support/cpu.h \
-include/grpc/support/histogram.h \
-include/grpc/support/host_port.h \
-include/grpc/support/log.h \
-include/grpc/support/log_windows.h \
-include/grpc/support/port_platform.h \
-include/grpc/support/string_util.h \
-include/grpc/support/subprocess.h \
-include/grpc/support/sync.h \
-include/grpc/support/sync_generic.h \
-include/grpc/support/sync_posix.h \
-include/grpc/support/sync_windows.h \
-include/grpc/support/thd.h \
-include/grpc/support/time.h \
-include/grpc/support/tls.h \
-include/grpc/support/tls_gcc.h \
-include/grpc/support/tls_msvc.h \
-include/grpc/support/tls_pthread.h \
-include/grpc/support/useful.h \
-include/grpc/impl/codegen/atm.h \
-include/grpc/impl/codegen/atm_gcc_atomic.h \
-include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/gpr_types.h \
-include/grpc/impl/codegen/port_platform.h \
-include/grpc/impl/codegen/slice.h \
-include/grpc/impl/codegen/sync.h \
-include/grpc/impl/codegen/sync_generic.h \
-include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_windows.h \
-src/core/lib/profiling/timers.h \
-src/core/lib/support/backoff.h \
-src/core/lib/support/block_annotate.h \
-src/core/lib/support/env.h \
-src/core/lib/support/mpscq.h \
-src/core/lib/support/murmur_hash.h \
-src/core/lib/support/stack_lockfree.h \
-src/core/lib/support/string.h \
-src/core/lib/support/string_windows.h \
-src/core/lib/support/thd_internal.h \
-src/core/lib/support/time_precise.h \
-src/core/lib/support/tmpfile.h \
-src/core/lib/profiling/basic_timers.c \
-src/core/lib/profiling/stap_timers.c \
+src/core/lib/security/util/json_util.h \
+src/core/lib/slice/percent_encoding.c \
+src/core/lib/slice/percent_encoding.h \
+src/core/lib/slice/slice.c \
+src/core/lib/slice/slice_buffer.c \
+src/core/lib/slice/slice_internal.h \
+src/core/lib/slice/slice_string_helpers.c \
+src/core/lib/slice/slice_string_helpers.h \
 src/core/lib/support/alloc.c \
 src/core/lib/support/avl.c \
 src/core/lib/support/backoff.c \
+src/core/lib/support/backoff.h \
+src/core/lib/support/block_annotate.h \
 src/core/lib/support/cmdline.c \
 src/core/lib/support/cpu_iphone.c \
 src/core/lib/support/cpu_linux.c \
 src/core/lib/support/cpu_posix.c \
 src/core/lib/support/cpu_windows.c \
+src/core/lib/support/env.h \
 src/core/lib/support/env_linux.c \
 src/core/lib/support/env_posix.c \
 src/core/lib/support/env_windows.c \
@@ -1258,77 +1226,109 @@ src/core/lib/support/log_linux.c \
 src/core/lib/support/log_posix.c \
 src/core/lib/support/log_windows.c \
 src/core/lib/support/mpscq.c \
+src/core/lib/support/mpscq.h \
 src/core/lib/support/murmur_hash.c \
+src/core/lib/support/murmur_hash.h \
 src/core/lib/support/stack_lockfree.c \
+src/core/lib/support/stack_lockfree.h \
 src/core/lib/support/string.c \
+src/core/lib/support/string.h \
 src/core/lib/support/string_posix.c \
 src/core/lib/support/string_util_windows.c \
 src/core/lib/support/string_windows.c \
+src/core/lib/support/string_windows.h \
 src/core/lib/support/subprocess_posix.c \
 src/core/lib/support/subprocess_windows.c \
 src/core/lib/support/sync.c \
 src/core/lib/support/sync_posix.c \
 src/core/lib/support/sync_windows.c \
 src/core/lib/support/thd.c \
+src/core/lib/support/thd_internal.h \
 src/core/lib/support/thd_posix.c \
 src/core/lib/support/thd_windows.c \
 src/core/lib/support/time.c \
 src/core/lib/support/time_posix.c \
 src/core/lib/support/time_precise.c \
+src/core/lib/support/time_precise.h \
 src/core/lib/support/time_windows.c \
 src/core/lib/support/tls_pthread.c \
+src/core/lib/support/tmpfile.h \
 src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
-doc/binary-logging.md \
-doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
-doc/compression_cookbook.md \
-doc/connection-backoff-interop-test-description.md \
-doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
-doc/cpp-style-guide.md \
-doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
-doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
-doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/core/pending_api_cleanups.md \
-src/core/README.md \
-src/core/ext/README.md \
-src/core/ext/census/README.md \
-src/core/ext/census/gen/README.md \
-src/core/ext/client_channel/README.md \
-src/core/ext/resolver/README.md \
-src/core/ext/resolver/dns/native/README.md \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/transport/README.md \
-src/core/ext/transport/chttp2/README.md \
-src/core/ext/transport/chttp2/client/insecure/README.md \
-src/core/ext/transport/chttp2/client/secure/README.md \
-src/core/ext/transport/chttp2/server/insecure/README.md \
-src/core/ext/transport/chttp2/server/secure/README.md \
-src/core/ext/transport/chttp2/transport/README.md \
-src/core/lib/README.md \
-src/core/lib/channel/README.md \
-src/core/lib/iomgr/README.md \
 src/core/lib/surface/README.md \
+src/core/lib/surface/alarm.c \
+src/core/lib/surface/api_trace.c \
+src/core/lib/surface/api_trace.h \
+src/core/lib/surface/byte_buffer.c \
+src/core/lib/surface/byte_buffer_reader.c \
+src/core/lib/surface/call.c \
+src/core/lib/surface/call.h \
+src/core/lib/surface/call_details.c \
+src/core/lib/surface/call_log_batch.c \
+src/core/lib/surface/call_test_only.h \
+src/core/lib/surface/channel.c \
+src/core/lib/surface/channel.h \
+src/core/lib/surface/channel_init.c \
+src/core/lib/surface/channel_init.h \
+src/core/lib/surface/channel_ping.c \
+src/core/lib/surface/channel_stack_type.c \
+src/core/lib/surface/channel_stack_type.h \
+src/core/lib/surface/completion_queue.c \
+src/core/lib/surface/completion_queue.h \
+src/core/lib/surface/event_string.c \
+src/core/lib/surface/event_string.h \
+src/core/lib/surface/init.c \
+src/core/lib/surface/init.h \
+src/core/lib/surface/init_secure.c \
+src/core/lib/surface/lame_client.c \
+src/core/lib/surface/lame_client.h \
+src/core/lib/surface/metadata_array.c \
+src/core/lib/surface/server.c \
+src/core/lib/surface/server.h \
+src/core/lib/surface/validate_metadata.c \
+src/core/lib/surface/version.c \
 src/core/lib/transport/README.md \
-src/core/lib/tsi/README.md
+src/core/lib/transport/byte_stream.c \
+src/core/lib/transport/byte_stream.h \
+src/core/lib/transport/connectivity_state.c \
+src/core/lib/transport/connectivity_state.h \
+src/core/lib/transport/mdstr_hash_table.c \
+src/core/lib/transport/mdstr_hash_table.h \
+src/core/lib/transport/metadata.c \
+src/core/lib/transport/metadata.h \
+src/core/lib/transport/metadata_batch.c \
+src/core/lib/transport/metadata_batch.h \
+src/core/lib/transport/pid_controller.c \
+src/core/lib/transport/pid_controller.h \
+src/core/lib/transport/service_config.c \
+src/core/lib/transport/service_config.h \
+src/core/lib/transport/static_metadata.c \
+src/core/lib/transport/static_metadata.h \
+src/core/lib/transport/timeout_encoding.c \
+src/core/lib/transport/timeout_encoding.h \
+src/core/lib/transport/transport.c \
+src/core/lib/transport/transport.h \
+src/core/lib/transport/transport_impl.h \
+src/core/lib/transport/transport_op_string.c \
+src/core/lib/tsi/README.md \
+src/core/lib/tsi/fake_transport_security.c \
+src/core/lib/tsi/fake_transport_security.h \
+src/core/lib/tsi/ssl_transport_security.c \
+src/core/lib/tsi/ssl_transport_security.h \
+src/core/lib/tsi/ssl_types.h \
+src/core/lib/tsi/transport_security.c \
+src/core/lib/tsi/transport_security.h \
+src/core/lib/tsi/transport_security_interface.h \
+src/core/plugin_registry/grpc_plugin_registry.c \
+third_party/nanopb/pb.h \
+third_party/nanopb/pb_common.c \
+third_party/nanopb/pb_common.h \
+third_party/nanopb/pb_decode.c \
+third_party/nanopb/pb_decode.h \
+third_party/nanopb/pb_encode.c \
+third_party/nanopb/pb_encode.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-- 
GitLab


From 9d1cc8c94bca8483bd94496fd4f4c1e518a101d3 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 13:57:25 -0800
Subject: [PATCH 261/344] Change interop test infra to run new Ruby tests

---
 tools/run_tests/run_interop_tests.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 981e38b813..08c4a878f0 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -350,10 +350,10 @@ class RubyLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED + _SKIP_SERVER_COMPRESSION
+    return _SKIP_SERVER_COMPRESSION
 
   def unimplemented_test_cases_server(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def __str__(self):
     return 'ruby'
-- 
GitLab


From d383e4aa886d6a8191b4f7be987eba57c82ec2b4 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Tue, 10 Jan 2017 13:58:07 -0800
Subject: [PATCH 262/344] added ability to run bad-server http2 tests

---
 tools/run_tests/run_interop_tests.py | 94 ++++++++++++++++++++++++----
 1 file changed, 82 insertions(+), 12 deletions(-)

diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 981e38b813..02694c8922 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -169,6 +169,9 @@ class JavaLanguage:
   def client_cmd(self, args):
     return ['./run-test-client.sh'] + args
 
+  def client_cmd_http2interop(self, args):
+    return ['./run-http2-client.sh'] + args
+
   def cloud_to_prod_env(self):
     return {}
 
@@ -179,10 +182,10 @@ class JavaLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_ADVANCED + _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
-    return _SKIP_COMPRESSION
+    return _SKIP_ADVANCED + _SKIP_COMPRESSION
 
   def __str__(self):
     return 'java'
@@ -226,11 +229,15 @@ class Http2Client:
   """
   def __init__(self):
     self.client_cwd = None
+    self.server_cwd = None
     self.safename = str(self)
 
   def client_cmd(self, args):
     return ['tools/http2_interop/http2_interop.test', '-test.v'] + args
 
+  def server_cmd(self, args):
+    return ['python test/http2_test/http2_test_server.py']
+
   def cloud_to_prod_env(self):
     return {}
 
@@ -375,6 +382,11 @@ class PythonLanguage:
         '--args="{}"'.format(' '.join(args))
     ]
 
+  def client_cmd_http2interop(self, args):
+    return [ 'py27/bin/python',
+              'src/python/grpcio_tests/tests/http2/_negative_http2_client.py',
+           ] + args
+
   def cloud_to_prod_env(self):
     return {}
 
@@ -429,7 +441,10 @@ _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong',
 _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
                     'oauth2_auth_token', 'per_rpc_creds']
 
-_HTTP2_TEST_CASES = ["tls", "framing"]
+_HTTP2_TEST_CASES = ['tls', 'framing']
+
+_HTTP2_BADSERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data',
+                     'goaway', 'ping', 'max_streams']
 
 DOCKER_WORKDIR_ROOT = '/var/local/git/grpc'
 
@@ -550,13 +565,26 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name,
 def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
                            server_port, docker_image=None):
   """Creates jobspec for cloud-to-cloud interop test"""
-  cmdline = bash_cmdline(language.client_cmd([
+  interop_only_options = [
       '--server_host_override=foo.test.google.fr',
       '--use_tls=true',
       '--use_test_ca=true',
+  ]
+  common_options = [
       '--test_case=%s' % test_case,
       '--server_host=%s' % server_host,
-      '--server_port=%s' % server_port]))
+  ]
+  if test_case in sorted(_HTTP2_BADSERVER_TEST_CASES):
+    # We are running the http2_badserver_interop test. Adjust command line accordingly.
+    offset = sorted(_HTTP2_BADSERVER_TEST_CASES).index(test_case)
+    client_options = common_options + ['--server_port=%s' %
+                                       (int(server_port)+offset)]
+    cmdline = bash_cmdline(language.client_cmd_http2interop(client_options))
+  else:
+    client_options = interop_only_options + common_options + ['--server_port=%s' % server_port]
+    cmdline = bash_cmdline(language.client_cmd(client_options))
+
+  print('Client_CMD = %s'%cmdline)
   cwd = language.client_cwd
   environ = language.global_env()
   if docker_image:
@@ -590,13 +618,30 @@ def server_jobspec(language, docker_image):
   cmdline = bash_cmdline(
       language.server_cmd(['--port=%s' % _DEFAULT_SERVER_PORT]))
   environ = language.global_env()
+  if language.safename == 'http2':
+    # we are running the http2 interop server. Open next N ports beginning
+    # with the server port. These ports are used for http2 interop test
+    # (one test case per port). We also attach the docker container running
+    # the server to local network, so we don't have to mess with port mapping
+    port_args = [
+      '-p', str(_DEFAULT_SERVER_PORT+0),
+      '-p', str(_DEFAULT_SERVER_PORT+1),
+      '-p', str(_DEFAULT_SERVER_PORT+2),
+      '-p', str(_DEFAULT_SERVER_PORT+3),
+      '-p', str(_DEFAULT_SERVER_PORT+4),
+      '-p', str(_DEFAULT_SERVER_PORT+5),
+      '-p', str(_DEFAULT_SERVER_PORT+6),
+      '--net=host',
+    ]
+  else:
+    port_args = ['-p', str(_DEFAULT_SERVER_PORT)]
+
   docker_cmdline = docker_run_cmdline(cmdline,
                                       image=docker_image,
                                       cwd=language.server_cwd,
                                       environ=environ,
-                                      docker_args=['-p', str(_DEFAULT_SERVER_PORT),
-                                                   '--name', container_name])
-
+                                      docker_args=port_args +
+                                        ['--name', container_name])
   server_job = jobset.JobSpec(
           cmdline=docker_cmdline,
           environ=environ,
@@ -730,7 +775,12 @@ argp.add_argument('--http2_interop',
                   default=False,
                   action='store_const',
                   const=True,
-                  help='Enable HTTP/2 interop tests')
+                  help='Enable HTTP/2 client edge case testing. (Bad client, good server)')
+argp.add_argument('--http2_badserver_interop',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Enable HTTP/2 server edge case testing. (Good client, bad server)')
 
 args = argp.parse_args()
 
@@ -756,14 +806,15 @@ languages = set(_LANGUAGES[l]
                       _LANGUAGES.iterkeys() if x == 'all' else [x]
                       for x in args.language))
 
-http2Interop = Http2Client() if args.http2_interop else None
+http2Interop = Http2Client() if (args.http2_badserver_interop
+                                 or args.http2_interop) else None
 
 docker_images={}
 if args.use_docker:
   # languages for which to build docker images
   languages_to_build = set(_LANGUAGES[k] for k in set([str(l) for l in languages] +
                                                     [s for s in servers]))
-  if args.http2_interop:
+  if args.http2_interop or args.http2_badserver_interop:
     languages_to_build.add(http2Interop)
 
   build_jobs = []
@@ -797,6 +848,14 @@ try:
     server_jobs[lang] = job
     server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
 
+  if args.http2_badserver_interop:
+    # launch a HTTP2 server emulator that creates edge cases
+    lang = str(http2Interop)
+    spec = server_jobspec(Http2Client(), docker_images.get(lang))
+    job = dockerjob.DockerJob(spec)
+    server_jobs[lang] = job
+    server_addresses[lang] = ('localhost', _DEFAULT_SERVER_PORT)
+
   jobs = []
   if args.cloud_to_prod:
     for server_host_name in args.prod_servers:
@@ -843,7 +902,7 @@ try:
     for language in languages:
       for test_case in _TEST_CASES:
         if not test_case in language.unimplemented_test_cases():
-          if not test_case in skip_server:
+          if not test_case in skip_server and not args.http2_badserver_interop:
             test_job = cloud_to_cloud_jobspec(language,
                                               test_case,
                                               server_name,
@@ -865,6 +924,17 @@ try:
                                           docker_image=docker_images.get(str(http2Interop)))
         jobs.append(test_job)
 
+    if args.http2_badserver_interop:
+      for language in languages:
+        for test_case in _HTTP2_BADSERVER_TEST_CASES:
+          test_job = cloud_to_cloud_jobspec(language,
+                                            test_case,
+                                            server_name,
+                                            server_host,
+                                            server_port,
+                                            docker_image=docker_images.get(str(language)))
+          jobs.append(test_job)
+
   if not jobs:
     print('No jobs to run.')
     for image in docker_images.itervalues():
-- 
GitLab


From a0d639dae9b53f3adb2c722789948bbf32dacd8a Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 14:46:10 -0800
Subject: [PATCH 263/344] Update negative-http2-interop-test-descriptions.md

---
 doc/negative-http2-interop-test-descriptions.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index 5ea3a96dff..65ee2cd32d 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -61,14 +61,14 @@ Client Procedure:
     ```
 
 Client asserts:
-* Call was successful.
+* Both calls are successful.
 * Response payload body is 314159 bytes in size.
 
 Server Procedure:
   1. Server sends a GOAWAY after receiving the first UnaryCall.
 
 Server asserts:
-* The second UnaryCall has a different stream_id than the first one.
+* Two different were used from the client.
 
 ### rst_after_header
 
-- 
GitLab


From 9fafc034659e0f218fcafd61a0b3e53d8b28991f Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 14:47:02 -0800
Subject: [PATCH 264/344] Update negative-http2-interop-test-descriptions.md

---
 doc/negative-http2-interop-test-descriptions.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index 65ee2cd32d..e471788891 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -68,7 +68,7 @@ Server Procedure:
   1. Server sends a GOAWAY after receiving the first UnaryCall.
 
 Server asserts:
-* Two different were used from the client.
+* Two different connections were used from the client.
 
 ### rst_after_header
 
-- 
GitLab


From 850ed9b5d0c8766a29cd795e48f5eed1337bf892 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 15:00:53 -0800
Subject: [PATCH 265/344] Update negative-http2-interop-test-descriptions.md

---
 doc/negative-http2-interop-test-descriptions.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index e471788891..1ded97b503 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -49,7 +49,7 @@ server. The client should handle the goaway by switching to a new stream without
 the user application having to do a thing.
 
 Client Procedure:
- 1. Client sends two UnaryCall requests with:
+ 1. Client sends two UnaryCall requests (and sleeps for 1 second in-between).
  
     ```
     {
-- 
GitLab


From 078e4210fdd3410581c38f449a527fd947dfcecc Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Tue, 10 Jan 2017 15:09:21 -0800
Subject: [PATCH 266/344] addressed feedback

created separate class for Http2Server.
---
 tools/run_tests/run_interop_tests.py | 74 +++++++++++++++++++---------
 1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 02694c8922..d25da0b2fa 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -182,10 +182,10 @@ class JavaLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def __str__(self):
     return 'java'
@@ -220,6 +220,33 @@ class GoLanguage:
   def __str__(self):
     return 'go'
 
+class Http2Server:
+  """Represents the HTTP/2 Interop Test server
+
+  This pretends to be a language in order to be built and run, but really it
+  isn't.
+  """
+  def __init__(self):
+    self.server_cwd = None
+    self.safename = str(self)
+
+  def server_cmd(self, args):
+    return ['python test/http2_test/http2_test_server.py']
+
+  def cloud_to_prod_env(self):
+    return {}
+
+  def global_env(self):
+    return {}
+
+  def unimplemented_test_cases(self):
+    return _TEST_CASES
+
+  def unimplemented_test_cases_server(self):
+    return _TEST_CASES
+
+  def __str__(self):
+    return 'http2'
 
 class Http2Client:
   """Represents the HTTP/2 Interop Test
@@ -229,15 +256,11 @@ class Http2Client:
   """
   def __init__(self):
     self.client_cwd = None
-    self.server_cwd = None
     self.safename = str(self)
 
   def client_cmd(self, args):
     return ['tools/http2_interop/http2_interop.test', '-test.v'] + args
 
-  def server_cmd(self, args):
-    return ['python test/http2_test/http2_test_server.py']
-
   def cloud_to_prod_env(self):
     return {}
 
@@ -574,7 +597,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
       '--test_case=%s' % test_case,
       '--server_host=%s' % server_host,
   ]
-  if test_case in sorted(_HTTP2_BADSERVER_TEST_CASES):
+  if test_case in _HTTP2_BADSERVER_TEST_CASES:
     # We are running the http2_badserver_interop test. Adjust command line accordingly.
     offset = sorted(_HTTP2_BADSERVER_TEST_CASES).index(test_case)
     client_options = common_options + ['--server_port=%s' %
@@ -584,7 +607,6 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
     client_options = interop_only_options + common_options + ['--server_port=%s' % server_port]
     cmdline = bash_cmdline(language.client_cmd(client_options))
 
-  print('Client_CMD = %s'%cmdline)
   cwd = language.client_cwd
   environ = language.global_env()
   if docker_image:
@@ -806,17 +828,20 @@ languages = set(_LANGUAGES[l]
                       _LANGUAGES.iterkeys() if x == 'all' else [x]
                       for x in args.language))
 
-http2Interop = Http2Client() if (args.http2_badserver_interop
-                                 or args.http2_interop) else None
+http2Interop = Http2Client() if args.http2_interop else None
+http2InteropServer = Http2Server() if args.http2_badserver_interop else None
 
 docker_images={}
 if args.use_docker:
   # languages for which to build docker images
   languages_to_build = set(_LANGUAGES[k] for k in set([str(l) for l in languages] +
                                                     [s for s in servers]))
-  if args.http2_interop or args.http2_badserver_interop:
+  if args.http2_interop:
     languages_to_build.add(http2Interop)
 
+  if args.http2_badserver_interop:
+    languages_to_build.add(http2InteropServer)
+
   build_jobs = []
   for l in languages_to_build:
     job = build_interop_image_jobspec(l)
@@ -850,8 +875,8 @@ try:
 
   if args.http2_badserver_interop:
     # launch a HTTP2 server emulator that creates edge cases
-    lang = str(http2Interop)
-    spec = server_jobspec(Http2Client(), docker_images.get(lang))
+    lang = str(http2InteropServer)
+    spec = server_jobspec(Http2Server(), docker_images.get(lang))
     job = dockerjob.DockerJob(spec)
     server_jobs[lang] = job
     server_addresses[lang] = ('localhost', _DEFAULT_SERVER_PORT)
@@ -899,17 +924,18 @@ try:
     skip_server = []  # test cases unimplemented by server
     if server_language:
       skip_server = server_language.unimplemented_test_cases_server()
-    for language in languages:
-      for test_case in _TEST_CASES:
-        if not test_case in language.unimplemented_test_cases():
-          if not test_case in skip_server and not args.http2_badserver_interop:
-            test_job = cloud_to_cloud_jobspec(language,
-                                              test_case,
-                                              server_name,
-                                              server_host,
-                                              server_port,
-                                              docker_image=docker_images.get(str(language)))
-            jobs.append(test_job)
+    if not args.http2_badserver_interop:
+      for language in languages:
+        for test_case in _TEST_CASES:
+          if not test_case in language.unimplemented_test_cases():
+            if not test_case in skip_server:
+              test_job = cloud_to_cloud_jobspec(language,
+                                                test_case,
+                                                server_name,
+                                                server_host,
+                                                server_port,
+                                                docker_image=docker_images.get(str(language)))
+              jobs.append(test_job)
 
     if args.http2_interop:
       for test_case in _HTTP2_TEST_CASES:
-- 
GitLab


From 8f3f2f4bd88f9d19bd3dc582f336cb524ef2a534 Mon Sep 17 00:00:00 2001
From: ncteisen <ncteisen@gmail.com>
Date: Tue, 10 Jan 2017 15:39:51 -0800
Subject: [PATCH 267/344] Fix ruby:{python,csharp,csharpcoreclr}_server
 behavior

---
 src/ruby/pb/test/client.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index e051676463..9c4ee9c6f2 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -575,7 +575,7 @@ class NamedTests
     seen_correct_exception = false
     begin
       resp = @stub.full_duplex_call([duplex_req])
-      resp.next # triggers initial req to be sent
+      resp.each { |r| }
     rescue GRPC::Unknown => e
       if e.details != message
         fail AssertionError,
-- 
GitLab


From 39fe75eed3102bc000e467c374e25e904419d893 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Tue, 13 Dec 2016 22:35:01 +0100
Subject: [PATCH 268/344] include/grpc/impl/codegen/port_platform.h: disable
 warn_unused_result on MINGW32 platform

---
 include/grpc/impl/codegen/port_platform.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index cd989d664c..4633fa12e8 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -361,7 +361,7 @@ typedef unsigned __int64 uint64_t;
 #define GPR_MAX_ALIGNMENT 16
 
 #ifndef GRPC_MUST_USE_RESULT
-#ifdef __GNUC__
+#if defined(__GNUC__) && !defined(__MINGW32__)
 #define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
 #else
 #define GRPC_MUST_USE_RESULT
-- 
GitLab


From d817c1b75bcdf21f8cae66f46b39dbb1f867dde9 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Tue, 13 Dec 2016 22:35:50 +0100
Subject: [PATCH 269/344] iocp_windows.c and tcp_server_windows.c: fixes for
 gcc on Windows (unused variables and type casts)

---
 src/core/lib/iomgr/iocp_windows.c       |  1 -
 src/core/lib/iomgr/tcp_server_windows.c | 11 ++++-------
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/core/lib/iomgr/iocp_windows.c b/src/core/lib/iomgr/iocp_windows.c
index 60ebe43676..f0f4a6ff39 100644
--- a/src/core/lib/iomgr/iocp_windows.c
+++ b/src/core/lib/iomgr/iocp_windows.c
@@ -80,7 +80,6 @@ grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx,
   LPOVERLAPPED overlapped;
   grpc_winsocket *socket;
   grpc_winsocket_callback_info *info;
-  grpc_closure *closure = NULL;
   success = GetQueuedCompletionStatus(
       g_iocp, &bytes, &completion_key, &overlapped,
       deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type)));
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 97d7827461..11d570367e 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -184,7 +184,6 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
 }
 
 static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
-  int immediately_done = 0;
   grpc_tcp_listener *sp;
   gpr_mu_lock(&s->mu);
 
@@ -240,7 +239,7 @@ static grpc_error *prepare_socket(SOCKET sock,
     error = GRPC_WSA_ERROR(WSAGetLastError(), "getsockname");
     goto failure;
   }
-  sockname_temp.len = sockname_temp_len;
+  sockname_temp.len = (size_t)sockname_temp_len;
 
   *port = grpc_sockaddr_get_port(&sockname_temp);
   return GRPC_ERROR_NONE;
@@ -248,8 +247,7 @@ static grpc_error *prepare_socket(SOCKET sock,
 failure:
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *tgtaddr = grpc_sockaddr_to_uri(addr);
-  grpc_error *final_error = grpc_error_set_int(
-      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
+  grpc_error_set_int(grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
                              "Failed to prepare server socket", &error, 1),
                          GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr),
       GRPC_ERROR_INT_FD, (intptr_t)sock);
@@ -261,7 +259,6 @@ failure:
 
 static void decrement_active_ports_and_notify_locked(grpc_exec_ctx *exec_ctx,
                                                      grpc_tcp_listener *sp) {
-  int notify = 0;
   sp->shutting_down = 0;
   GPR_ASSERT(sp->server->active_ports > 0);
   if (0 == --sp->server->active_ports) {
@@ -375,7 +372,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
       int peer_name_len = (int)peer_name.len;
       err =
           getpeername(sock, (struct sockaddr *)peer_name.addr, &peer_name_len);
-      peer_name.len = peer_name_len;
+      peer_name.len = (size_t)peer_name_len;
       if (!err) {
         peer_name_string = grpc_sockaddr_to_uri(&peer_name);
       } else {
@@ -498,7 +495,7 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
       if (0 == getsockname(sp->socket->socket,
                            (struct sockaddr *)sockname_temp.addr,
                            &sockname_temp_len)) {
-        sockname_temp.len = sockname_temp_len;
+        sockname_temp.len = (size_t)sockname_temp_len;
         *port = grpc_sockaddr_get_port(&sockname_temp);
         if (*port > 0) {
           allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
-- 
GitLab


From 294dc2f003d8173108b7de645052d3cc3305d428 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Tue, 13 Dec 2016 00:07:12 +0100
Subject: [PATCH 270/344] Makefile.template and Makefile: avoid def-files on
 MSYS2 / MINGW32 platform

---
 Makefile                    | 18 +++++++++---------
 templates/Makefile.template |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index a26842e71b..0c13184a43 100644
--- a/Makefile
+++ b/Makefile
@@ -2578,7 +2578,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared gpr.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
 else
 $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP)
 	$(E) "[LD]      Linking $@"
@@ -2901,7 +2901,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -3174,7 +3174,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc_cronet.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -3674,7 +3674,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
@@ -3938,7 +3938,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4313,7 +4313,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_cronet.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_cronet-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_cronet-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4436,7 +4436,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_reflection.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4828,7 +4828,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
@@ -5318,7 +5318,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared grpc_csharp_ext.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 109de33c31..55fbe530be 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1546,7 +1546,7 @@
   ${out_mingbase}.$(SHARED_EXT_${lang_to_var[lib.language]}): $(LIB${lib.name.upper()}_OBJS) ${mingw_lib_deps}
   	$(E) "[LD]      Linking $@"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared ${lib.name}.def -Wl,--output-def=${out_mingbase}.def -Wl,--out-implib=${out_libbase}-dll.a -o ${out_mingbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${mingw_libs}
+  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=${out_mingbase}.def -Wl,--out-implib=${out_libbase}-dll.a -o ${out_mingbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${mingw_libs}
   else
   ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}): $(LIB${lib.name.upper()}_OBJS) ${lib_deps}
   	$(E) "[LD]      Linking $@"
-- 
GitLab


From 121d289e28d0a791cbc144cd9c3696e706684f9b Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Mon, 12 Dec 2016 23:49:27 +0100
Subject: [PATCH 271/344] Makefile.template and Makefile: use .exe suffix for
 grpc_cpp_plugin on MSYS2 / MINGW32 platform

---
 Makefile                    | 31 +++++++++++++++++--------------
 templates/Makefile.template |  5 ++++-
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile
index 0c13184a43..433c115e84 100644
--- a/Makefile
+++ b/Makefile
@@ -479,6 +479,7 @@ CPP_PC_TEMPLATE = prefix=$(prefix),exec_prefix=\$${prefix},includedir=\$${prefix
 CSHARP_PC_TEMPLATE = prefix=$(prefix),exec_prefix=\$${prefix},includedir=\$${prefix}/include,libdir=\$${exec_prefix}/lib,,Name: $(PC_NAME),Description: $(PC_DESCRIPTION),Version: $(CSHARP_VERSION),Cflags: -I\$${includedir} $(PC_CFLAGS),Requires.private: $(PC_REQUIRES_PRIVATE),Libs: -L\$${libdir} $(PC_LIB),Libs.private: $(PC_LIBS_PRIVATE)
 
 ifeq ($(SYSTEM),MINGW32)
+EXECUTABLE_SUFFIX = .exe
 SHARED_EXT_CORE = dll
 SHARED_EXT_CPP = dll
 SHARED_EXT_CSHARP = dll
@@ -487,6 +488,7 @@ SHARED_VERSION_CORE = -2
 SHARED_VERSION_CPP = -1
 SHARED_VERSION_CSHARP = -1
 else ifeq ($(SYSTEM),Darwin)
+EXECUTABLE_SUFFIX = 
 SHARED_EXT_CORE = dylib
 SHARED_EXT_CPP = dylib
 SHARED_EXT_CSHARP = dylib
@@ -495,6 +497,7 @@ SHARED_VERSION_CORE =
 SHARED_VERSION_CPP =
 SHARED_VERSION_CSHARP =
 else
+EXECUTABLE_SUFFIX = 
 SHARED_EXT_CORE = so.$(CORE_VERSION)
 SHARED_EXT_CPP = so.$(CPP_VERSION)
 SHARED_EXT_CSHARP = so.$(CSHARP_VERSION)
@@ -2039,7 +2042,7 @@ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_ba
 $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2054,7 +2057,7 @@ $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/ref
 $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2069,7 +2072,7 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com
 $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2084,7 +2087,7 @@ $(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.p
 $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2099,7 +2102,7 @@ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/
 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2114,7 +2117,7 @@ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $
 $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2129,7 +2132,7 @@ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/ech
 $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2144,7 +2147,7 @@ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto
 $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2159,7 +2162,7 @@ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages
 $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2174,7 +2177,7 @@ $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.p
 $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: src/proto/grpc/testing/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2189,7 +2192,7 @@ $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads
 $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2204,7 +2207,7 @@ $(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services
 $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2219,7 +2222,7 @@ $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto
 $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -2234,7 +2237,7 @@ $(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $
 $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 55fbe530be..6364662d9a 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -392,6 +392,7 @@
   Libs.private: $(PC_LIBS_PRIVATE)
 
   ifeq ($(SYSTEM),MINGW32)
+  EXECUTABLE_SUFFIX = .exe
   SHARED_EXT_CORE = dll
   SHARED_EXT_CPP = dll
   SHARED_EXT_CSHARP = dll
@@ -400,6 +401,7 @@
   SHARED_VERSION_CPP = -${settings.cpp_version.major}
   SHARED_VERSION_CSHARP = -${settings.csharp_version.major}
   else ifeq ($(SYSTEM),Darwin)
+  EXECUTABLE_SUFFIX = 
   SHARED_EXT_CORE = dylib
   SHARED_EXT_CPP = dylib
   SHARED_EXT_CSHARP = dylib
@@ -408,6 +410,7 @@
   SHARED_VERSION_CPP =
   SHARED_VERSION_CSHARP =
   else
+  EXECUTABLE_SUFFIX = 
   SHARED_EXT_CORE = so.$(CORE_VERSION)
   SHARED_EXT_CPP = so.$(CPP_VERSION)
   SHARED_EXT_CSHARP = so.$(CSHARP_VERSION)
@@ -1196,7 +1199,7 @@
   $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))}
   	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $<
+  	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
   endif
 
   % endfor
-- 
GitLab


From 1643c045a03536bff3bcafed6c1b599cc47d508a Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Mon, 12 Dec 2016 23:12:47 +0100
Subject: [PATCH 272/344] Makefile.template and Makefile: avoid stripping too
 heavily on MSYS2 / MINGW32 platform

---
 Makefile                    | 7 +++++++
 templates/Makefile.template | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/Makefile b/Makefile
index 433c115e84..4f0d0017f3 100644
--- a/Makefile
+++ b/Makefile
@@ -292,12 +292,19 @@ AR = libtool -no_warning_for_no_symbols -o
 endif
 STRIP ?= strip -x
 else
+ifeq ($(SYSTEM),MINGW32)
+ifeq ($(origin AR), default)
+AR = ar rcs
+endif
+STRIP ?= strip --strip-unneeded
+else
 ifeq ($(origin AR), default)
 AR = ar rcs
 endif
 STRIP ?= strip
 endif
 endif
+endif
 INSTALL ?= install
 RM ?= rm -f
 PKG_CONFIG ?= pkg-config
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 6364662d9a..3844918de2 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -182,12 +182,19 @@
   endif
   STRIP ?= strip -x
   else
+  ifeq ($(SYSTEM),MINGW32)
+  ifeq ($(origin AR), default)
+  AR = ar rcs
+  endif
+  STRIP ?= strip --strip-unneeded
+  else
   ifeq ($(origin AR), default)
   AR = ar rcs
   endif
   STRIP ?= strip
   endif
   endif
+  endif
   INSTALL ?= install
   RM ?= rm -f
   PKG_CONFIG ?= pkg-config
-- 
GitLab


From 13f6716d8578ecb5e7c20151b781ad0d18be9c92 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Mon, 12 Dec 2016 23:56:04 +0100
Subject: [PATCH 273/344] Makefile.template and Makefile: install plugins on
 MSYS2 / MINGW32 platform

---
 Makefile                    | 4 ----
 templates/Makefile.template | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/Makefile b/Makefile
index 4f0d0017f3..024ca8f12a 100644
--- a/Makefile
+++ b/Makefile
@@ -2440,9 +2440,6 @@ endif
 
 
 install-plugins: $(PROTOC_PLUGINS)
-ifeq ($(SYSTEM),MINGW32)
-	$(Q) false
-else
 	$(E) "[INSTALL] Installing grpc protoc plugins"
 	$(Q) $(INSTALL) -d $(prefix)/bin
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin
@@ -2458,7 +2455,6 @@ else
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin
 	$(Q) $(INSTALL) -d $(prefix)/bin
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin
-endif
 
 install-pkg-config_c: pc_c pc_c_unsecure
 	$(E) "[INSTALL] Installing C pkg-config files"
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 3844918de2..1b6bc0e93d 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1332,9 +1332,6 @@
   ${install_shared("csharp")}
 
   install-plugins: $(PROTOC_PLUGINS)
-  ifeq ($(SYSTEM),MINGW32)
-  	$(Q) false
-  else
   	$(E) "[INSTALL] Installing grpc protoc plugins"
   % for tgt in targets:
   % if tgt.build == 'protoc':
@@ -1342,7 +1339,6 @@
   	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/${tgt.name} $(prefix)/bin/${tgt.name}
   % endif
   % endfor
-  endif
 
   install-pkg-config_c: pc_c pc_c_unsecure
   	$(E) "[INSTALL] Installing C pkg-config files"
-- 
GitLab


From 98c0bd7c829c4932ac12ebbe6687f0fc5380e866 Mon Sep 17 00:00:00 2001
From: Yuxuan Li <yuxuanli@google.com>
Date: Tue, 15 Nov 2016 13:31:36 -0800
Subject: [PATCH 274/344] add setting channel args functionality to performance
 tesing

setting channel args --draft

clang-format
---
 src/proto/grpc/testing/control.proto | 10 ++++++++++
 test/cpp/qps/client.h                | 13 +++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index be387cf786..529313cfb1 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -78,6 +78,14 @@ message SecurityParams {
   string server_host_override = 2;
 }
 
+message ChannelArg {
+  string name = 1;
+  oneof value {
+    string str_value = 2;
+    int32 int_value = 3;
+  }
+}
+
 message ClientConfig {
   // List of targets to connect to. At least one target needs to be specified.
   repeated string server_targets = 1;
@@ -103,6 +111,8 @@ message ClientConfig {
 
   // If we use an OTHER_CLIENT client_type, this string gives more detail
   string other_client_api = 15;
+
+  repeated ChannelArg channel_args = 16;
 }
 
 message ClientStatus { ClientStats stats = 1; }
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index fdd78ebb89..18f9778fc6 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -409,6 +409,7 @@ class ClientImpl : public Client {
       // old compilers happy with using this in std::vector
       ChannelArguments args;
       args.SetInt("shard_to_ensure_no_subchannel_merges", shard);
+      set_channel_args(config, &args);
       channel_ = CreateTestChannel(
           target, config.security_params().server_host_override(),
           config.has_security_params(), !config.security_params().use_test_ca(),
@@ -423,6 +424,18 @@ class ClientImpl : public Client {
     StubType* get_stub() { return stub_.get(); }
 
    private:
+    void set_channel_args(const ClientConfig& config, ChannelArguments* args) {
+      for (auto channel_arg : config.channel_args()) {
+        if (channel_arg.value_case() == ChannelArg::kStrValue) {
+          args->SetString(channel_arg.name(), channel_arg.str_value());
+        } else if (channel_arg.value_case() == ChannelArg::kIntValue) {
+          args->SetInt(channel_arg.name(), channel_arg.int_value());
+        } else {
+          gpr_log(GPR_ERROR, "Empty channel arg value.");
+        }
+      }
+    }
+
     std::shared_ptr<Channel> channel_;
     std::unique_ptr<StubType> stub_;
   };
-- 
GitLab


From df71518e54dbc0ecf0f992f6d102314e8a6c03ff Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 11 Jan 2017 10:44:41 +0100
Subject: [PATCH 275/344] fix code formatting

---
 src/core/lib/iomgr/tcp_server_windows.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 11d570367e..dafe851ce8 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -247,7 +247,8 @@ static grpc_error *prepare_socket(SOCKET sock,
 failure:
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   char *tgtaddr = grpc_sockaddr_to_uri(addr);
-  grpc_error_set_int(grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
+  grpc_error_set_int(
+      grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
                              "Failed to prepare server socket", &error, 1),
                          GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr),
       GRPC_ERROR_INT_FD, (intptr_t)sock);
-- 
GitLab


From ac87a46225128f2c92e9d2cb8522b4b88d5abde8 Mon Sep 17 00:00:00 2001
From: Yuxuan Li <yuxuanli@google.com>
Date: Fri, 11 Nov 2016 12:05:11 -0800
Subject: [PATCH 276/344] enable uploading server cpu usage data from
 performance tests to big query

---
 test/cpp/qps/qps_json_driver.cc               |  1 +
 .../run_tests/performance/bq_upload_result.py |  8 ++++---
 .../performance/scenario_result_schema.json   | 22 +++++++++++++++++++
 tools/run_tests/run_performance_tests.py      | 20 +++++++++++------
 4 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index da835b995a..57ee5ef63c 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -212,6 +212,7 @@ static bool QpsDriver() {
             SearchOfferedLoad(FLAGS_initial_search_value,
                               FLAGS_targeted_cpu_load, scenario, &success);
         gpr_log(GPR_INFO, "targeted_offered_load %f", targeted_offered_load);
+        GetCpuLoad(scenario, targeted_offered_load, &success);
       } else {
         gpr_log(GPR_ERROR, "Unimplemented search param");
       }
diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py
index ddcf053ae5..89d2a9b320 100755
--- a/tools/run_tests/performance/bq_upload_result.py
+++ b/tools/run_tests/performance/bq_upload_result.py
@@ -115,9 +115,11 @@ def _flatten_result_inplace(scenario_result):
   scenario_result['scenario']['clientConfig'] = json.dumps(scenario_result['scenario']['clientConfig'])
   scenario_result['scenario']['serverConfig'] = json.dumps(scenario_result['scenario']['serverConfig'])
   scenario_result['latencies'] = json.dumps(scenario_result['latencies'])
+  scenario_result['serverCpuStats'] = []
   for stats in scenario_result['serverStats']:
-    stats.pop('totalCpuTime', None)
-    stats.pop('idleCpuTime', None)
+    scenario_result['serverCpuStats'].append(dict())
+    scenario_result['serverCpuStats'][-1]['totalCpuTime'] = stats.pop('totalCpuTime', None)
+    scenario_result['serverCpuStats'][-1]['idleCpuTime'] = stats.pop('idleCpuTime', None)
   for stats in scenario_result['clientStats']:
     stats['latencies'] = json.dumps(stats['latencies'])
     stats.pop('requestResults', None)
@@ -125,7 +127,7 @@ def _flatten_result_inplace(scenario_result):
   scenario_result['clientSuccess'] = json.dumps(scenario_result['clientSuccess'])
   scenario_result['serverSuccess'] = json.dumps(scenario_result['serverSuccess'])
   scenario_result['requestResults'] = json.dumps(scenario_result.get('requestResults', []))
-  scenario_result['summary'].pop('serverCpuUsage', None)
+  scenario_result['serverCpuUsage'] = scenario_result['summary'].pop('serverCpuUsage', None)
   scenario_result['summary'].pop('successfulRequestsPerSecond', None)
   scenario_result['summary'].pop('failedRequestsPerSecond', None)
 
diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json
index 3285f212d7..8ec41c377c 100644
--- a/tools/run_tests/performance/scenario_result_schema.json
+++ b/tools/run_tests/performance/scenario_result_schema.json
@@ -213,5 +213,27 @@
     "name": "requestResults",
     "type": "STRING",
     "mode": "NULLABLE"
+  },
+  {
+    "name": "serverCpuStats",
+    "type": "RECORD",
+    "mode": "REPEATED",
+    "fields": [
+      {
+        "name": "totalCpuTime",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "idleCpuTime",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      }
+    ]
+  },
+  {
+    "name": "serverCpuUsage",
+    "type": "FLOAT",
+    "mode": "NULLABLE"
   }
 ]
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index b7b742d7af..d6eed3f5bd 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -113,7 +113,7 @@ def create_qpsworker_job(language, shortname=None, port=10000, remote_host=None,
 
 
 def create_scenario_jobspec(scenario_json, workers, remote_host=None,
-                            bq_result_table=None):
+                            bq_result_table=None, server_cpu_load=0):
   """Runs one scenario using QPS driver."""
   # setting QPS_WORKERS env variable here makes sure it works with SSH too.
   cmd = 'QPS_WORKERS="%s" ' % ','.join(workers)
@@ -121,7 +121,9 @@ def create_scenario_jobspec(scenario_json, workers, remote_host=None,
     cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table
   cmd += 'tools/run_tests/performance/run_qps_driver.sh '
   cmd += '--scenarios_json=%s ' % pipes.quote(json.dumps({'scenarios': [scenario_json]}))
-  cmd += '--scenario_result_file=scenario_result.json'
+  cmd += '--scenario_result_file=scenario_result.json '
+  if server_cpu_load != 0:
+      cmd += '--search_param=offered_load --initial_search_value=1000 --targeted_cpu_load=%d --stride=500 --error_tolerance=0.01' % server_cpu_load
   if remote_host:
     user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
     cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
@@ -129,7 +131,7 @@ def create_scenario_jobspec(scenario_json, workers, remote_host=None,
   return jobset.JobSpec(
       cmdline=[cmd],
       shortname='qps_json_driver.%s' % scenario_json['name'],
-      timeout_seconds=3*60,
+      timeout_seconds=12*60,
       shell=True,
       verbose_success=True)
 
@@ -318,7 +320,7 @@ Scenario = collections.namedtuple('Scenario', 'jobspec workers name')
 
 def create_scenarios(languages, workers_by_lang, remote_host=None, regex='.*',
                      category='all', bq_result_table=None,
-                     netperf=False, netperf_hosts=[]):
+                     netperf=False, netperf_hosts=[], server_cpu_load=0):
   """Create jobspecs for scenarios to run."""
   all_workers = [worker
                  for workers in workers_by_lang.values()
@@ -379,7 +381,8 @@ def create_scenarios(languages, workers_by_lang, remote_host=None, regex='.*',
               create_scenario_jobspec(scenario_json,
                                       [w.host_and_port for w in workers],
                                       remote_host=remote_host,
-                                      bq_result_table=bq_result_table),
+                                      bq_result_table=bq_result_table,
+                                      server_cpu_load=server_cpu_load),
               workers,
               scenario_json['name'])
           scenarios.append(scenario)
@@ -461,6 +464,9 @@ argp.add_argument('--netperf',
                   action='store_const',
                   const=True,
                   help='Run netperf benchmark as one of the scenarios.')
+argp.add_argument('--server_cpu_load',
+                  default=0, type=int,
+                  help='Select a targeted server cpu load to run. 0 means ignore this flag')
 argp.add_argument('-x', '--xml_report', default='report.xml', type=str,
                   help='Name of XML report file to generate.')
 argp.add_argument('--perf_args',
@@ -490,7 +496,6 @@ argp.add_argument('--skip_generate_flamegraphs',
                         'May be useful if "perf_args" arguments do not make sense for '
                         'generating flamegraphs (e.g., "--perf_args=stat ...")'))
 
-
 args = argp.parse_args()
 
 languages = set(scenario_config.LANGUAGES[l]
@@ -540,7 +545,8 @@ scenarios = create_scenarios(languages,
                            category=args.category,
                            bq_result_table=args.bq_result_table,
                            netperf=args.netperf,
-                           netperf_hosts=args.remote_worker_host)
+                           netperf_hosts=args.remote_worker_host,
+                           server_cpu_load=args.server_cpu_load)
 
 if not scenarios:
   raise Exception('No scenarios to run')
-- 
GitLab


From c344e87449cb23fa03977c6a8dbdedfba8730296 Mon Sep 17 00:00:00 2001
From: Eric Gribkoff <ericgribkoff@google.com>
Date: Mon, 9 Jan 2017 10:53:50 -0800
Subject: [PATCH 277/344] Adds HTTP/2 interop test client

---
 Makefile                                      |  92 +++++-
 build.yaml                                    |  32 +++
 test/cpp/interop/http2_client.cc              | 272 ++++++++++++++++++
 test/cpp/interop/http2_client.h               |  80 ++++++
 .../generated/sources_and_headers.json        |  44 +++
 .../http2_client_main.vcxproj                 | 206 +++++++++++++
 .../http2_client_main.vcxproj.filters         |  47 +++
 7 files changed, 771 insertions(+), 2 deletions(-)
 create mode 100644 test/cpp/interop/http2_client.cc
 create mode 100644 test/cpp/interop/http2_client.h
 create mode 100644 vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj
 create mode 100644 vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj.filters

diff --git a/Makefile b/Makefile
index 024ca8f12a..fdeb389a80 100644
--- a/Makefile
+++ b/Makefile
@@ -1095,6 +1095,7 @@ grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
 grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
 grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
+http2_client: $(BINDIR)/$(CONFIG)/http2_client
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
@@ -1270,9 +1271,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc
 pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
 
 ifeq ($(EMBED_OPENSSL),true)
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
 else
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
 endif
 
 
@@ -1477,6 +1478,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
+  $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -1570,6 +1572,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
+  $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -4958,6 +4961,59 @@ ifneq ($(NO_DEPS),true)
 endif
 
 
+LIBHTTP2_CLIENT_MAIN_SRC = \
+    $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
+    test/cpp/interop/http2_client.cc \
+
+PUBLIC_HEADERS_CXX += \
+
+LIBHTTP2_CLIENT_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBHTTP2_CLIENT_MAIN_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libhttp2_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBHTTP2_CLIENT_MAIN_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a
+	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBHTTP2_CLIENT_MAIN_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBHTTP2_CLIENT_MAIN_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/http2_client.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
+
+
 LIBINTEROP_CLIENT_HELPER_SRC = \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     test/cpp/interop/client_helper.cc \
@@ -12912,6 +12968,37 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
 
 
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/http2_client: 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)/http2_client: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/http2_client:  $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/http2_client
+
+endif
+
+endif
+
+
+
+
 HYBRID_END2END_TEST_SRC = \
     test/cpp/end2end/hybrid_end2end_test.cc \
 
@@ -16829,6 +16916,7 @@ test/core/util/test_tcp_server.c: $(OPENSSL_DEP)
 test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP)
 test/cpp/interop/client.cc: $(OPENSSL_DEP)
 test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
+test/cpp/interop/http2_client.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_server.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP)
diff --git a/build.yaml b/build.yaml
index 55aca52f68..1f90d26804 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1217,6 +1217,22 @@ libs:
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
   vs_props:
   - protoc
+- name: http2_client_main
+  build: private
+  language: c++
+  headers:
+  - test/cpp/interop/http2_client.h
+  src:
+  - src/proto/grpc/testing/empty.proto
+  - src/proto/grpc/testing/messages.proto
+  - src/proto/grpc/testing/test.proto
+  - test/cpp/interop/http2_client.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - grpc++_test_config
 - name: interop_client_helper
   build: private
   language: c++
@@ -3191,6 +3207,22 @@ targets:
   - grpc++
   - grpc++_test_util
   - grpc_test_util
+- name: http2_client
+  build: test
+  run: false
+  language: c++
+  src: []
+  deps:
+  - http2_client_main
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - grpc++_test_config
+  platforms:
+  - mac
+  - linux
+  - posix
 - name: hybrid_end2end_test
   gtest: true
   build: test
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
new file mode 100644
index 0000000000..38aee43b26
--- /dev/null
+++ b/test/cpp/interop/http2_client.cc
@@ -0,0 +1,272 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#include <thread>
+
+#include <gflags/gflags.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#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/test.grpc.pb.h"
+#include "test/cpp/interop/http2_client.h"
+
+#include "src/core/lib/support/string.h"
+#include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/util/test_config.h"
+
+namespace grpc {
+namespace testing {
+
+namespace {
+const int kLargeRequestSize = 271828;
+const int kLargeResponseSize = 314159;
+}  // namespace
+
+Http2Client::ServiceStub::ServiceStub(std::shared_ptr<Channel> channel)
+    : channel_(channel) {
+  stub_ = TestService::NewStub(channel);
+}
+
+TestService::Stub* Http2Client::ServiceStub::Get() { return stub_.get(); }
+
+Http2Client::Http2Client(std::shared_ptr<Channel> channel)
+    : serviceStub_(channel), channel_(channel) {}
+
+bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) {
+  if (s.error_code() == expected_code) {
+    return true;
+  }
+
+  gpr_log(GPR_ERROR, "Error status code: %d (expected: %d), message: %s",
+          s.error_code(), expected_code, s.error_message().c_str());
+  abort();
+}
+
+bool Http2Client::DoRstAfterHeader() {
+  gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header");
+
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+  Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
+  GPR_ASSERT(!response.has_payload());  // no data should be received
+
+  gpr_log(GPR_DEBUG, "Done testing reset stream after header");
+  return true;
+}
+
+bool Http2Client::DoRstAfterData() {
+  gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data");
+
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+  Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
+  GPR_ASSERT(response.has_payload());  // data should be received
+
+  gpr_log(GPR_DEBUG, "Done testing reset stream after data");
+  return true;
+}
+
+bool Http2Client::DoRstDuringData() {
+  gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data");
+
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+  Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
+  GPR_ASSERT(!response.has_payload());  // no data should be received
+
+  gpr_log(GPR_DEBUG, "Done testing reset stream during data");
+  return true;
+}
+
+bool Http2Client::DoGoaway() {
+  gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway");
+
+  int numCalls = 2;
+  for (int i = 0; i < numCalls; i++) {
+    ClientContext context;
+    SimpleRequest request;
+    SimpleResponse response;
+    request.set_response_size(kLargeResponseSize);
+    grpc::string payload(kLargeRequestSize, '\0');
+    request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+    Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+    AssertStatusCode(s, grpc::StatusCode::OK);
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(kLargeResponseSize, '\0'));
+  }
+
+  gpr_log(GPR_DEBUG, "Done testing goaway");
+  return true;
+}
+
+bool Http2Client::DoPing() {
+  gpr_log(GPR_DEBUG, "Sending RPC and expecting ping");
+
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+  Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::OK);
+  GPR_ASSERT(response.payload().body() ==
+             grpc::string(kLargeResponseSize, '\0'));
+
+  gpr_log(GPR_DEBUG, "Done testing ping");
+  return true;
+}
+
+void Http2Client::MaxStreamsWorker(std::shared_ptr<grpc::Channel> channel) {
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+  Status s =
+      TestService::NewStub(channel)->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::OK);
+  GPR_ASSERT(response.payload().body() ==
+             grpc::string(kLargeResponseSize, '\0'));
+}
+
+bool Http2Client::DoMaxStreams() {
+  gpr_log(GPR_DEBUG, "Testing max streams");
+
+  // Make an initial call on the channel to ensure the server's max streams
+  // setting is received
+  ClientContext context;
+  SimpleRequest request;
+  SimpleResponse response;
+  request.set_response_size(kLargeResponseSize);
+  grpc::string payload(kLargeRequestSize, '\0');
+  request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+  Status s =
+      TestService::NewStub(channel_)->UnaryCall(&context, request, &response);
+  AssertStatusCode(s, grpc::StatusCode::OK);
+  GPR_ASSERT(response.payload().body() ==
+             grpc::string(kLargeResponseSize, '\0'));
+
+  std::vector<std::thread> test_threads;
+
+  for (int i = 0; i < 10; i++) {
+    test_threads.emplace_back(
+        std::thread(&Http2Client::MaxStreamsWorker, this, channel_));
+  }
+
+  for (auto it = test_threads.begin(); it != test_threads.end(); it++) {
+    it->join();
+  }
+
+  gpr_log(GPR_DEBUG, "Done testing max streams");
+  return true;
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+DEFINE_int32(server_port, 0, "Server port.");
+DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
+DEFINE_string(test_case, "rst_after_header",
+              "Configure different test cases. Valid options are:\n\n"
+              "goaway\n"
+              "max_streams\n"
+              "ping\n"
+              "rst_after_data\n"
+              "rst_after_header\n"
+              "rst_during_data\n");
+
+int main(int argc, char** argv) {
+  grpc::testing::InitTest(&argc, &argv, true);
+  GPR_ASSERT(FLAGS_server_port);
+  const int host_port_buf_size = 1024;
+  char host_port[host_port_buf_size];
+  snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
+           FLAGS_server_port);
+  grpc::testing::Http2Client client(grpc::CreateTestChannel(host_port, false));
+  gpr_log(GPR_INFO, "Testing case: %s", FLAGS_test_case.c_str());
+  int ret = 0;
+  if (FLAGS_test_case == "rst_after_header") {
+    client.DoRstAfterHeader();
+  } else if (FLAGS_test_case == "rst_after_data") {
+    client.DoRstAfterData();
+  } else if (FLAGS_test_case == "rst_during_data") {
+    client.DoRstDuringData();
+  } else if (FLAGS_test_case == "goaway") {
+    client.DoGoaway();
+  } else if (FLAGS_test_case == "ping") {
+    client.DoPing();
+  } else if (FLAGS_test_case == "max_streams") {
+    client.DoMaxStreams();
+  } else {
+    const char* testcases[] = {
+        "goaway",         "max_streams",      "ping",
+        "rst_after_data", "rst_after_header", "rst_during_data"};
+    char* joined_testcases =
+        gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", NULL);
+
+    gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s",
+            FLAGS_test_case.c_str(), joined_testcases);
+    gpr_free(joined_testcases);
+    ret = 1;
+  }
+
+  return ret;
+}
diff --git a/test/cpp/interop/http2_client.h b/test/cpp/interop/http2_client.h
new file mode 100644
index 0000000000..6a315f5abb
--- /dev/null
+++ b/test/cpp/interop/http2_client.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_INTEROP_HTTP2_CLIENT_H
+#define GRPC_TEST_CPP_INTEROP_HTTP2_CLIENT_H
+
+#include <memory>
+
+#include <grpc++/channel.h>
+#include <grpc/grpc.h>
+#include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/test.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+class Http2Client {
+ public:
+  explicit Http2Client(std::shared_ptr<Channel> channel);
+  ~Http2Client() {}
+
+  bool DoRstAfterHeader();
+  bool DoRstAfterData();
+  bool DoRstDuringData();
+  bool DoGoaway();
+  bool DoPing();
+  bool DoMaxStreams();
+
+ private:
+  class ServiceStub {
+   public:
+    ServiceStub(std::shared_ptr<Channel> channel);
+
+    TestService::Stub* Get();
+
+   private:
+    std::unique_ptr<TestService::Stub> stub_;
+    std::shared_ptr<Channel> channel_;
+  };
+
+  void MaxStreamsWorker(std::shared_ptr<grpc::Channel> channel);
+  bool AssertStatusCode(const Status& s, StatusCode expected_code);
+  ServiceStub serviceStub_;
+  std::shared_ptr<Channel> channel_;
+};
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_INTEROP_HTTP2_CLIENT_H
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 8849dcc600..0c00767200 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -2772,6 +2772,23 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_config", 
+      "grpc++_test_util", 
+      "grpc_test_util", 
+      "http2_client_main"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "http2_client", 
+    "src": [], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -5388,6 +5405,33 @@
     "third_party": false, 
     "type": "lib"
   }, 
+  {
+    "deps": [
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_config", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/empty.grpc.pb.h", 
+      "src/proto/grpc/testing/empty.pb.h", 
+      "src/proto/grpc/testing/messages.grpc.pb.h", 
+      "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/test.grpc.pb.h", 
+      "src/proto/grpc/testing/test.pb.h", 
+      "test/cpp/interop/http2_client.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "http2_client_main", 
+    "src": [
+      "test/cpp/interop/http2_client.cc", 
+      "test/cpp/interop/http2_client.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
   {
     "deps": [
       "gpr", 
diff --git a/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj b/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj
new file mode 100644
index 0000000000..c94c346ed9
--- /dev/null
+++ b/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8008C126-4B35-5A76-A795-39DA13DA57F4}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>http2_client_main</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>http2_client_main</TargetName>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\interop\http2_client.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\http2_client.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
+      <Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj.filters b/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj.filters
new file mode 100644
index 0000000000..40e4191345
--- /dev/null
+++ b/vsprojects/vcxproj/http2_client_main/http2_client_main.vcxproj.filters
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\empty.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\http2_client.cc">
+      <Filter>test\cpp\interop</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\interop\http2_client.h">
+      <Filter>test\cpp\interop</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{8f01743f-58cf-2127-20d1-21303c8e0e8e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{219dd0bc-d605-d0fa-cca4-460276dd64cf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{7ee50971-dbc6-3240-e6a2-a432dac43e90}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{66289b19-9541-151c-03a1-771101833b4e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{18fdd193-31a2-a622-980e-df055c23af50}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{f6da8892-ac51-d835-468a-b3b093df4baa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\interop">
+      <UniqueIdentifier>{e32cff29-3247-cece-56cf-8fd16a1a79fe}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
-- 
GitLab


From 6bbd95e4a319495a7ad6c70b93b0f7984b6cc891 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Wed, 11 Jan 2017 09:35:09 -0800
Subject: [PATCH 278/344] minor fix

---
 tools/run_tests/run_interop_tests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index d25da0b2fa..a33ff55ca3 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -876,7 +876,7 @@ try:
   if args.http2_badserver_interop:
     # launch a HTTP2 server emulator that creates edge cases
     lang = str(http2InteropServer)
-    spec = server_jobspec(Http2Server(), docker_images.get(lang))
+    spec = server_jobspec(http2InteropServer, docker_images.get(lang))
     job = dockerjob.DockerJob(spec)
     server_jobs[lang] = job
     server_addresses[lang] = ('localhost', _DEFAULT_SERVER_PORT)
-- 
GitLab


From b8c5fe1e621dd804b3aec1175b6a8c23637de0ef Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 10:47:35 -0800
Subject: [PATCH 279/344] Promote dns resolution failure message to INFO

---
 src/core/ext/resolver/dns/native/dns_resolver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index bb2b012507..655d9dc586 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -189,7 +189,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
     gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
     gpr_timespec timeout = gpr_time_sub(next_try, now);
     const char *msg = grpc_error_string(error);
-    gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
+    gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", msg);
     grpc_error_free_string(msg);
     GPR_ASSERT(!r->have_retry_timer);
     r->have_retry_timer = true;
-- 
GitLab


From 1da20c10b0f56e83364045445be0fb4f0c44b4cd Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 10:50:26 -0800
Subject: [PATCH 280/344] Remove unused load

---
 test/core/support/BUILD | 2 --
 1 file changed, 2 deletions(-)

diff --git a/test/core/support/BUILD b/test/core/support/BUILD
index 77f0a9a048..dfe952eb37 100644
--- a/test/core/support/BUILD
+++ b/test/core/support/BUILD
@@ -27,8 +27,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
-
 cc_test(
     name = "alloc_test",
     srcs = ["alloc_test.c"],
-- 
GitLab


From cc5910228d84561d40cd8f0513faddc1e0100275 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 11:10:43 -0800
Subject: [PATCH 281/344] manual revert of #8901

---
 build.yaml                                    |  1 +
 test/cpp/end2end/async_end2end_test.cc        | 19 ++++--
 test/cpp/end2end/end2end_test.cc              | 20 ++++--
 test/cpp/interop/client.cc                    |  1 +
 test/cpp/interop/client_helper.cc             | 10 ++-
 test/cpp/interop/interop_server.cc            |  1 +
 test/cpp/interop/server_helper.cc             | 18 +++---
 test/cpp/interop/stress_test.cc               |  1 +
 test/cpp/util/create_test_channel.cc          | 64 ++++++++++++++++---
 test/cpp/util/create_test_channel.h           |  4 ++
 test/cpp/util/test_credentials_provider.cc    | 52 +++------------
 test/cpp/util/test_credentials_provider.h     | 50 ++++++++++-----
 .../generated/sources_and_headers.json        |  1 +
 .../interop_server_helper.vcxproj             |  3 +
 14 files changed, 153 insertions(+), 92 deletions(-)

diff --git a/build.yaml b/build.yaml
index 55aca52f68..64b2a6e01c 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1259,6 +1259,7 @@ libs:
   src:
   - test/cpp/interop/server_helper.cc
   deps:
+  - grpc++_test_util
   - grpc_test_util
   - grpc++
   - grpc
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 8e385d100c..2ce3f2f7bd 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -254,7 +254,8 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
 
     // Setup server
     ServerBuilder builder;
-    auto server_creds = GetServerCredentials(GetParam().credentials_type);
+    auto server_creds = GetCredentialsProvider()->GetServerCredentials(
+        GetParam().credentials_type);
     builder.AddListeningPort(server_address_.str(), server_creds);
     builder.RegisterService(&service_);
     cq_ = builder.AddCompletionQueue();
@@ -283,8 +284,8 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
 
   void ResetStub() {
     ChannelArguments args;
-    auto channel_creds =
-        GetChannelCredentials(GetParam().credentials_type, &args);
+    auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
+        GetParam().credentials_type, &args);
     std::shared_ptr<Channel> channel =
         CreateCustomChannel(server_address_.str(), channel_creds, args);
     stub_ = grpc::testing::EchoTestService::NewStub(channel);
@@ -892,8 +893,8 @@ TEST_P(AsyncEnd2endTest, ServerCheckDone) {
 
 TEST_P(AsyncEnd2endTest, UnimplementedRpc) {
   ChannelArguments args;
-  auto channel_creds =
-      GetChannelCredentials(GetParam().credentials_type, &args);
+  auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
+      GetParam().credentials_type, &args);
   std::shared_ptr<Channel> channel =
       CreateCustomChannel(server_address_.str(), channel_creds, args);
   std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
@@ -1404,11 +1405,15 @@ std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking,
   std::vector<grpc::string> credentials_types;
   std::vector<grpc::string> messages;
 
-  credentials_types.push_back(kInsecureCredentialsType);
-  auto sec_list = GetSecureCredentialsTypeList();
+  if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType,
+                                                      nullptr) != nullptr) {
+    credentials_types.push_back(kInsecureCredentialsType);
+  }
+  auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList();
   for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) {
     credentials_types.push_back(*sec);
   }
+  GPR_ASSERT(!credentials_types.empty());
 
   messages.push_back("Hello");
   for (int sz = 1; sz < test_big_limit; sz *= 2) {
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 9bb892c694..1a1a94e87c 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -242,7 +242,8 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> {
     // Setup server
     ServerBuilder builder;
     ConfigureServerBuilder(&builder);
-    auto server_creds = GetServerCredentials(GetParam().credentials_type);
+    auto server_creds = GetCredentialsProvider()->GetServerCredentials(
+        GetParam().credentials_type);
     if (GetParam().credentials_type != kInsecureCredentialsType) {
       server_creds->SetAuthMetadataProcessor(processor);
     }
@@ -270,8 +271,8 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> {
     }
     EXPECT_TRUE(is_server_started_);
     ChannelArguments args;
-    auto channel_creds =
-        GetChannelCredentials(GetParam().credentials_type, &args);
+    auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
+        GetParam().credentials_type, &args);
     if (!user_agent_prefix_.empty()) {
       args.SetUserAgentPrefix(user_agent_prefix_);
     }
@@ -1520,11 +1521,18 @@ std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
   std::vector<TestScenario> scenarios;
   std::vector<grpc::string> credentials_types;
   if (test_secure) {
-    credentials_types = GetSecureCredentialsTypeList();
+    credentials_types =
+        GetCredentialsProvider()->GetSecureCredentialsTypeList();
   }
   if (test_insecure) {
-    credentials_types.push_back(kInsecureCredentialsType);
+    // Only add insecure credentials type when it is registered with the
+    // provider. User may create providers that do not have insecure.
+    if (GetCredentialsProvider()->GetChannelCredentials(
+            kInsecureCredentialsType, nullptr) != nullptr) {
+      credentials_types.push_back(kInsecureCredentialsType);
+    }
   }
+  GPR_ASSERT(!credentials_types.empty());
   for (auto it = credentials_types.begin(); it != credentials_types.end();
        ++it) {
     scenarios.emplace_back(false, *it);
@@ -1541,7 +1549,7 @@ INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
 
 INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
                         ::testing::ValuesIn(CreateTestScenarios(false, true,
-                                                                false)));
+                                                                true)));
 
 INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
                         ::testing::ValuesIn(CreateTestScenarios(true, true,
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index c58910abc3..3265554444 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -49,6 +49,7 @@
 #include "test/cpp/util/test_config.h"
 
 DEFINE_bool(use_tls, false, "Whether to use tls.");
+DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
 DEFINE_bool(use_test_ca, false, "False to use SSL roots for google");
 DEFINE_int32(server_port, 0, "Server port.");
 DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index c171969e14..91564e5dce 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -50,8 +50,10 @@
 #include "src/cpp/client/secure_credentials.h"
 #include "test/core/security/oauth2_utils.h"
 #include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 DECLARE_bool(use_tls);
+DECLARE_string(custom_credentials_type);
 DECLARE_bool(use_test_ca);
 DECLARE_int32(server_port);
 DECLARE_string(server_host);
@@ -114,8 +116,12 @@ std::shared_ptr<Channel> CreateChannelForTestCase(
     creds = AccessTokenCredentials(raw_token);
     GPR_ASSERT(creds);
   }
-  return CreateTestChannel(host_port, FLAGS_server_host_override, FLAGS_use_tls,
-                           !FLAGS_use_test_ca, creds);
+  if (FLAGS_custom_credentials_type.empty()) {
+    return CreateTestChannel(host_port, FLAGS_server_host_override,
+                             FLAGS_use_tls, !FLAGS_use_test_ca, creds);
+  } else {
+    return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds);
+  }
 }
 
 }  // namespace testing
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 67456ce18b..956840ba70 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -56,6 +56,7 @@
 #include "test/cpp/util/test_config.h"
 
 DEFINE_bool(use_tls, false, "Whether to use tls.");
+DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
 DEFINE_int32(port, 0, "Server port.");
 DEFINE_int32(max_send_message_size, -1, "The maximum send message size.");
 
diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc
index 8b0b511bcb..d395f50fa5 100644
--- a/test/cpp/interop/server_helper.cc
+++ b/test/cpp/interop/server_helper.cc
@@ -39,23 +39,23 @@
 #include <grpc++/security/server_credentials.h>
 
 #include "src/core/lib/surface/call_test_only.h"
-#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 DECLARE_bool(use_tls);
+DECLARE_string(custom_credentials_type);
 
 namespace grpc {
 namespace testing {
 
 std::shared_ptr<ServerCredentials> CreateInteropServerCredentials() {
-  if (FLAGS_use_tls) {
-    SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
-                                                        test_server1_cert};
-    SslServerCredentialsOptions ssl_opts;
-    ssl_opts.pem_root_certs = "";
-    ssl_opts.pem_key_cert_pairs.push_back(pkcp);
-    return SslServerCredentials(ssl_opts);
+  if (!FLAGS_custom_credentials_type.empty()) {
+    return GetCredentialsProvider()->GetServerCredentials(
+        FLAGS_custom_credentials_type);
+  } else if (FLAGS_use_tls) {
+    return GetCredentialsProvider()->GetServerCredentials(kTlsCredentialsType);
   } else {
-    return InsecureServerCredentials();
+    return GetCredentialsProvider()->GetServerCredentials(
+        kInsecureCredentialsType);
   }
 }
 
diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index 97e658869f..562522de77 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -147,6 +147,7 @@ DEFINE_bool(do_not_abort_on_transient_failures, true,
 // Options from client.cc (for compatibility with interop test).
 // TODO(sreek): Consolidate overlapping options
 DEFINE_bool(use_tls, false, "Whether to use tls.");
+DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
 DEFINE_bool(use_test_ca, false, "False to use SSL roots for google");
 DEFINE_int32(server_port, 0, "Server port.");
 DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index fe8b5d5423..ad62e03490 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -35,11 +35,37 @@
 
 #include <grpc++/create_channel.h>
 #include <grpc++/security/credentials.h>
+#include <grpc/support/log.h>
 
-#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 
+namespace {
+
+const char kProdTlsCredentialsType[] = "prod_ssl";
+
+class SslCredentialProvider : public testing::CredentialTypeProvider {
+ public:
+  std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+      grpc::ChannelArguments* args) override {
+    return SslCredentials(SslCredentialsOptions());
+  }
+  std::shared_ptr<ServerCredentials> GetServerCredentials() override {
+    return nullptr;
+  }
+};
+
+gpr_once g_once_init_add_prod_ssl_provider = GPR_ONCE_INIT;
+// Register ssl with non-test roots type to the credentials provider.
+void AddProdSslType() {
+  testing::GetCredentialsProvider()->AddSecureType(
+      kProdTlsCredentialsType, std::unique_ptr<testing::CredentialTypeProvider>(
+                                   new SslCredentialProvider));
+}
+
+}  // namespace
+
 // When ssl is enabled, if server is empty, override_hostname is used to
 // create channel. Otherwise, connect to server and override hostname if
 // override_hostname is provided.
@@ -61,16 +87,22 @@ std::shared_ptr<Channel> CreateTestChannel(
     const std::shared_ptr<CallCredentials>& creds,
     const ChannelArguments& args) {
   ChannelArguments channel_args(args);
+  std::shared_ptr<ChannelCredentials> channel_creds;
   if (enable_ssl) {
-    const char* roots_certs = use_prod_roots ? "" : test_root_cert;
-    SslCredentialsOptions ssl_opts = {roots_certs, "", ""};
-
-    std::shared_ptr<ChannelCredentials> channel_creds =
-        SslCredentials(ssl_opts);
-
-    if (!server.empty() && !override_hostname.empty()) {
-      channel_args.SetSslTargetNameOverride(override_hostname);
+    if (use_prod_roots) {
+      gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType);
+      channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials(
+          kProdTlsCredentialsType, &channel_args);
+      if (!server.empty() && !override_hostname.empty()) {
+        channel_args.SetSslTargetNameOverride(override_hostname);
+      }
+    } else {
+      // override_hostname is discarded as the provider handles it.
+      channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials(
+          testing::kTlsCredentialsType, &channel_args);
     }
+    GPR_ASSERT(channel_creds != nullptr);
+
     const grpc::string& connect_to =
         server.empty() ? override_hostname : server;
     if (creds.get()) {
@@ -103,4 +135,18 @@ std::shared_ptr<Channel> CreateTestChannel(const grpc::string& server,
   return CreateTestChannel(server, "foo.test.google.fr", enable_ssl, false);
 }
 
+std::shared_ptr<Channel> CreateTestChannel(
+    const grpc::string& server, const grpc::string& credential_type,
+    const std::shared_ptr<CallCredentials>& creds) {
+  ChannelArguments channel_args;
+  std::shared_ptr<ChannelCredentials> channel_creds =
+      testing::GetCredentialsProvider()->GetChannelCredentials(credential_type,
+                                                               &channel_args);
+  GPR_ASSERT(channel_creds != nullptr);
+  if (creds.get()) {
+    channel_creds = CompositeChannelCredentials(channel_creds, creds);
+  }
+  return CreateCustomChannel(server, channel_creds, channel_args);
+}
+
 }  // namespace grpc
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index 4ff666dc1b..ce71a97edb 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -59,6 +59,10 @@ std::shared_ptr<Channel> CreateTestChannel(
     const std::shared_ptr<CallCredentials>& creds,
     const ChannelArguments& args);
 
+std::shared_ptr<Channel> CreateTestChannel(
+    const grpc::string& server, const grpc::string& credential_type,
+    const std::shared_ptr<CallCredentials>& creds);
+
 }  // namespace grpc
 
 #endif  // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H
diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc
index 0456b96667..909b02a701 100644
--- a/test/cpp/util/test_credentials_provider.cc
+++ b/test/cpp/util/test_credentials_provider.cc
@@ -43,25 +43,9 @@
 #include "test/core/end2end/data/ssl_test_data.h"
 
 namespace grpc {
+namespace testing {
 namespace {
 
-using grpc::testing::CredentialTypeProvider;
-
-// Provide test credentials. Thread-safe.
-class CredentialsProvider {
- public:
-  virtual ~CredentialsProvider() {}
-
-  virtual void AddSecureType(
-      const grpc::string& type,
-      std::unique_ptr<CredentialTypeProvider> type_provider) = 0;
-  virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
-      const grpc::string& type, ChannelArguments* args) = 0;
-  virtual std::shared_ptr<ServerCredentials> GetServerCredentials(
-      const grpc::string& type) = 0;
-  virtual std::vector<grpc::string> GetSecureCredentialsTypeList() = 0;
-};
-
 class DefaultCredentialsProvider : public CredentialsProvider {
  public:
   ~DefaultCredentialsProvider() override {}
@@ -145,37 +129,21 @@ class DefaultCredentialsProvider : public CredentialsProvider {
       added_secure_type_providers_;
 };
 
-gpr_once g_once_init_provider = GPR_ONCE_INIT;
 CredentialsProvider* g_provider = nullptr;
 
-void CreateDefaultProvider() { g_provider = new DefaultCredentialsProvider; }
-
-CredentialsProvider* GetProvider() {
-  gpr_once_init(&g_once_init_provider, &CreateDefaultProvider);
-  return g_provider;
-}
-
 }  // namespace
 
-namespace testing {
-
-void AddSecureType(const grpc::string& type,
-                   std::unique_ptr<CredentialTypeProvider> type_provider) {
-  GetProvider()->AddSecureType(type, std::move(type_provider));
-}
-
-std::shared_ptr<ChannelCredentials> GetChannelCredentials(
-    const grpc::string& type, ChannelArguments* args) {
-  return GetProvider()->GetChannelCredentials(type, args);
-}
-
-std::shared_ptr<ServerCredentials> GetServerCredentials(
-    const grpc::string& type) {
-  return GetProvider()->GetServerCredentials(type);
+CredentialsProvider* GetCredentialsProvider() {
+  if (g_provider == nullptr) {
+    g_provider = new DefaultCredentialsProvider;
+  }
+  return g_provider;
 }
 
-std::vector<grpc::string> GetSecureCredentialsTypeList() {
-  return GetProvider()->GetSecureCredentialsTypeList();
+void SetCredentialsProvider(CredentialsProvider* provider) {
+  // For now, forbids overriding provider.
+  GPR_ASSERT(g_provider == nullptr);
+  g_provider = provider;
 }
 
 }  // namespace testing
diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h
index 1fb311e556..0bc52ebe4d 100644
--- a/test/cpp/util/test_credentials_provider.h
+++ b/test/cpp/util/test_credentials_provider.h
@@ -59,23 +59,39 @@ class CredentialTypeProvider {
   virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0;
 };
 
-// Add a secure type in addition to the defaults above
-// (kInsecureCredentialsType, kTlsCredentialsType) that can be returned from the
-// functions below.
-void AddSecureType(const grpc::string& type,
-                   std::unique_ptr<CredentialTypeProvider> type_provider);
-
-// Provide channel credentials according to the given type. Alter the channel
-// arguments if needed.
-std::shared_ptr<ChannelCredentials> GetChannelCredentials(
-    const grpc::string& type, ChannelArguments* args);
-
-// Provide server credentials according to the given type.
-std::shared_ptr<ServerCredentials> GetServerCredentials(
-    const grpc::string& type);
-
-// Provide a list of secure credentials type.
-std::vector<grpc::string> GetSecureCredentialsTypeList();
+// Provide test credentials. Thread-safe.
+class CredentialsProvider {
+ public:
+  virtual ~CredentialsProvider() {}
+
+  // Add a secure type in addition to the defaults. The default provider has
+  // (kInsecureCredentialsType, kTlsCredentialsType).
+  virtual void AddSecureType(
+      const grpc::string& type,
+      std::unique_ptr<CredentialTypeProvider> type_provider) = 0;
+
+  // Provide channel credentials according to the given type. Alter the channel
+  // arguments if needed. Return nullptr if type is not registered.
+  virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+      const grpc::string& type, ChannelArguments* args) = 0;
+
+  // Provide server credentials according to the given type.
+  // Return nullptr if type is not registered.
+  virtual std::shared_ptr<ServerCredentials> GetServerCredentials(
+      const grpc::string& type) = 0;
+
+  // Provide a list of secure credentials type.
+  virtual std::vector<grpc::string> GetSecureCredentialsTypeList() = 0;
+};
+
+// Get the current provider. Create a default one if not set.
+// Not thread-safe.
+CredentialsProvider* GetCredentialsProvider();
+
+// Set the global provider. Takes ownership. The previous set provider will be
+// destroyed.
+// Not thread-safe.
+void SetCredentialsProvider(CredentialsProvider* provider);
 
 }  // namespace testing
 }  // namespace grpc
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 8849dcc600..72f0b08d9e 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -5447,6 +5447,7 @@
       "gpr", 
       "grpc", 
       "grpc++", 
+      "grpc++_test_util", 
       "grpc_test_util"
     ], 
     "headers": [
diff --git a/vsprojects/vcxproj/interop_server_helper/interop_server_helper.vcxproj b/vsprojects/vcxproj/interop_server_helper/interop_server_helper.vcxproj
index 4c99988a34..377cadc1a1 100644
--- a/vsprojects/vcxproj/interop_server_helper/interop_server_helper.vcxproj
+++ b/vsprojects/vcxproj/interop_server_helper/interop_server_helper.vcxproj
@@ -154,6 +154,9 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
-- 
GitLab


From a6e796f58f691ae130fe6e3b8ed746d67e189d79 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 11 Jan 2017 13:49:43 -0800
Subject: [PATCH 282/344] ignore core counts and core lists in qps json driver

---
 test/cpp/qps/driver.cc                        | 91 +------------------
 test/cpp/qps/driver.h                         |  3 +-
 test/cpp/qps/qps_json_driver.cc               |  5 +-
 .../run_tests/performance/scenario_config.py  | 24 +++--
 4 files changed, 18 insertions(+), 105 deletions(-)

diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 93ef32db77..42722b7e9d 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -76,30 +76,6 @@ static std::string get_host(const std::string& worker) {
   return s;
 }
 
-static std::unordered_map<string, std::deque<int>> get_hosts_and_cores(
-    const deque<string>& workers) {
-  std::unordered_map<string, std::deque<int>> hosts;
-  for (auto it = workers.begin(); it != workers.end(); it++) {
-    const string host = get_host(*it);
-    if (hosts.find(host) == hosts.end()) {
-      auto stub = WorkerService::NewStub(
-          CreateChannel(*it, InsecureChannelCredentials()));
-      grpc::ClientContext ctx;
-      ctx.set_wait_for_ready(true);
-      CoreRequest dummy;
-      CoreResponse cores;
-      grpc::Status s = stub->CoreCount(&ctx, dummy, &cores);
-      GPR_ASSERT(s.ok());
-      std::deque<int> dq;
-      for (int i = 0; i < cores.cores(); i++) {
-        dq.push_back(i);
-      }
-      hosts[host] = dq;
-    }
-  }
-  return hosts;
-}
-
 static deque<string> get_workers(const string& env_name) {
   char* env = gpr_getenv(env_name.c_str());
   if (!env) {
@@ -210,7 +186,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
     const ClientConfig& initial_client_config, size_t num_clients,
     const ServerConfig& initial_server_config, size_t num_servers,
     int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
-    const char* qps_server_target_override, bool configure_core_lists) {
+    const char* qps_server_target_override) {
   // Log everything from the driver
   gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
 
@@ -279,9 +255,6 @@ std::unique_ptr<ScenarioResult> RunScenario(
   std::vector<ServerData> servers(num_servers);
   std::unordered_map<string, std::deque<int>> hosts_cores;
 
-  if (configure_core_lists) {
-    hosts_cores = get_hosts_and_cores(workers);
-  }
   for (size_t i = 0; i < num_servers; i++) {
     gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
             workers[i].c_str(), i);
@@ -289,37 +262,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
         CreateChannel(workers[i], InsecureChannelCredentials()));
 
     ServerConfig server_config = initial_server_config;
-    int server_core_limit = initial_server_config.core_limit();
-    int client_core_limit = initial_client_config.core_limit();
-
-    if (configure_core_lists) {
-      string host_str(get_host(workers[i]));
-      if (server_core_limit == 0 && client_core_limit > 0) {
-        // In this case, limit the server cores if it matches the
-        // same host as one or more clients
-        const auto& dq = hosts_cores.at(host_str);
-        bool match = false;
-        int limit = dq.size();
-        for (size_t cli = 0; cli < num_clients; cli++) {
-          if (host_str == get_host(workers[cli + num_servers])) {
-            limit -= client_core_limit;
-            match = true;
-          }
-        }
-        if (match) {
-          GPR_ASSERT(limit > 0);
-          server_core_limit = limit;
-        }
-      }
-      if (server_core_limit > 0) {
-        auto& dq = hosts_cores.at(host_str);
-        GPR_ASSERT(dq.size() >= static_cast<size_t>(server_core_limit));
-        gpr_log(GPR_INFO, "Setting server core_list");
-        for (int core = 0; core < server_core_limit; core++) {
-          server_config.add_core_list(dq.front());
-          dq.pop_front();
-        }
-      }
+    if(server_config.core_limit() != 0) {
+      gpr_log(GPR_WARN, "server config core limit is set but ignored by driver");
     }
 
     ServerArgs args;
@@ -364,33 +308,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
         CreateChannel(worker, InsecureChannelCredentials()));
     ClientConfig per_client_config = client_config;
 
-    int server_core_limit = initial_server_config.core_limit();
-    int client_core_limit = initial_client_config.core_limit();
-    if (configure_core_lists &&
-        ((server_core_limit > 0) || (client_core_limit > 0))) {
-      auto& dq = hosts_cores.at(get_host(worker));
-      if (client_core_limit == 0) {
-        // limit client cores if it matches a server host
-        bool match = false;
-        int limit = dq.size();
-        for (size_t srv = 0; srv < num_servers; srv++) {
-          if (get_host(worker) == get_host(workers[srv])) {
-            match = true;
-          }
-        }
-        if (match) {
-          GPR_ASSERT(limit > 0);
-          client_core_limit = limit;
-        }
-      }
-      if (client_core_limit > 0) {
-        GPR_ASSERT(dq.size() >= static_cast<size_t>(client_core_limit));
-        gpr_log(GPR_INFO, "Setting client core_list");
-        for (int core = 0; core < client_core_limit; core++) {
-          per_client_config.add_core_list(dq.front());
-          dq.pop_front();
-        }
-      }
+    if(initial_client_config.core_limit() != 0) {
+      gpr_log(GPR_WARN, "client config core limit set but ignored");
     }
 
     // Reduce channel count so that total channels specified is held regardless
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index b5c8152e1b..e72d30a4ef 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -46,8 +46,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
     const grpc::testing::ClientConfig& client_config, size_t num_clients,
     const grpc::testing::ServerConfig& server_config, size_t num_servers,
     int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
-    const char* qps_server_target_override = "",
-    bool configure_core_lists = true);
+    const char* qps_server_target_override = "");
 
 bool RunQuit();
 }  // namespace testing
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index da835b995a..ca4c686578 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -70,9 +70,6 @@ DEFINE_double(error_tolerance, 0.01,
 DEFINE_string(qps_server_target_override, "",
               "Override QPS server target to configure in client configs."
               "Only applicable if there is a single benchmark server.");
-DEFINE_bool(configure_core_lists, true,
-            "Provide 'core_list' parameters to workers. Value determined "
-            "by cores available and 'core_limit' parameters of the scenarios.");
 
 namespace grpc {
 namespace testing {
@@ -85,7 +82,7 @@ static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
       scenario.server_config(), scenario.num_servers(),
       scenario.warmup_seconds(), scenario.benchmark_seconds(),
       scenario.spawn_local_worker_count(),
-      FLAGS_qps_server_target_override.c_str(), FLAGS_configure_core_lists);
+      FLAGS_qps_server_target_override.c_str());
 
   // Amend the result with scenario config. Eventually we should adjust
   // RunScenario contract so we don't need to touch the result here.
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index c3c5ece362..b20bb40eb1 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -109,7 +109,6 @@ def _ping_pong_scenario(name, rpc_type,
                         unconstrained_client=None,
                         client_language=None,
                         server_language=None,
-                        server_core_limit=0,
                         async_server_threads=0,
                         warmup_seconds=WARMUP_SECONDS,
                         categories=DEFAULT_CATEGORIES,
@@ -136,7 +135,6 @@ def _ping_pong_scenario(name, rpc_type,
     'server_config': {
       'server_type': server_type,
       'security_params': _get_secargs(secure),
-      'core_limit': server_core_limit,
       'async_server_threads': async_server_threads,
     },
     'warmup_seconds': warmup_seconds,
@@ -200,7 +198,7 @@ class CXXLanguage:
           rpc_type='STREAMING',
           client_type='ASYNC_CLIENT',
           server_type='ASYNC_GENERIC_SERVER',
-          use_generic_payload=True, server_core_limit=1, async_server_threads=1,
+          use_generic_payload=True, async_server_threads=1,
           secure=secure,
           categories=smoketest_categories)
 
@@ -219,7 +217,7 @@ class CXXLanguage:
           client_type='ASYNC_CLIENT',
           server_type='ASYNC_GENERIC_SERVER',
           unconstrained_client='async', use_generic_payload=True,
-          server_core_limit=1, async_server_threads=1,
+          async_server_threads=1,
           secure=secure)
 
       yield _ping_pong_scenario(
@@ -248,7 +246,7 @@ class CXXLanguage:
               rpc_type=rpc_type.upper(),
               client_type='%s_CLIENT' % synchronicity.upper(),
               server_type='%s_SERVER' % synchronicity.upper(),
-              server_core_limit=1, async_server_threads=1,
+              async_server_threads=1,
               secure=secure)
 
           yield _ping_pong_scenario(
@@ -332,13 +330,13 @@ class CSharpLanguage:
     yield _ping_pong_scenario(
         'csharp_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY',
         client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1,
+        server_language='c++', async_server_threads=1,
         categories=[SMOKETEST, SCALABLE])
 
     yield _ping_pong_scenario(
         'csharp_to_cpp_protobuf_async_streaming_ping_pong', rpc_type='STREAMING',
         client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1)
+        server_language='c++', async_server_threads=1)
 
     yield _ping_pong_scenario(
         'csharp_to_cpp_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY',
@@ -414,13 +412,13 @@ class NodeLanguage:
     #yield _ping_pong_scenario(
     #    'node_to_cpp_protobuf_async_unary_ping_pong', rpc_type='UNARY',
     #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-    #    server_language='c++', server_core_limit=1, async_server_threads=1)
+    #    server_language='c++', async_server_threads=1)
 
     # TODO(jtattermusch): make this scenario work
     #yield _ping_pong_scenario(
     #    'node_to_cpp_protobuf_async_streaming_ping_pong', rpc_type='STREAMING',
     #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-    #    server_language='c++', server_core_limit=1, async_server_threads=1)
+    #    server_language='c++', async_server_threads=1)
 
   def __str__(self):
     return 'node'
@@ -469,13 +467,13 @@ class PythonLanguage:
     yield _ping_pong_scenario(
         'python_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY',
         client_type='SYNC_CLIENT', server_type='ASYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1,
+        server_language='c++', async_server_threads=1,
         categories=[SMOKETEST, SCALABLE])
 
     yield _ping_pong_scenario(
         'python_to_cpp_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING',
         client_type='SYNC_CLIENT', server_type='ASYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1)
+        server_language='c++', async_server_threads=1)
 
   def __str__(self):
     return 'python'
@@ -516,12 +514,12 @@ class RubyLanguage:
     yield _ping_pong_scenario(
         'ruby_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY',
         client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1)
+        server_language='c++', async_server_threads=1)
 
     yield _ping_pong_scenario(
         'ruby_to_cpp_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING',
         client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
-        server_language='c++', server_core_limit=1, async_server_threads=1)
+        server_language='c++', async_server_threads=1)
 
   def __str__(self):
     return 'ruby'
-- 
GitLab


From 8a0ef63dea1546a04fd00c6be7f4f223e3e559f1 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 11 Jan 2017 13:52:01 -0800
Subject: [PATCH 283/344] remove LimitCores in c++ benchmark

---
 test/cpp/qps/client.h       |  2 +-
 test/cpp/qps/limit_cores.cc | 87 -------------------------------------
 test/cpp/qps/limit_cores.h  | 49 ---------------------
 test/cpp/qps/server.h       |  2 +-
 4 files changed, 2 insertions(+), 138 deletions(-)
 delete mode 100644 test/cpp/qps/limit_cores.cc
 delete mode 100644 test/cpp/qps/limit_cores.h

diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index fdd78ebb89..3018c21f32 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -374,7 +374,7 @@ class ClientImpl : public Client {
   ClientImpl(const ClientConfig& config,
              std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
                  create_stub)
-      : cores_(LimitCores(config.core_list().data(), config.core_list_size())),
+      : cores_(gpr_cpu_num_cores()),
         channels_(config.client_channels()),
         create_stub_(create_stub) {
     for (int i = 0; i < config.client_channels(); i++) {
diff --git a/test/cpp/qps/limit_cores.cc b/test/cpp/qps/limit_cores.cc
deleted file mode 100644
index b5c222542b..0000000000
--- a/test/cpp/qps/limit_cores.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *
- * Copyright 2016, 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.
- *
- */
-
-#include "test/cpp/qps/limit_cores.h"
-
-#include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-
-#ifdef GPR_CPU_LINUX
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sched.h>
-
-namespace grpc {
-namespace testing {
-
-int LimitCores(const int* cores, int cores_size) {
-  const int num_cores = gpr_cpu_num_cores();
-  int cores_set = 0;
-
-  cpu_set_t* cpup = CPU_ALLOC(num_cores);
-  GPR_ASSERT(cpup);
-  const size_t size = CPU_ALLOC_SIZE(num_cores);
-  CPU_ZERO_S(size, cpup);
-
-  if (cores_size > 0) {
-    for (int i = 0; i < cores_size; i++) {
-      if (cores[i] < num_cores) {
-        CPU_SET_S(cores[i], size, cpup);
-        cores_set++;
-      }
-    }
-  } else {
-    for (int i = 0; i < num_cores; i++) {
-      CPU_SET_S(i, size, cpup);
-      cores_set++;
-    }
-  }
-  bool affinity_set = (sched_setaffinity(0, size, cpup) == 0);
-  CPU_FREE(cpup);
-  return affinity_set ? cores_set : num_cores;
-}
-
-}  // namespace testing
-}  // namespace grpc
-#else
-namespace grpc {
-namespace testing {
-
-// LimitCores is not currently supported for non-Linux platforms
-int LimitCores(const int*, int) { return gpr_cpu_num_cores(); }
-
-}  // namespace testing
-}  // namespace grpc
-#endif
diff --git a/test/cpp/qps/limit_cores.h b/test/cpp/qps/limit_cores.h
deleted file mode 100644
index 5482904a3c..0000000000
--- a/test/cpp/qps/limit_cores.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef TEST_QPS_LIMIT_CORES_H
-#define TEST_QPS_LIMIT_CORES_H
-
-namespace grpc {
-namespace testing {
-/// LimitCores: allow this worker to only run on the cores specified in the
-/// array \a cores, which is of length \a cores_size.
-///
-/// LimitCores takes array and size arguments (instead of vector) for direct
-/// conversion from repeated field of protobuf. Use a cores_size of 0 to remove
-/// existing limits (from an empty repeated field)
-int LimitCores(const int *cores, int cores_size);
-}  // namespace testing
-}  // namespace grpc
-
-#endif  // TEST_QPS_LIMIT_CORES_H
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index c3d18e5789..5f4c34c9ad 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -51,7 +51,7 @@ namespace testing {
 class Server {
  public:
   explicit Server(const ServerConfig& config) : timer_(new UsageTimer) {
-    cores_ = LimitCores(config.core_list().data(), config.core_list_size());
+    cores_ = gpr_cpu_num_cores();
     if (config.port()) {
       port_ = config.port();
 
-- 
GitLab


From 6ff1ca4871d73dd018e33bfca0df896570c0d429 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 11 Jan 2017 14:25:55 -0800
Subject: [PATCH 284/344] re-run generate project to build qps json driver

---
 Makefile                                      |   3 -
 build.yaml                                    |   1 -
 test/cpp/qps/client.h                         |   1 -
 test/cpp/qps/driver.cc                        |   4 +-
 test/cpp/qps/server.h                         |   1 -
 .../generated/sources_and_headers.json        |   1 -
 tools/run_tests/generated/tests.json          | 136 +++++++++---------
 vsprojects/vcxproj/qps/qps.vcxproj            |   2 -
 vsprojects/vcxproj/qps/qps.vcxproj.filters    |   3 -
 9 files changed, 70 insertions(+), 82 deletions(-)

diff --git a/Makefile b/Makefile
index 8f7328ae28..314db9f4c1 100644
--- a/Makefile
+++ b/Makefile
@@ -5200,7 +5200,6 @@ LIBQPS_SRC = \
     test/cpp/qps/client_async.cc \
     test/cpp/qps/client_sync.cc \
     test/cpp/qps/driver.cc \
-    test/cpp/qps/limit_cores.cc \
     test/cpp/qps/parse_json.cc \
     test/cpp/qps/qps_worker.cc \
     test/cpp/qps/report.cc \
@@ -5256,7 +5255,6 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/limit_cores.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
@@ -16812,7 +16810,6 @@ test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
 test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
 test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
 test/cpp/qps/driver.cc: $(OPENSSL_DEP)
-test/cpp/qps/limit_cores.cc: $(OPENSSL_DEP)
 test/cpp/qps/parse_json.cc: $(OPENSSL_DEP)
 test/cpp/qps/qps_worker.cc: $(OPENSSL_DEP)
 test/cpp/qps/report.cc: $(OPENSSL_DEP)
diff --git a/build.yaml b/build.yaml
index de9d253ef1..8f217682c2 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1306,7 +1306,6 @@ libs:
   - test/cpp/qps/client_async.cc
   - test/cpp/qps/client_sync.cc
   - test/cpp/qps/driver.cc
-  - test/cpp/qps/limit_cores.cc
   - test/cpp/qps/parse_json.cc
   - test/cpp/qps/qps_worker.cc
   - test/cpp/qps/report.cc
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 3018c21f32..ae7264c9c1 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -51,7 +51,6 @@
 
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/interarrival.h"
-#include "test/cpp/qps/limit_cores.h"
 #include "test/cpp/qps/usage_timer.h"
 #include "test/cpp/util/create_test_channel.h"
 
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 42722b7e9d..7494ced460 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -263,7 +263,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
 
     ServerConfig server_config = initial_server_config;
     if(server_config.core_limit() != 0) {
-      gpr_log(GPR_WARN, "server config core limit is set but ignored by driver");
+      gpr_log(GPR_ERROR, "server config core limit is set but ignored by driver");
     }
 
     ServerArgs args;
@@ -309,7 +309,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
     ClientConfig per_client_config = client_config;
 
     if(initial_client_config.core_limit() != 0) {
-      gpr_log(GPR_WARN, "client config core limit set but ignored");
+      gpr_log(GPR_ERROR, "client config core limit set but ignored");
     }
 
     // Reduce channel count so that total channels specified is held regardless
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 5f4c34c9ad..821d5935be 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -42,7 +42,6 @@
 #include "src/proto/grpc/testing/messages.grpc.pb.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
-#include "test/cpp/qps/limit_cores.h"
 #include "test/cpp/qps/usage_timer.h"
 
 namespace grpc {
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 6ae269cc20..deadec29a4 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -5545,7 +5545,6 @@
       "test/cpp/qps/driver.h", 
       "test/cpp/qps/histogram.h", 
       "test/cpp/qps/interarrival.h", 
-      "test/cpp/qps/limit_cores.cc", 
       "test/cpp/qps/limit_cores.h", 
       "test/cpp/qps/parse_json.cc", 
       "test/cpp/qps/parse_json.h", 
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b76263b8b9..7b46e8256c 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -36756,7 +36756,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -36780,7 +36780,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"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\": 0, \"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\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": 0, \"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\": 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": [
@@ -36804,7 +36804,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": 0, \"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\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_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\": 0, \"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\": 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": [
@@ -36828,7 +36828,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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\": \"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": [
@@ -36852,7 +36852,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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\": \"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": [
@@ -36876,7 +36876,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_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\": \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -36900,7 +36900,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -36924,7 +36924,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -36948,7 +36948,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -36972,7 +36972,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -36996,7 +36996,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37020,7 +37020,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37044,7 +37044,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37068,7 +37068,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37092,7 +37092,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37116,7 +37116,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37140,7 +37140,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37164,7 +37164,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37188,7 +37188,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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": [
@@ -37212,7 +37212,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_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\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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": [
@@ -37236,7 +37236,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_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": [
@@ -37260,7 +37260,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_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": [
@@ -37284,7 +37284,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -37308,7 +37308,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37332,7 +37332,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37356,7 +37356,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37380,7 +37380,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37404,7 +37404,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37428,7 +37428,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37452,7 +37452,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37476,7 +37476,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37500,7 +37500,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37524,7 +37524,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37548,7 +37548,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37572,7 +37572,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37609,7 +37609,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"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\": 0, \"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\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": 0, \"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\": 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": [
@@ -37646,7 +37646,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": 0, \"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\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_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\": 0, \"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\": 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": [
@@ -37683,7 +37683,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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\": \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -37720,7 +37720,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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\": \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -37757,7 +37757,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_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\": \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -37794,7 +37794,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37831,7 +37831,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37868,7 +37868,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -37905,7 +37905,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -37942,7 +37942,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -37979,7 +37979,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38016,7 +38016,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38053,7 +38053,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -38090,7 +38090,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38127,7 +38127,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38164,7 +38164,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -38201,7 +38201,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38238,7 +38238,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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": [
@@ -38275,7 +38275,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_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\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_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": [
@@ -38312,7 +38312,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38349,7 +38349,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38386,7 +38386,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38423,7 +38423,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38460,7 +38460,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -38497,7 +38497,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38534,7 +38534,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38571,7 +38571,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -38608,7 +38608,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38645,7 +38645,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38682,7 +38682,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
@@ -38719,7 +38719,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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, 
     "ci_platforms": [
@@ -38756,7 +38756,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"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": [
@@ -38793,7 +38793,7 @@
   {
     "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, \"core_limit\": 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}}}]}"
+      "{\"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": [
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj b/vsprojects/vcxproj/qps/qps.vcxproj
index 004cf7c9f0..8b98b5e67c 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj
+++ b/vsprojects/vcxproj/qps/qps.vcxproj
@@ -207,8 +207,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\driver.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\parse_json.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.cc">
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj.filters b/vsprojects/vcxproj/qps/qps.vcxproj.filters
index d3a440ba73..111b133d71 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj.filters
+++ b/vsprojects/vcxproj/qps/qps.vcxproj.filters
@@ -25,9 +25,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\driver.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.cc">
-      <Filter>test\cpp\qps</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\parse_json.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
-- 
GitLab


From 8ad258a450cd7800984be3da48e21bd1484c9673 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 15:22:29 -0800
Subject: [PATCH 285/344] Add missing include for GPRAPI

---
 include/grpc/support/log_windows.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/grpc/support/log_windows.h b/include/grpc/support/log_windows.h
index 12bf8cc1f5..943a8e908b 100644
--- a/include/grpc/support/log_windows.h
+++ b/include/grpc/support/log_windows.h
@@ -34,6 +34,8 @@
 #ifndef GRPC_SUPPORT_LOG_WINDOWS_H
 #define GRPC_SUPPORT_LOG_WINDOWS_H
 
+#include <grpc/impl/codegen/port_platform.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
-- 
GitLab


From 20ce39a4fe664b73cd271044e59377ee4d91d950 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Wed, 11 Jan 2017 15:44:13 -0800
Subject: [PATCH 286/344] remove limit_cores.h from build.yaml

---
 build.yaml                                         | 1 -
 tools/run_tests/generated/sources_and_headers.json | 2 --
 vsprojects/vcxproj/qps/qps.vcxproj                 | 1 -
 vsprojects/vcxproj/qps/qps.vcxproj.filters         | 3 ---
 4 files changed, 7 deletions(-)

diff --git a/build.yaml b/build.yaml
index 8f217682c2..8f478066f7 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1289,7 +1289,6 @@ libs:
   - test/cpp/qps/driver.h
   - test/cpp/qps/histogram.h
   - test/cpp/qps/interarrival.h
-  - test/cpp/qps/limit_cores.h
   - test/cpp/qps/parse_json.h
   - test/cpp/qps/qps_worker.h
   - test/cpp/qps/report.h
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index deadec29a4..8bf9dfd617 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -5525,7 +5525,6 @@
       "test/cpp/qps/driver.h", 
       "test/cpp/qps/histogram.h", 
       "test/cpp/qps/interarrival.h", 
-      "test/cpp/qps/limit_cores.h", 
       "test/cpp/qps/parse_json.h", 
       "test/cpp/qps/qps_worker.h", 
       "test/cpp/qps/report.h", 
@@ -5545,7 +5544,6 @@
       "test/cpp/qps/driver.h", 
       "test/cpp/qps/histogram.h", 
       "test/cpp/qps/interarrival.h", 
-      "test/cpp/qps/limit_cores.h", 
       "test/cpp/qps/parse_json.cc", 
       "test/cpp/qps/parse_json.h", 
       "test/cpp/qps/qps_worker.cc", 
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj b/vsprojects/vcxproj/qps/qps.vcxproj
index 8b98b5e67c..2d7892683a 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj
+++ b/vsprojects/vcxproj/qps/qps.vcxproj
@@ -151,7 +151,6 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\driver.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\histogram.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\interarrival.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\report.h" />
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj.filters b/vsprojects/vcxproj/qps/qps.vcxproj.filters
index 111b133d71..f25be9af19 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj.filters
+++ b/vsprojects/vcxproj/qps/qps.vcxproj.filters
@@ -60,9 +60,6 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\interarrival.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.h">
-      <Filter>test\cpp\qps</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
-- 
GitLab


From 4314043e407763918de6696366919d0fa8afac83 Mon Sep 17 00:00:00 2001
From: Noah Eisen <ncteisen@gmail.com>
Date: Wed, 11 Jan 2017 15:59:33 -0800
Subject: [PATCH 287/344] Update negative-http2-interop-test-descriptions.md

---
 doc/negative-http2-interop-test-descriptions.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/negative-http2-interop-test-descriptions.md b/doc/negative-http2-interop-test-descriptions.md
index 1ded97b503..b64fe6a024 100644
--- a/doc/negative-http2-interop-test-descriptions.md
+++ b/doc/negative-http2-interop-test-descriptions.md
@@ -50,6 +50,7 @@ the user application having to do a thing.
 
 Client Procedure:
  1. Client sends two UnaryCall requests (and sleeps for 1 second in-between).
+ TODO: resolve [9300](https://github.com/grpc/grpc/issues/9300) and remove the 1 second sleep
  
     ```
     {
-- 
GitLab


From 43dc9ed3b7faf24c02896b2307739630a3c92154 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 16:05:25 -0800
Subject: [PATCH 288/344] Add licenses to all BUILD files and missing copyright

---
 bazel/BUILD                            | 31 ++++++++++++++++++++++++++
 src/proto/grpc/testing/BUILD           | 30 +++++++++++++++++++++++++
 src/proto/grpc/testing/duplicate/BUILD | 30 +++++++++++++++++++++++++
 test/core/bad_client/BUILD             |  2 ++
 test/core/bad_ssl/BUILD                |  2 ++
 test/core/end2end/BUILD                |  2 ++
 test/core/end2end/fuzzers/BUILD        |  2 ++
 test/core/http/BUILD                   |  2 ++
 test/core/json/BUILD                   |  2 ++
 test/core/nanopb/BUILD                 |  2 ++
 test/core/transport/chttp2/BUILD       |  2 ++
 test/core/util/BUILD                   | 29 ++++++++++++++++++++++++
 12 files changed, 136 insertions(+)

diff --git a/bazel/BUILD b/bazel/BUILD
index 940a379404..2d3c576aa0 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -1,3 +1,34 @@
+# Copyright 2016, 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.
+
+licenses(["notice"])  # 3-clause BSD
+
 package(default_visibility = ["//:__subpackages__"])
 
 load(":cc_grpc_library.bzl", "cc_grpc_library")
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index f9f9cbceaf..8d5c32d35c 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -1,3 +1,33 @@
+# Copyright 2016, 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.
+
+licenses(["notice"])  # 3-clause BSD
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/src/proto/grpc/testing/duplicate/BUILD b/src/proto/grpc/testing/duplicate/BUILD
index 255e699bec..f58de9bec6 100644
--- a/src/proto/grpc/testing/duplicate/BUILD
+++ b/src/proto/grpc/testing/duplicate/BUILD
@@ -1,3 +1,33 @@
+# Copyright 2016, 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.
+
+licenses(["notice"])  # 3-clause BSD
 
 package(default_visibility = ["//visibility:public"])
 
diff --git a/test/core/bad_client/BUILD b/test/core/bad_client/BUILD
index 5406eb9a4b..6b06955efe 100644
--- a/test/core/bad_client/BUILD
+++ b/test/core/bad_client/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load(":generate_tests.bzl", "grpc_bad_client_tests")
 
 grpc_bad_client_tests()
diff --git a/test/core/bad_ssl/BUILD b/test/core/bad_ssl/BUILD
index 630733dd4d..288788a52d 100644
--- a/test/core/bad_ssl/BUILD
+++ b/test/core/bad_ssl/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load(":generate_tests.bzl", "grpc_bad_ssl_tests")
 
 grpc_bad_ssl_tests()
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index 681cea1de7..a40fb8e083 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load(":generate_tests.bzl", "grpc_end2end_tests")
 
 cc_library(
diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD
index 2adda560b4..4d98aa0725 100644
--- a/test/core/end2end/fuzzers/BUILD
+++ b/test/core/end2end/fuzzers/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 
 grpc_fuzzer(
diff --git a/test/core/http/BUILD b/test/core/http/BUILD
index 58d265bd8f..037ede3cd1 100644
--- a/test/core/http/BUILD
+++ b/test/core/http/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 
 grpc_fuzzer(
diff --git a/test/core/json/BUILD b/test/core/json/BUILD
index 4b3fbd6076..05d4c6e0c5 100644
--- a/test/core/json/BUILD
+++ b/test/core/json/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 
 grpc_fuzzer(
diff --git a/test/core/nanopb/BUILD b/test/core/nanopb/BUILD
index bdf79b7fef..b02d750f32 100644
--- a/test/core/nanopb/BUILD
+++ b/test/core/nanopb/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 
 grpc_fuzzer(
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
index 5dd205174f..94b4830138 100644
--- a/test/core/transport/chttp2/BUILD
+++ b/test/core/transport/chttp2/BUILD
@@ -27,6 +27,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.
 
+licenses(["notice"])  # 3-clause BSD
+
 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
 
 grpc_fuzzer(
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index e50e595d03..e7ed5ea2f5 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -1,4 +1,33 @@
+# Copyright 2016, 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.
 
+licenses(["notice"])  # 3-clause BSD
 
 cc_library(
     name = "gpr_test_util",
-- 
GitLab


From d36a53156c9591cd68e5ea17d7579cda896e2840 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 16:14:44 -0800
Subject: [PATCH 289/344] Add missing include for size_t

---
 test/core/util/memory_counters.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h
index f332816501..b9b2b3adda 100644
--- a/test/core/util/memory_counters.h
+++ b/test/core/util/memory_counters.h
@@ -34,6 +34,8 @@
 #ifndef GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H
 #define GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H
 
+#include <stddef.h>
+
 struct grpc_memory_counters {
   size_t total_size_relative;
   size_t total_size_absolute;
-- 
GitLab


From 015998f7708843ead6379ac5e6d6963603d200ea Mon Sep 17 00:00:00 2001
From: Adele Zhou <adelez@adelez2.mtv.corp.google.com>
Date: Tue, 6 Dec 2016 16:05:07 -0800
Subject: [PATCH 290/344] Add perf link

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 70cf9fcc30..174e861f59 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,8 @@ See [INSTALL](INSTALL.md) for installation instructions for various platforms.
 
 See [tools/run_tests](tools/run_tests) for more guidance on how to run various test suites (e.g. unit tests, interop tests, benchmarks)
 
+See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5712453606309888) for the performance numbers for v1.0.x.
+
 #Repository Structure & Status
 
 This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core).
-- 
GitLab


From 122c687d61aac26d228da9bb6ed2a6237be55d93 Mon Sep 17 00:00:00 2001
From: Stanley Cheung <stanleycheung@google.com>
Date: Wed, 11 Jan 2017 19:35:17 -0800
Subject: [PATCH 291/344] Fix various PHP bugs

---
 src/php/bin/generate_proto_php.sh | 21 +++++++++++++--------
 src/php/lib/Grpc/BaseStub.php     |  6 +++---
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh
index c558bc5769..06cd769330 100755
--- a/src/php/bin/generate_proto_php.sh
+++ b/src/php/bin/generate_proto_php.sh
@@ -39,10 +39,12 @@ protoc --proto_path=src/proto/math \
 
 # replace the Empty message with EmptyMessage
 # because Empty is a PHP reserved word
-sed -i 's/message Empty/message EmptyMessage/g' \
-    src/proto/grpc/testing/empty.proto
-sed -i 's/grpc\.testing\.Empty/grpc\.testing\.EmptyMessage/g' \
-    src/proto/grpc/testing/test.proto
+sed 's/message Empty/message EmptyMessage/g' \
+  src/proto/grpc/testing/empty.proto > empty.proto
+mv empty.proto ./src/proto/grpc/testing
+sed 's/grpc\.testing\.Empty/grpc\.testing\.EmptyMessage/g' \
+  src/proto/grpc/testing/test.proto > test.proto
+mv test.proto ./src/proto/grpc/testing
 
 protoc --proto_path=. \
        --php_out=src/php/tests/interop \
@@ -53,7 +55,10 @@ protoc --proto_path=. \
        src/proto/grpc/testing/test.proto
 
 # change it back
-sed -i 's/message EmptyMessage/message Empty/g' \
-    src/proto/grpc/testing/empty.proto
-sed -i 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \
-    src/proto/grpc/testing/test.proto
+sed 's/message EmptyMessage/message Empty/g' \
+  src/proto/grpc/testing/empty.proto > empty.proto
+mv empty.proto ./src/proto/grpc/testing
+sed 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \
+  src/proto/grpc/testing/test.proto > test.proto
+mv test.proto ./src/proto/grpc/testing
+
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index aec60af094..a9e77b9396 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -271,7 +271,7 @@ class BaseStub
      * @return ClientStreamingSurfaceActiveCall The active call object
      */
     public function _clientStreamRequest($method,
-                                         callable $deserialize,
+                                         $deserialize,
                                          array $metadata = [],
                                          array $options = [])
     {
@@ -307,7 +307,7 @@ class BaseStub
      */
     public function _serverStreamRequest($method,
                                          $argument,
-                                         callable $deserialize,
+                                         $deserialize,
                                          array $metadata = [],
                                          array $options = [])
     {
@@ -340,7 +340,7 @@ class BaseStub
      * @return BidiStreamingSurfaceActiveCall The active call object
      */
     public function _bidiRequest($method,
-                                 callable $deserialize,
+                                 $deserialize,
                                  array $metadata = [],
                                  array $options = [])
     {
-- 
GitLab


From 90cd2789457a466c208a46bbaf413cfe2af57bd8 Mon Sep 17 00:00:00 2001
From: Stanley Cheung <stanleycheung@google.com>
Date: Wed, 11 Jan 2017 21:38:33 -0800
Subject: [PATCH 292/344] PHP: use a macro to specify extension src dir

---
 config.m4 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/config.m4 b/config.m4
index 12b10578e8..85549e5f42 100644
--- a/config.m4
+++ b/config.m4
@@ -5,9 +5,9 @@ if test "$PHP_GRPC" != "no"; then
   dnl Write more examples of tests here...
 
   dnl # --with-grpc -> add include path
-  PHP_ADD_INCLUDE(../../grpc/include)
-  PHP_ADD_INCLUDE(../../grpc/src/php/ext/grpc)
-  PHP_ADD_INCLUDE(../../grpc/third_party/boringssl/include)
+  PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
+  PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
+  PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
 
   LIBS="-lpthread $LIBS"
 
-- 
GitLab


From a2341eaed05cb5713dc95ff52fe59730a006f389 Mon Sep 17 00:00:00 2001
From: yang-g <yangg@google.com>
Date: Wed, 11 Jan 2017 23:01:24 -0800
Subject: [PATCH 293/344] omg it is 2017

---
 bazel/BUILD                            | 2 +-
 src/proto/grpc/testing/BUILD           | 2 +-
 src/proto/grpc/testing/duplicate/BUILD | 2 +-
 test/core/util/BUILD                   | 2 +-
 tools/distrib/check_copyright.py       | 1 +
 5 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/bazel/BUILD b/bazel/BUILD
index 2d3c576aa0..fe776b20ef 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2016, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 8d5c32d35c..283740839d 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2016, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/proto/grpc/testing/duplicate/BUILD b/src/proto/grpc/testing/duplicate/BUILD
index f58de9bec6..8fc5a96af4 100644
--- a/src/proto/grpc/testing/duplicate/BUILD
+++ b/src/proto/grpc/testing/duplicate/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2016, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index e7ed5ea2f5..8769683b23 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2016, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index 718bb563f3..c993407eb2 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -90,6 +90,7 @@ LICENSE_PREFIX = {
   'Makefile':   r'#\s*',
   'Dockerfile': r'#\s*',
   'LICENSE':    '',
+  'BUILD':      r'#\s*',
 }
 
 _EXEMPT = frozenset((
-- 
GitLab


From 3aab96f56c7de370070e9966cf3728fbcd1018dd Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 11 Jan 2017 16:12:46 +0100
Subject: [PATCH 294/344] successfuly compile gRPC with cmake+Ninja

---
 CMakeLists.txt                    | 8 +++++++-
 templates/CMakeLists.txt.template | 8 +++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd271d472d..9e6b5f6bee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,7 +66,13 @@ set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")
 set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
 if (MSVC)
-  add_definitions( -D_WIN32_WINNT=0x600 )
+  add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
+  # needed to compile boringssl
+  add_definitions(/wd4464 /wd4623 /wd4668 /wd4701 /wd4702 /wd4777 /wd5027)
+  # needed to compile protobuf
+  add_definitions(/wd4065 /wd4506)
+  # TODO(jtattermusch): revisit C4267 occurrences throughout the code
+  add_definitions(/wd4267)
 endif()
 
 if (gRPC_USE_PROTO_LITE)
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index c3c636c6af..8d49abeffd 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -84,7 +84,13 @@
   set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
   if (MSVC)
-    add_definitions( -D_WIN32_WINNT=0x600 )
+    add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
+    # needed to compile boringssl
+    add_definitions(/wd4464 /wd4623 /wd4668 /wd4701 /wd4702 /wd4777 /wd5027)
+    # needed to compile protobuf
+    add_definitions(/wd4065 /wd4506)
+    # TODO(jtattermusch): revisit C4267 occurrences throughout the code
+    add_definitions(/wd4267)
   endif()
 
   if (gRPC_USE_PROTO_LITE)
-- 
GitLab


From af7b87f8eba17ec4ea4e87e19ebdb6935aadedc7 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 12 Jan 2017 09:41:03 +0100
Subject: [PATCH 295/344] remove unneeded/broken targets from CMakeLists.exe

---
 CMakeLists.txt                    | 68 -------------------------------
 templates/CMakeLists.txt.template |  9 +++-
 2 files changed, 7 insertions(+), 70 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e6b5f6bee..4627c10e2e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1589,45 +1589,6 @@ if (gRPC_INSTALL)
 endif()
 
   
-add_library(grpc++_reflection
-  src/cpp/ext/proto_server_reflection.cc
-  src/cpp/ext/proto_server_reflection_plugin.cc
-  src/proto/grpc/reflection/v1alpha/reflection.proto
-)
-
-target_include_directories(grpc++_reflection
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
-  PRIVATE ${BORINGSSL_ROOT_DIR}/include
-  PRIVATE ${PROTOBUF_ROOT_DIR}/src
-  PRIVATE ${ZLIB_INCLUDE_DIR}
-  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
-)
-
-target_link_libraries(grpc++_reflection
-  grpc++
-)
-
-foreach(_hdr
-  include/grpc++/ext/proto_server_reflection_plugin.h
-)
-  string(REPLACE "include/" "" _path ${_hdr})
-  get_filename_component(_path ${_path} PATH)
-  install(FILES ${_hdr}
-    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
-  )
-endforeach()
-
-  
-if (gRPC_INSTALL)
-  install(TARGETS grpc++_reflection EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
-  
 add_library(grpc++_unsecure
   src/cpp/client/insecure_credentials.cc
   src/cpp/common/insecure_create_auth_context.cc
@@ -1828,35 +1789,6 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
-add_library(grpc_csharp_ext
-  src/csharp/ext/grpc_csharp_ext.c
-)
-
-target_include_directories(grpc_csharp_ext
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
-  PRIVATE ${BORINGSSL_ROOT_DIR}/include
-  PRIVATE ${PROTOBUF_ROOT_DIR}/src
-  PRIVATE ${ZLIB_INCLUDE_DIR}
-  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
-)
-
-target_link_libraries(grpc_csharp_ext
-  grpc
-  gpr
-)
-
-
-  
-if (gRPC_INSTALL)
-  install(TARGETS grpc_csharp_ext EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
 
 
 add_executable(gen_hpack_tables
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 8d49abeffd..028c1b8c32 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -194,14 +194,19 @@
   endif()
 
   % for lib in libs:
-  % if lib.build in ["all", "protoc", "tool"]:
+  % if lib.build in ["all", "protoc", "tool"] and lib.language in ['c', 'c++']:
+  ## TODO(jtattermusch): grpc++_reflection includes .proto files
+  ## which is not yet supported and thus fails the entire build.
+  ## Re-enable once fixed.
+  % if lib.name != 'grpc++_reflection':
     ${cc_library(lib)}
     ${cc_install(lib)}
   % endif
+  % endif
   % endfor
 
   % for tgt in targets:
-  % if tgt.build in ["all", "protoc", "tool"]:
+  % if tgt.build in ["all", "protoc", "tool"] and tgt.language in ['c', 'c++']:
   ${cc_binary(tgt)}
   ${cc_install(tgt)}
   % endif
-- 
GitLab


From 8e883b23bae2d2dd3367d3d1bcbe0d95c1d7c31d Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Thu, 12 Jan 2017 11:45:52 +0100
Subject: [PATCH 296/344] Makefile.template: fixed a few variables names, and
 added a missing variable on dll name

---
 templates/Makefile.template | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/templates/Makefile.template b/templates/Makefile.template
index 1b6bc0e93d..230f16c0c8 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1303,7 +1303,7 @@
   % if not lib.get('external_deps', None):
   	$(E) "[INSTALL] Installing $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})"
   	$(Q) $(INSTALL) -d $(prefix)/lib
-  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]})
+  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})
   ifeq ($(SYSTEM),MINGW32)
   	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
   else ifneq ($(SYSTEM),Darwin)
@@ -1520,7 +1520,7 @@
         link_libs = link_libs + ' -l' + dep
         lib_deps = lib_deps + ' $(LIBDIR)/$(CONFIG)/lib' + dep + '.$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
         mingw_libs = mingw_libs + ' -l' + dep + '-imp'
-        mingw_lib_deps = mingw_lib_deps + ' $(LIBDIR)/$(CONFIG)/' + dep + '.$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
+        mingw_lib_deps = mingw_lib_deps + ' $(LIBDIR)/$(CONFIG)/' + dep + '$(SHARED_VERSION_' + lang_to_var[dep_lib.language] + ').$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
 
     security = lib.get('secure', 'check')
     if security == True:
@@ -1558,11 +1558,11 @@
   	$(E) "[LD]      Linking $@"
   	$(Q) mkdir -p `dirname $@`
   ifeq ($(SYSTEM),Darwin)
-  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
+  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   else
   	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.core_version.major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
-  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
-  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
+  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
+  	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
   endif
   endif
   % endif
-- 
GitLab


From 34f58fe42c0ede74555ccaa54e9769ec10bb9fca Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 12 Jan 2017 14:14:05 +0100
Subject: [PATCH 297/344] remove not-yet-useful projects from grpc.sln

---
 templates/vsprojects/grpc.sln.template |  2 +-
 vsprojects/grpc.sln                    | 66 --------------------------
 2 files changed, 1 insertion(+), 67 deletions(-)

diff --git a/templates/vsprojects/grpc.sln.template b/templates/vsprojects/grpc.sln.template
index ded98383da..0b28e936be 100644
--- a/templates/vsprojects/grpc.sln.template
+++ b/templates/vsprojects/grpc.sln.template
@@ -2,6 +2,6 @@
 --- |
   <%namespace file="sln_defs.include" import="gen_solution"/>\
   <%
-  solution_projects = [p for p in vsprojects if p.build not in ['protoc', 'test', 'fuzzer'] and p.language in ['c', 'c++'] and p.vs_proj_dir == '.' and not (p.build == 'private' and p.language == 'c++')]
+  solution_projects = [p for p in vsprojects if p.build not in ['protoc', 'test', 'fuzzer'] and p.language in ['c', 'c++'] and p.vs_proj_dir == '.' and not (p.build == 'private' and p.language == 'c++') and not p.name in ['z', 'boringssl', 'grpc++_reflection']]
   %>\
   ${gen_solution(solution_projects, use_dlls='yes')}
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 63be171c6e..591d3b5edb 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -3,11 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl", "vcxproj\.\boringssl\boringssl.vcxproj", "{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_hpack_tables", "vcxproj\.\gen_hpack_tables\gen_hpack_tables.vcxproj", "{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -56,14 +51,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_reflection", "vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj", "{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB} = {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -161,11 +148,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tcp_server", "vcxproj\
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "z", "vcxproj\.\z\z.vcxproj", "{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -178,22 +160,6 @@ Global
 		Release-DLL|x64 = Release-DLL|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.ActiveCfg = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.ActiveCfg = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.ActiveCfg = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.Build.0 = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.Build.0 = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.Build.0 = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.Build.0 = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.Build.0 = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.Build.0 = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.ActiveCfg = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.Build.0 = Release|x64
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.ActiveCfg = Debug|x64
 		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.ActiveCfg = Release|Win32
@@ -306,22 +272,6 @@ Global
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.ActiveCfg = Debug|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.ActiveCfg = Debug|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.ActiveCfg = Release|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.ActiveCfg = Release|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.Build.0 = Debug|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.Build.0 = Debug|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.Build.0 = Release|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.Build.0 = Release|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.Build.0 = Debug|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.Build.0 = Release|Win32
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.ActiveCfg = Release|x64
-		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.Build.0 = Release|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32
@@ -482,22 +432,6 @@ Global
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.Build.0 = Release|Win32
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.ActiveCfg = Release|x64
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.Build.0 = Release|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|Win32.ActiveCfg = Debug|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|x64.ActiveCfg = Debug|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release|Win32.ActiveCfg = Release|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release|x64.ActiveCfg = Release|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|Win32.Build.0 = Debug|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|x64.Build.0 = Debug|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release|Win32.Build.0 = Release|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release|x64.Build.0 = Release|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug-DLL|x64.Build.0 = Debug|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|Win32.Build.0 = Release|Win32
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|x64.ActiveCfg = Release|x64
-		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
-- 
GitLab


From c79da7b383b2e927c2fc03860fcf641e76d694a4 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 12 Jan 2017 14:57:24 +0100
Subject: [PATCH 298/344] fix compilation of grpc_dll project

---
 src/core/ext/census/tracing.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/core/ext/census/tracing.c b/src/core/ext/census/tracing.c
index 8f0e12296d..3b5d6dab2b 100644
--- a/src/core/ext/census/tracing.c
+++ b/src/core/ext/census/tracing.c
@@ -31,19 +31,15 @@
  *
  */
 
-//#include "src/core/ext/census/tracing.h"
-
 #include <grpc/census.h>
 
 /* TODO(aveitch): These are all placeholder implementations. */
 
-// int census_trace_mask(const census_context *context) {
-//   return CENSUS_TRACE_MASK_NONE;
-// }
-
-// void census_set_trace_mask(int trace_mask) {}
+int census_trace_mask(const census_context *context) {
+  return CENSUS_TRACE_MASK_NONE;
+}
 
-// void census_trace_print(census_context *context, uint32_t type,
-//                         const char *buffer, size_t n) {}
+void census_set_trace_mask(int trace_mask) {}
 
-// void SetTracerParams(const Params& params);
+void census_trace_print(census_context *context, uint32_t type,
+                        const char *buffer, size_t n) {}
-- 
GitLab


From fe71d7fc5fb9d730cda1579baba65da7389ecb49 Mon Sep 17 00:00:00 2001
From: Stanley Cheung <stanleycheung@google.com>
Date: Thu, 12 Jan 2017 11:13:23 -0800
Subject: [PATCH 299/344] Fix the template as well

---
 templates/config.m4.template | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/templates/config.m4.template b/templates/config.m4.template
index 5847d456f5..f5f1d23088 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -7,9 +7,9 @@
     dnl Write more examples of tests here...
 
     dnl # --with-grpc -> add include path
-    PHP_ADD_INCLUDE(../../grpc/include)
-    PHP_ADD_INCLUDE(../../grpc/src/php/ext/grpc)
-    PHP_ADD_INCLUDE(../../grpc/third_party/boringssl/include)
+    PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
+    PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
+    PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/third_party/boringssl/include)
 
     LIBS="-lpthread $LIBS"
 
-- 
GitLab


From 62a7ca8c9516b071593e7cea63d3466678589085 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Thu, 12 Jan 2017 11:32:15 -0800
Subject: [PATCH 300/344] re-run clang-format.sh

---
 test/cpp/qps/driver.cc          |  7 ++++---
 test/cpp/qps/qps_json_driver.cc | 12 ++++++------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 7494ced460..74fe3662c1 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -262,8 +262,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
         CreateChannel(workers[i], InsecureChannelCredentials()));
 
     ServerConfig server_config = initial_server_config;
-    if(server_config.core_limit() != 0) {
-      gpr_log(GPR_ERROR, "server config core limit is set but ignored by driver");
+    if (server_config.core_limit() != 0) {
+      gpr_log(GPR_ERROR,
+              "server config core limit is set but ignored by driver");
     }
 
     ServerArgs args;
@@ -308,7 +309,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
         CreateChannel(worker, InsecureChannelCredentials()));
     ClientConfig per_client_config = client_config;
 
-    if(initial_client_config.core_limit() != 0) {
+    if (initial_client_config.core_limit() != 0) {
       gpr_log(GPR_ERROR, "client config core limit set but ignored");
     }
 
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index ca4c686578..db77a82746 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -77,12 +77,12 @@ namespace testing {
 static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
                                                     bool* success) {
   std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
-  auto result = RunScenario(
-      scenario.client_config(), scenario.num_clients(),
-      scenario.server_config(), scenario.num_servers(),
-      scenario.warmup_seconds(), scenario.benchmark_seconds(),
-      scenario.spawn_local_worker_count(),
-      FLAGS_qps_server_target_override.c_str());
+  auto result =
+      RunScenario(scenario.client_config(), scenario.num_clients(),
+                  scenario.server_config(), scenario.num_servers(),
+                  scenario.warmup_seconds(), scenario.benchmark_seconds(),
+                  scenario.spawn_local_worker_count(),
+                  FLAGS_qps_server_target_override.c_str());
 
   // Amend the result with scenario config. Eventually we should adjust
   // RunScenario contract so we don't need to touch the result here.
-- 
GitLab


From c518198d9adc423442082130dace7230b5df6e50 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Thu, 12 Jan 2017 12:40:11 -0800
Subject: [PATCH 301/344] run_tests: set Node runtime variable when using
 default compiler

---
 tools/run_tests/run_tests.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index ab719a6727..5aae3432e1 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -377,6 +377,7 @@ class NodeLanguage(object):
                                          'node4', 'node5', 'node6',
                                          'node7', 'electron1.3'])
     if self.args.compiler == 'default':
+      self.runtime = 'node'
       self.node_version = '4'
     else:
       if self.args.compiler.startswith('electron'):
-- 
GitLab


From abe9757da1cda736db7305823aa3269454949cb5 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Thu, 12 Jan 2017 22:06:04 +0100
Subject: [PATCH 302/344] Makefile: fixed a few variables names, and added a
 missing variable on dll name

---
 Makefile | 80 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/Makefile b/Makefile
index 024ca8f12a..932f606831 100644
--- a/Makefile
+++ b/Makefile
@@ -2337,7 +2337,7 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
 install-shared_c: shared_c strip-shared_c install-pkg-config_c
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2346,7 +2346,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2355,7 +2355,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet-imp.a $(prefix)/lib/libgrpc_cronet-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2364,7 +2364,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2381,7 +2381,7 @@ endif
 install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-config_cxx
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2390,7 +2390,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet-imp.a $(prefix)/lib/libgrpc++_cronet-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2399,7 +2399,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection-imp.a $(prefix)/lib/libgrpc++_reflection-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2408,7 +2408,7 @@ else ifneq ($(SYSTEM),Darwin)
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2425,7 +2425,7 @@ endif
 install-shared_csharp: shared_csharp strip-shared_csharp
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
 ifeq ($(SYSTEM),MINGW32)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
 else ifneq ($(SYSTEM),Darwin)
@@ -2590,11 +2590,11 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.2 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -2913,11 +2913,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3186,11 +3186,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(L
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3686,11 +3686,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.2
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.2
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
 endif
 endif
 
@@ -3941,7 +3941,7 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
@@ -3950,11 +3950,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC+
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4316,7 +4316,7 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_cronet-imp
@@ -4325,11 +4325,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(L
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4439,7 +4439,7 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++-imp
@@ -4448,11 +4448,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP):
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -4831,7 +4831,7 @@ endif
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT_CORE)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
@@ -4840,11 +4840,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
 endif
 endif
 
@@ -5330,11 +5330,11 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHA
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
-	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
 endif
 endif
 
-- 
GitLab


From 4dd97f901939c75ad9b77dc490cc642b2bc52161 Mon Sep 17 00:00:00 2001
From: Makarand Dharmapurikar <makarandd@google.com>
Date: Thu, 12 Jan 2017 15:04:31 -0800
Subject: [PATCH 303/344] dockerfile update for http2_badserver_interop

added h2 and twisted python modules
---
 tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
index 05e963d1e6..03ff179f71 100644
--- a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
@@ -46,6 +46,7 @@ RUN apt-get update && apt-get install -y \
 RUN pip install pip --upgrade
 RUN pip install virtualenv
 RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+RUN pip install twisted h2
 
 # Define the default command.
 CMD ["bash"]
-- 
GitLab


From 50c878088a0aa43208609dce30ec578cf10296c0 Mon Sep 17 00:00:00 2001
From: Stanley Cheung <stanleycheung@google.com>
Date: Thu, 12 Jan 2017 15:49:56 -0800
Subject: [PATCH 304/344] Use tmp file instead of writing to current directory

---
 src/php/bin/generate_proto_php.sh | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh
index 06cd769330..416fa9df97 100755
--- a/src/php/bin/generate_proto_php.sh
+++ b/src/php/bin/generate_proto_php.sh
@@ -39,12 +39,13 @@ protoc --proto_path=src/proto/math \
 
 # replace the Empty message with EmptyMessage
 # because Empty is a PHP reserved word
+output_file=$(mktemp)
 sed 's/message Empty/message EmptyMessage/g' \
-  src/proto/grpc/testing/empty.proto > empty.proto
-mv empty.proto ./src/proto/grpc/testing
+  src/proto/grpc/testing/empty.proto > $output_file
+mv $output_file ./src/proto/grpc/testing/empty.proto
 sed 's/grpc\.testing\.Empty/grpc\.testing\.EmptyMessage/g' \
-  src/proto/grpc/testing/test.proto > test.proto
-mv test.proto ./src/proto/grpc/testing
+  src/proto/grpc/testing/test.proto > $output_file
+mv $output_file ./src/proto/grpc/testing/test.proto
 
 protoc --proto_path=. \
        --php_out=src/php/tests/interop \
@@ -56,9 +57,9 @@ protoc --proto_path=. \
 
 # change it back
 sed 's/message EmptyMessage/message Empty/g' \
-  src/proto/grpc/testing/empty.proto > empty.proto
-mv empty.proto ./src/proto/grpc/testing
+  src/proto/grpc/testing/empty.proto > $output_file
+mv $output_file ./src/proto/grpc/testing/empty.proto
 sed 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \
-  src/proto/grpc/testing/test.proto > test.proto
-mv test.proto ./src/proto/grpc/testing
+  src/proto/grpc/testing/test.proto > $output_file
+mv $output_file ./src/proto/grpc/testing/test.proto
 
-- 
GitLab


From 88162f82c407e3025d3e157705b3aade63da675f Mon Sep 17 00:00:00 2001
From: Michael Lumish <mlumish@google.com>
Date: Thu, 12 Jan 2017 17:37:58 -0800
Subject: [PATCH 305/344] Do not use OPENSSL_NO_THREAD normally for Node on
 Windows

---
 binding.gyp                    | 8 ++++++--
 templates/binding.gyp.template | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/binding.gyp b/binding.gyp
index bb1c7f0a3a..fd48da875a 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -54,14 +54,18 @@
           'GRPC_UV'
         ]
       }],
+      ['runtime=="electron"', {
+        "defines": [
+          'OPENSSL_NO_THREADS'
+        ]
+      }],
       # This is the condition for using boringssl
       ['OS=="win" or runtime=="electron"', {
         "include_dirs": [
           "third_party/boringssl/include"
         ],
         "defines": [
-          'OPENSSL_NO_ASM',
-          'OPENSSL_NO_THREADS'
+          'OPENSSL_NO_ASM'
         ]
       }, {
         # Based on logic above, we know that this must be a non-Windows system
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 9b9e4e116d..7570aa5e7e 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -56,14 +56,18 @@
             'GRPC_UV'
           ]
         }],
+        ['runtime=="electron"', {
+          "defines": [
+            'OPENSSL_NO_THREADS'
+          ]
+        }],
         # This is the condition for using boringssl
         ['OS=="win" or runtime=="electron"', {
           "include_dirs": [
             "third_party/boringssl/include"
           ],
           "defines": [
-            'OPENSSL_NO_ASM',
-            'OPENSSL_NO_THREADS'
+            'OPENSSL_NO_ASM'
           ]
         }, {
           # Based on logic above, we know that this must be a non-Windows system
-- 
GitLab


From 24263c3f7a3b04f073712e40376829e47772d7db Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Wed, 11 Jan 2017 01:03:09 +0100
Subject: [PATCH 306/344] Fixing a few items with the new Bazel BUILD system:

-) Fixing Bazel 0.4.x breakage
-) Adding helloworld BUILD examples
-) Fixing grpc++ missing files.
-) Adding helloworld example as a test for Bazel basic.
---
 BUILD                                      |  2 +
 bazel/BUILD                                |  8 +++-
 bazel/cc_grpc_library.bzl                  |  1 -
 bazel/generate_cc.bzl                      |  4 +-
 examples/cpp/helloworld/BUILD              | 42 +++++++++++++++++
 examples/cpp/helloworld/greeter_client.cc  |  4 ++
 examples/cpp/helloworld/greeter_server.cc  |  4 ++
 examples/protos/BUILD                      | 52 ++++++++++++++++++++++
 tools/jenkins/run_bazel_basic_in_docker.sh |  2 +-
 9 files changed, 115 insertions(+), 4 deletions(-)
 create mode 100644 examples/cpp/helloworld/BUILD
 create mode 100644 examples/protos/BUILD

diff --git a/BUILD b/BUILD
index 3122dc0a32..2c9a6f35a1 100644
--- a/BUILD
+++ b/BUILD
@@ -1078,6 +1078,7 @@ grpc_cc_library(
         "src/cpp/common/completion_queue_cc.cc",
         "src/cpp/common/core_codegen.cc",
         "src/cpp/common/rpc_method.cc",
+        "src/cpp/common/version_cc.cc",
         "src/cpp/server/async_generic_service.cc",
         "src/cpp/server/create_default_thread_pool.cc",
         "src/cpp/server/dynamic_thread_pool.cc",
@@ -1086,6 +1087,7 @@ grpc_cc_library(
         "src/cpp/server/server_context.cc",
         "src/cpp/server/server_credentials.cc",
         "src/cpp/server/server_posix.cc",
+        "src/cpp/thread_manager/thread_manager.cc",
         "src/cpp/util/byte_buffer_cc.cc",
         "src/cpp/util/slice_cc.cc",
         "src/cpp/util/status.cc",
diff --git a/bazel/BUILD b/bazel/BUILD
index 940a379404..44a1673212 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -2,8 +2,14 @@ package(default_visibility = ["//:__subpackages__"])
 
 load(":cc_grpc_library.bzl", "cc_grpc_library")
 
+proto_library(
+    name = "well_known_protos_list",
+    srcs = ["@submodule_protobuf//:well_known_protos"],
+)
+
 cc_grpc_library(
     name = "well_known_protos",
-    srcs = "@submodule_protobuf//:well_known_protos",
+    srcs = "well_known_protos_list",
+    deps = [],
     proto_only = True,
 )
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
index e1dd27b0c3..9020eacb74 100644
--- a/bazel/cc_grpc_library.bzl
+++ b/bazel/cc_grpc_library.bzl
@@ -44,7 +44,6 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
         **kwargs
     )
 
-  if not proto_only:
     native.cc_library(
         name = name,
         srcs = [":" + codegen_grpc_target, ":" + codegen_target],
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index 3665733681..d49cbe8d72 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -24,13 +24,15 @@ def generate_cc_impl(ctx):
   if ctx.executable.plugin:
     arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
     arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+    additional_input = [ctx.executable.plugin]
   else:
     arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+    additional_input = []
   arguments += ["-I{0}={0}".format(include.path) for include in includes]
   arguments += [proto.path for proto in protos]
 
   ctx.action(
-      inputs = protos + includes,
+      inputs = protos + includes + additional_input,
       outputs = out_files,
       executable = ctx.executable._protoc,
       arguments = arguments,
diff --git a/examples/cpp/helloworld/BUILD b/examples/cpp/helloworld/BUILD
new file mode 100644
index 0000000000..b9c3f5dfbe
--- /dev/null
+++ b/examples/cpp/helloworld/BUILD
@@ -0,0 +1,42 @@
+# 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.
+
+cc_binary(
+    name = "greeter_client",
+    srcs = ["greeter_client.cc"],
+    deps = ["//examples/protos:helloworld"],
+    defines = ["BAZEL_BUILD"],
+)
+
+cc_binary(
+    name = "greeter_server",
+    srcs = ["greeter_server.cc"],
+    deps = ["//examples/protos:helloworld"],
+    defines = ["BAZEL_BUILD"],
+)
diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
index 61f3953056..8ee33b1383 100644
--- a/examples/cpp/helloworld/greeter_client.cc
+++ b/examples/cpp/helloworld/greeter_client.cc
@@ -37,7 +37,11 @@
 
 #include <grpc++/grpc++.h>
 
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
 #include "helloworld.grpc.pb.h"
+#endif
 
 using grpc::Channel;
 using grpc::ClientContext;
diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc
index 9eab32c62b..c8a6d8ae86 100644
--- a/examples/cpp/helloworld/greeter_server.cc
+++ b/examples/cpp/helloworld/greeter_server.cc
@@ -37,7 +37,11 @@
 
 #include <grpc++/grpc++.h>
 
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
 #include "helloworld.grpc.pb.h"
+#endif
 
 using grpc::Server;
 using grpc::ServerBuilder;
diff --git a/examples/protos/BUILD b/examples/protos/BUILD
new file mode 100644
index 0000000000..2ffdf64f9a
--- /dev/null
+++ b/examples/protos/BUILD
@@ -0,0 +1,52 @@
+# 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.
+
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+
+grpc_proto_library(
+    name = "auth_sample",
+    srcs = ["auth_sample.proto"],
+)
+
+grpc_proto_library(
+    name = "hellostreamingworld",
+    srcs = ["hellostreamingworld.proto"],
+)
+
+grpc_proto_library(
+    name = "helloworld",
+    srcs = ["helloworld.proto"],
+)
+
+grpc_proto_library(
+    name = "route_guide",
+    srcs = ["route_guide.proto"],
+)
diff --git a/tools/jenkins/run_bazel_basic_in_docker.sh b/tools/jenkins/run_bazel_basic_in_docker.sh
index 51aaa90ff8..b1d498a07d 100755
--- a/tools/jenkins/run_bazel_basic_in_docker.sh
+++ b/tools/jenkins/run_bazel_basic_in_docker.sh
@@ -39,4 +39,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc
 && git submodule update --init --reference /var/local/jenkins/grpc/${name} \
 ${name}')
 cd /var/local/git/grpc
-bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/...
+bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/cpp/...
-- 
GitLab


From 93d0b580a51af6e9c099164424040dfd4d6a71f3 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Thu, 12 Jan 2017 17:57:36 -0800
Subject: [PATCH 307/344] Properly generate electron dependencies in test
 Dockerfile from template

---
 .../test/node_jessie_x64/Dockerfile.template   | 15 +++++++++++++--
 .../dockerfile/test/node_jessie_x64/Dockerfile | 18 +++++++++++-------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
index 72b098f0c2..fa5c8c3816 100644
--- a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
@@ -28,10 +28,21 @@
   # 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 debian:jessie
-  
+
   <%include file="../../apt_get_basic.include"/>
+
+  # Install Electron apt dependencies
+  RUN apt-get update && apt-get install -y ${'\\'}
+    libasound ${'\\'}
+    libgconf-2-4 ${'\\'}
+    libgtk2.0-0 ${'\\'}
+    libnss3 ${'\\'}
+    libxss1 ${'\\'}
+    libxtst6 ${'\\'}
+    xvfb
+
   <%include file="../../python_deps.include"/>
   <%include file="../../node_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile
index 120ea59ae2..184298f913 100644
--- a/tools/dockerfile/test/node_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile
@@ -42,18 +42,12 @@ RUN apt-get update && apt-get install -y \
   git \
   golang \
   gyp \
-  libasound2 \
   lcov \
   libc6 \
   libc6-dbg \
   libc6-dev \
-  libgconf-2-4 \
   libgtest-dev \
-  libgtk2.0-0 \
-  libnss3 \
   libtool \
-  libxss1\
-  libxtst6 \
   make \
   perl \
   strace \
@@ -63,13 +57,23 @@ RUN apt-get update && apt-get install -y \
   telnet \
   unzip \
   wget \
-  xvfb \
   zip && apt-get clean
 
 #================
 # Build profiling
 RUN apt-get update && apt-get install -y time && apt-get clean
 
+
+# Install Electron apt dependencies
+RUN apt-get update && apt-get install -y \
+  libasound \
+  libgconf-2-4 \
+  libgtk2.0-0 \
+  libnss3 \
+  libxss1 \
+  libxtst6 \
+  xvfb
+
 #====================
 # Python dependencies
 
-- 
GitLab


From 06d3d4ad387a4fde43edafb8a8c218c3e5fc7fb1 Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Fri, 13 Jan 2017 12:22:24 +0100
Subject: [PATCH 308/344] Makefile.template: remove the 'imp' suffix from MINGW
 library names

---
 Makefile                    | 26 +++++++++++++-------------
 templates/Makefile.template |  4 ++--
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile
index 1f25c3859f..bec4f3172c 100644
--- a/Makefile
+++ b/Makefile
@@ -2342,7 +2342,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.a $(prefix)/lib/libgpr.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
@@ -2351,7 +2351,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
@@ -2360,7 +2360,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet-imp.a $(prefix)/lib/libgrpc_cronet-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(prefix)/lib/libgrpc_cronet.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so
@@ -2369,7 +2369,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
@@ -2386,7 +2386,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
@@ -2395,7 +2395,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet-imp.a $(prefix)/lib/libgrpc++_cronet-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(prefix)/lib/libgrpc++_cronet.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
@@ -2404,7 +2404,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection-imp.a $(prefix)/lib/libgrpc++_reflection-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
@@ -2413,7 +2413,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
@@ -2430,7 +2430,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(prefix)/lib/libgrpc_csharp_ext.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
@@ -3947,7 +3947,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4322,7 +4322,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_cronet-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4445,7 +4445,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4837,7 +4837,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 230f16c0c8..6f4a2ed644 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1305,7 +1305,7 @@
   	$(Q) $(INSTALL) -d $(prefix)/lib
   	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})
   ifeq ($(SYSTEM),MINGW32)
-  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
+  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
   else ifneq ($(SYSTEM),Darwin)
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.core_version.major}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so
@@ -1519,7 +1519,7 @@
         assert dep_lib, 'lib %s not found (in %s)' % (dep, lib.name)
         link_libs = link_libs + ' -l' + dep
         lib_deps = lib_deps + ' $(LIBDIR)/$(CONFIG)/lib' + dep + '.$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
-        mingw_libs = mingw_libs + ' -l' + dep + '-imp'
+        mingw_libs = mingw_libs + ' -l' + dep
         mingw_lib_deps = mingw_lib_deps + ' $(LIBDIR)/$(CONFIG)/' + dep + '$(SHARED_VERSION_' + lang_to_var[dep_lib.language] + ').$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
 
     security = lib.get('secure', 'check')
-- 
GitLab


From 44b2d08149af2f976eca8b7fdb155543a101faaf Mon Sep 17 00:00:00 2001
From: Mario Emmenlauer <mario@emmenlauer.de>
Date: Fri, 13 Jan 2017 12:35:49 +0100
Subject: [PATCH 309/344] Makefile.template: use import library names for
 mingw, instead of static libraries

---
 Makefile                    | 26 +++++++++++++-------------
 templates/Makefile.template |  4 ++--
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile
index bec4f3172c..504d06f4ae 100644
--- a/Makefile
+++ b/Makefile
@@ -2342,7 +2342,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.a $(prefix)/lib/libgpr.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgpr.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
@@ -2351,7 +2351,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
@@ -2360,7 +2360,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(prefix)/lib/libgrpc_cronet.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_cronet.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so
@@ -2369,7 +2369,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
@@ -2386,7 +2386,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
@@ -2395,7 +2395,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(prefix)/lib/libgrpc++_cronet.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
@@ -2404,7 +2404,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
@@ -2413,7 +2413,7 @@ endif
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
@@ -2430,7 +2430,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
 ifeq ($(SYSTEM),MINGW32)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(prefix)/lib/libgrpc_csharp_ext.a
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.2
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
@@ -3947,7 +3947,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc$(SHARED_VERSION_CORE)-dll
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4322,7 +4322,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_cronet$(SHARED_VERSION_CORE)-dll
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_CRONET_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4445,7 +4445,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++$(SHARED_VERSION_CPP)-dll
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
@@ -4837,7 +4837,7 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr$(SHARED_VERSION_CORE)-dll -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE)
 	$(E) "[LD]      Linking $@"
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 6f4a2ed644..6f4db26f2b 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1305,7 +1305,7 @@
   	$(Q) $(INSTALL) -d $(prefix)/lib
   	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]})
   ifeq ($(SYSTEM),MINGW32)
-  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
+  	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]})-dll.a $(prefix)/lib/lib${lib.name}.a
   else ifneq ($(SYSTEM),Darwin)
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.core_version.major}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so
@@ -1519,7 +1519,7 @@
         assert dep_lib, 'lib %s not found (in %s)' % (dep, lib.name)
         link_libs = link_libs + ' -l' + dep
         lib_deps = lib_deps + ' $(LIBDIR)/$(CONFIG)/lib' + dep + '.$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
-        mingw_libs = mingw_libs + ' -l' + dep
+        mingw_libs = mingw_libs + ' -l' + dep + '$(SHARED_VERSION_' + lang_to_var[dep_lib.language] + ')-dll'
         mingw_lib_deps = mingw_lib_deps + ' $(LIBDIR)/$(CONFIG)/' + dep + '$(SHARED_VERSION_' + lang_to_var[dep_lib.language] + ').$(SHARED_EXT_' + lang_to_var[dep_lib.language] + ')'
 
     security = lib.get('secure', 'check')
-- 
GitLab


From 6fb04d6924b3714baa95b69d51fa40c082578124 Mon Sep 17 00:00:00 2001
From: Yuxuan Li <yuxuanli@google.com>
Date: Fri, 18 Nov 2016 18:08:36 -0800
Subject: [PATCH 310/344] memory usage profiling for client call, client
 channel, server creation, server call and server channel.

fix bug. server: snapshot pass by pointer
---
 Makefile                                      | 104 ++++++
 build.yaml                                    |  37 ++
 test/core/memory_usage/client.c               | 314 +++++++++++++++++
 test/core/memory_usage/memory_usage_test.c    |  93 +++++
 test/core/memory_usage/server.c               | 321 ++++++++++++++++++
 tools/doxygen/Doxyfile.c++                    |  38 +--
 tools/doxygen/Doxyfile.c++.internal           |  36 +-
 tools/doxygen/Doxyfile.core                   |  34 +-
 tools/doxygen/Doxyfile.core.internal          |  62 ++--
 .../generated/sources_and_headers.json        |  51 +++
 tools/run_tests/generated/tests.json          |  20 ++
 vsprojects/buildtests_c.sln                   |  54 +++
 .../memory_profile_client.vcxproj             | 199 +++++++++++
 .../memory_profile_client.vcxproj.filters     |  21 ++
 .../memory_profile_server.vcxproj             | 199 +++++++++++
 .../memory_profile_server.vcxproj.filters     |  21 ++
 16 files changed, 1519 insertions(+), 85 deletions(-)
 create mode 100644 test/core/memory_usage/client.c
 create mode 100644 test/core/memory_usage/memory_usage_test.c
 create mode 100644 test/core/memory_usage/server.c
 create mode 100644 vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj
 create mode 100644 vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj.filters
 create mode 100644 vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj
 create mode 100644 vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj.filters

diff --git a/Makefile b/Makefile
index a26842e71b..cfd53c69f7 100644
--- a/Makefile
+++ b/Makefile
@@ -1013,6 +1013,9 @@ lame_client_test: $(BINDIR)/$(CONFIG)/lame_client_test
 lb_policies_test: $(BINDIR)/$(CONFIG)/lb_policies_test
 load_file_test: $(BINDIR)/$(CONFIG)/load_file_test
 low_level_ping_pong_benchmark: $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
+memory_profile_client: $(BINDIR)/$(CONFIG)/memory_profile_client
+memory_profile_server: $(BINDIR)/$(CONFIG)/memory_profile_server
+memory_profile_test: $(BINDIR)/$(CONFIG)/memory_profile_test
 message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
 mlog_test: $(BINDIR)/$(CONFIG)/mlog_test
 multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
@@ -1348,6 +1351,9 @@ buildtests_c: privatelibs_c \
   $(BINDIR)/$(CONFIG)/lame_client_test \
   $(BINDIR)/$(CONFIG)/lb_policies_test \
   $(BINDIR)/$(CONFIG)/load_file_test \
+  $(BINDIR)/$(CONFIG)/memory_profile_client \
+  $(BINDIR)/$(CONFIG)/memory_profile_server \
+  $(BINDIR)/$(CONFIG)/memory_profile_test \
   $(BINDIR)/$(CONFIG)/message_compress_test \
   $(BINDIR)/$(CONFIG)/mlog_test \
   $(BINDIR)/$(CONFIG)/multiple_server_queues_test \
@@ -1739,6 +1745,8 @@ test_c: buildtests_c
 	$(Q) $(BINDIR)/$(CONFIG)/lame_client_test || ( echo test lame_client_test failed ; exit 1 )
 	$(E) "[RUN]     Testing load_file_test"
 	$(Q) $(BINDIR)/$(CONFIG)/load_file_test || ( echo test load_file_test failed ; exit 1 )
+	$(E) "[RUN]     Testing memory_profile_test"
+	$(Q) $(BINDIR)/$(CONFIG)/memory_profile_test || ( echo test memory_profile_test failed ; exit 1 )
 	$(E) "[RUN]     Testing message_compress_test"
 	$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
 	$(E) "[RUN]     Testing multiple_server_queues_test"
@@ -10290,6 +10298,102 @@ endif
 endif
 
 
+MEMORY_PROFILE_CLIENT_SRC = \
+    test/core/memory_usage/client.c \
+
+MEMORY_PROFILE_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_CLIENT_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/memory_profile_client: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/memory_profile_client: $(MEMORY_PROFILE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_client
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_memory_profile_client: $(MEMORY_PROFILE_CLIENT_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MEMORY_PROFILE_CLIENT_OBJS:.o=.dep)
+endif
+endif
+
+
+MEMORY_PROFILE_SERVER_SRC = \
+    test/core/memory_usage/server.c \
+
+MEMORY_PROFILE_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_SERVER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/memory_profile_server: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/memory_profile_server: $(MEMORY_PROFILE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_server
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_memory_profile_server: $(MEMORY_PROFILE_SERVER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MEMORY_PROFILE_SERVER_OBJS:.o=.dep)
+endif
+endif
+
+
+MEMORY_PROFILE_TEST_SRC = \
+    test/core/memory_usage/memory_usage_test.c \
+
+MEMORY_PROFILE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_PROFILE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/memory_profile_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(MEMORY_PROFILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_profile_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_memory_profile_test: $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MEMORY_PROFILE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 MESSAGE_COMPRESS_TEST_SRC = \
     test/core/compression/message_compress_test.c \
 
diff --git a/build.yaml b/build.yaml
index 55aca52f68..0dbab7c55a 100644
--- a/build.yaml
+++ b/build.yaml
@@ -2322,6 +2322,43 @@ targets:
   - mac
   - linux
   - posix
+- name: memory_profile_client
+  build: test
+  run: false
+  language: c
+  src:
+  - test/core/memory_usage/client.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+- name: memory_profile_server
+  build: test
+  run: false
+  language: c
+  src:
+  - test/core/memory_usage/server.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+- name: memory_profile_test
+  cpu_cost: 1.5
+  build: test
+  language: c
+  src:
+  - test/core/memory_usage/memory_usage_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  platforms:
+  - mac
+  - linux
+  - posix
 - name: message_compress_test
   build: test
   language: c
diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c
new file mode 100644
index 0000000000..9fc122b4c3
--- /dev/null
+++ b/test/core/memory_usage/client.c
@@ -0,0 +1,314 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/byte_buffer_reader.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/cmdline.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "src/core/lib/support/string.h"
+#include "test/core/util/memory_counters.h"
+#include "test/core/util/test_config.h"
+
+static grpc_channel *channel;
+static grpc_completion_queue *cq;
+static grpc_op metadata_ops[2];
+static grpc_op status_ops[2];
+static grpc_op snapshot_ops[6];
+static grpc_op *op;
+
+typedef struct {
+  grpc_call *call;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_status_code status;
+  char *details;
+  size_t details_capacity;
+  grpc_metadata_array trailing_metadata_recv;
+} fling_call;
+
+// Statically allocate call data structs. Enough to accomodate 10000 ping-pong
+// calls and 1 extra for the snapshot calls.
+static fling_call calls[10001];
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+// A call is intentionally divided into two steps. First step is to initiate a
+// call (i.e send and recv metadata). A call is outstanding after we initated,
+// so we can measure the call memory usage.
+static void init_ping_pong_request(int call_idx) {
+  grpc_metadata_array_init(&calls[call_idx].initial_metadata_recv);
+
+  memset(metadata_ops, 0, sizeof(metadata_ops));
+  op = metadata_ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &calls[call_idx].initial_metadata_recv;
+  op++;
+
+  calls[call_idx].call = grpc_channel_create_call(
+      channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/Reflector/reflectUnary",
+      "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[call_idx].call,
+                                                   metadata_ops,
+                                                   (size_t)(op - metadata_ops),
+                                                   tag(call_idx), NULL));
+  grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+}
+
+// Second step is to finish the call (i.e recv status) and destroy the call.
+static void finish_ping_pong_request(int call_idx) {
+  grpc_metadata_array_init(&calls[call_idx].trailing_metadata_recv);
+
+  memset(status_ops, 0, sizeof(status_ops));
+  op = status_ops;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata =
+      &calls[call_idx].trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &calls[call_idx].status;
+  op->data.recv_status_on_client.status_details = &calls[call_idx].details;
+  op->data.recv_status_on_client.status_details_capacity =
+      &calls[call_idx].details_capacity;
+  op++;
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[call_idx].call,
+                                                   status_ops,
+                                                   (size_t)(op - status_ops),
+                                                   tag(call_idx), NULL));
+  grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  grpc_metadata_array_destroy(&calls[call_idx].initial_metadata_recv);
+  grpc_metadata_array_destroy(&calls[call_idx].trailing_metadata_recv);
+  gpr_free(calls[call_idx].details);
+  grpc_call_destroy(calls[call_idx].call);
+  calls[call_idx].call = NULL;
+}
+
+static struct grpc_memory_counters send_snapshot_request(
+    int call_idx, const char *call_type) {
+  grpc_metadata_array_init(&calls[call_idx].initial_metadata_recv);
+  grpc_metadata_array_init(&calls[call_idx].trailing_metadata_recv);
+
+  grpc_byte_buffer *response_payload_recv = NULL;
+  memset(snapshot_ops, 0, sizeof(snapshot_ops));
+  op = snapshot_ops;
+
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &calls[call_idx].initial_metadata_recv;
+  op++;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &response_payload_recv;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata =
+      &calls[call_idx].trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &calls[call_idx].status;
+  op->data.recv_status_on_client.status_details = &calls[call_idx].details;
+  op->data.recv_status_on_client.status_details_capacity =
+      &calls[call_idx].details_capacity;
+  op++;
+
+  calls[call_idx].call = grpc_channel_create_call(
+      channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq, call_type, "localhost",
+      gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(
+                                 calls[call_idx].call, snapshot_ops,
+                                 (size_t)(op - snapshot_ops), (void *)0, NULL));
+  grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+
+  grpc_byte_buffer_reader reader;
+  grpc_byte_buffer_reader_init(&reader, response_payload_recv);
+  grpc_slice response = grpc_byte_buffer_reader_readall(&reader);
+
+  struct grpc_memory_counters snapshot;
+  snapshot.total_size_absolute =
+      ((struct grpc_memory_counters *)GRPC_SLICE_START_PTR(response))
+          ->total_size_absolute;
+  snapshot.total_allocs_absolute =
+      ((struct grpc_memory_counters *)GRPC_SLICE_START_PTR(response))
+          ->total_allocs_absolute;
+  snapshot.total_size_relative =
+      ((struct grpc_memory_counters *)GRPC_SLICE_START_PTR(response))
+          ->total_size_relative;
+  snapshot.total_allocs_relative =
+      ((struct grpc_memory_counters *)GRPC_SLICE_START_PTR(response))
+          ->total_allocs_relative;
+
+  grpc_metadata_array_destroy(&calls[call_idx].initial_metadata_recv);
+  grpc_metadata_array_destroy(&calls[call_idx].trailing_metadata_recv);
+  grpc_slice_unref(response);
+  grpc_byte_buffer_reader_destroy(&reader);
+  grpc_byte_buffer_destroy(response_payload_recv);
+  gpr_free(calls[call_idx].details);
+  calls[call_idx].details = NULL;
+  calls[call_idx].details_capacity = 0;
+  grpc_call_destroy(calls[call_idx].call);
+  calls[call_idx].call = NULL;
+
+  return snapshot;
+}
+
+int main(int argc, char **argv) {
+  grpc_memory_counters_init();
+  grpc_slice slice = grpc_slice_from_copied_string("x");
+  char *fake_argv[1];
+
+  char *target = "localhost:443";
+  gpr_cmdline *cl;
+  grpc_event event;
+
+  grpc_init();
+
+  GPR_ASSERT(argc >= 1);
+  fake_argv[0] = argv[0];
+  grpc_test_init(1, fake_argv);
+
+  int warmup_iterations = 100;
+  int benchmark_iterations = 1000;
+
+  cl = gpr_cmdline_create("memory profiling client");
+  gpr_cmdline_add_string(cl, "target", "Target host:port", &target);
+  gpr_cmdline_add_int(cl, "warmup", "Warmup iterations", &warmup_iterations);
+  gpr_cmdline_add_int(cl, "benchmark", "Benchmark iterations",
+                      &benchmark_iterations);
+  gpr_cmdline_parse(cl, argc, argv);
+  gpr_cmdline_destroy(cl);
+
+  for (int k = 0; k < (int)(sizeof(calls) / sizeof(fling_call)); k++) {
+    calls[k].details = NULL;
+    calls[k].details_capacity = 0;
+  }
+
+  cq = grpc_completion_queue_create(NULL);
+
+  struct grpc_memory_counters client_channel_start =
+      grpc_memory_counters_snapshot();
+  channel = grpc_insecure_channel_create(target, NULL, NULL);
+
+  int call_idx = 0;
+
+  struct grpc_memory_counters before_server_create =
+      send_snapshot_request(0, "Reflector/GetBeforeSvrCreation");
+  struct grpc_memory_counters after_server_create =
+      send_snapshot_request(0, "Reflector/GetAfterSvrCreation");
+
+  // warmup period
+  for (call_idx = 0; call_idx < warmup_iterations; ++call_idx) {
+    init_ping_pong_request(call_idx + 1);
+  }
+
+  struct grpc_memory_counters server_benchmark_calls_start =
+      send_snapshot_request(0, "Reflector/SimpleSnapshot");
+
+  struct grpc_memory_counters client_benchmark_calls_start =
+      grpc_memory_counters_snapshot();
+
+  // benchmark period
+  for (; call_idx < warmup_iterations + benchmark_iterations; ++call_idx) {
+    init_ping_pong_request(call_idx + 1);
+  }
+
+  struct grpc_memory_counters client_calls_inflight =
+      grpc_memory_counters_snapshot();
+
+  struct grpc_memory_counters server_calls_inflight =
+      send_snapshot_request(0, "Reflector/DestroyCalls");
+
+  do {
+    event = grpc_completion_queue_next(
+        cq, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                         gpr_time_from_micros(10000, GPR_TIMESPAN)),
+        NULL);
+  } while (event.type != GRPC_QUEUE_TIMEOUT);
+
+  // second step - recv status and destroy call
+  for (call_idx = 0; call_idx < warmup_iterations + benchmark_iterations;
+       ++call_idx) {
+    finish_ping_pong_request(call_idx + 1);
+  }
+
+  struct grpc_memory_counters server_calls_end =
+      send_snapshot_request(0, "Reflector/SimpleSnapshot");
+
+  struct grpc_memory_counters client_channel_end =
+      grpc_memory_counters_snapshot();
+
+  grpc_channel_destroy(channel);
+  grpc_completion_queue_shutdown(cq);
+
+  do {
+    event = grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
+                                       NULL);
+  } while (event.type != GRPC_QUEUE_SHUTDOWN);
+  grpc_slice_unref(slice);
+
+  grpc_completion_queue_destroy(cq);
+  grpc_shutdown();
+
+  gpr_log(GPR_INFO, "---------client stats--------");
+  gpr_log(GPR_INFO, "client call memory usage: %f bytes per call",
+          (double)(client_calls_inflight.total_size_relative -
+                   client_benchmark_calls_start.total_size_relative) /
+              benchmark_iterations);
+  gpr_log(GPR_INFO, "client channel memory usage %zi bytes",
+          client_channel_end.total_size_relative -
+              client_channel_start.total_size_relative);
+
+  gpr_log(GPR_INFO, "---------server stats--------");
+  gpr_log(GPR_INFO, "server create: %zi bytes",
+          after_server_create.total_size_relative -
+              before_server_create.total_size_relative);
+  gpr_log(GPR_INFO, "server call memory usage: %f bytes per call",
+          (double)(server_calls_inflight.total_size_relative -
+                   server_benchmark_calls_start.total_size_relative) /
+              benchmark_iterations);
+  gpr_log(GPR_INFO, "server channel memory usage %zi bytes",
+          server_calls_end.total_size_relative -
+              after_server_create.total_size_relative);
+
+  grpc_memory_counters_destroy();
+  return 0;
+}
diff --git a/test/core/memory_usage/memory_usage_test.c b/test/core/memory_usage/memory_usage_test.c
new file mode 100644
index 0000000000..7e7a9d050d
--- /dev/null
+++ b/test/core/memory_usage/memory_usage_test.c
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/subprocess.h>
+#include "src/core/lib/support/string.h"
+#include "test/core/util/port.h"
+
+int main(int argc, char **argv) {
+  char *me = argv[0];
+  char *lslash = strrchr(me, '/');
+  char root[1024];
+  int port = grpc_pick_unused_port_or_die();
+  char *args[10];
+  int status;
+  gpr_subprocess *svr, *cli;
+  /* figure out where we are */
+  if (lslash) {
+    memcpy(root, me, (size_t)(lslash - me));
+    root[lslash - me] = 0;
+  } else {
+    strcpy(root, ".");
+  }
+  /* start the server */
+  gpr_asprintf(&args[0], "%s/memory_profile_server%s", root,
+               gpr_subprocess_binary_extension());
+  args[1] = "--bind";
+  gpr_join_host_port(&args[2], "::", port);
+  args[3] = "--no-secure";
+  svr = gpr_subprocess_create(4, (const char **)args);
+  gpr_free(args[0]);
+  gpr_free(args[2]);
+
+  /* start the client */
+  gpr_asprintf(&args[0], "%s/memory_profile_client%s", root,
+               gpr_subprocess_binary_extension());
+  args[1] = "--target";
+  gpr_join_host_port(&args[2], "127.0.0.1", port);
+  args[3] = "--warmup=1000";
+  args[4] = "--benchmark=9000";
+  cli = gpr_subprocess_create(5, (const char **)args);
+  gpr_free(args[0]);
+  gpr_free(args[2]);
+
+  /* wait for completion */
+  printf("waiting for client\n");
+  if ((status = gpr_subprocess_join(cli))) {
+    gpr_subprocess_destroy(cli);
+    gpr_subprocess_destroy(svr);
+    return status;
+  }
+  gpr_subprocess_destroy(cli);
+
+  gpr_subprocess_interrupt(svr);
+  status = gpr_subprocess_join(svr);
+  gpr_subprocess_destroy(svr);
+  return status;
+}
diff --git a/test/core/memory_usage/server.c b/test/core/memory_usage/server.c
new file mode 100644
index 0000000000..c0710930b0
--- /dev/null
+++ b/test/core/memory_usage/server.c
@@ -0,0 +1,321 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifndef _WIN32
+/* This is for _exit() below, which is temporary. */
+#include <unistd.h>
+#endif
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/cmdline.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/memory_counters.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static grpc_completion_queue *cq;
+static grpc_server *server;
+static grpc_op metadata_ops[2];
+static grpc_op snapshot_ops[5];
+static grpc_op status_op;
+static int got_sigint = 0;
+static grpc_byte_buffer *payload_buffer = NULL;
+static grpc_byte_buffer *terminal_buffer = NULL;
+static int was_cancelled = 2;
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+typedef enum {
+  FLING_SERVER_NEW_REQUEST = 1,
+  FLING_SERVER_SEND_INIT_METADATA,
+  FLING_SERVER_WAIT_FOR_DESTROY,
+  FLING_SERVER_SEND_STATUS_FLING_CALL,
+  FLING_SERVER_SEND_STATUS_SNAPSHOT,
+  FLING_SERVER_BATCH_SEND_STATUS_FLING_CALL
+} fling_server_tags;
+
+typedef struct {
+  fling_server_tags state;
+  grpc_call *call;
+  grpc_call_details call_details;
+  grpc_metadata_array request_metadata_recv;
+  grpc_metadata_array initial_metadata_send;
+} fling_call;
+
+// hold up to 10000 calls and 6 snaphost calls
+static fling_call calls[100006];
+
+static void request_call_unary(int call_idx) {
+  if (call_idx == (int)(sizeof(calls) / sizeof(fling_call))) {
+    gpr_log(GPR_INFO, "Used all call slots (10000) on server. Server exit.");
+    _exit(0);
+  }
+  grpc_metadata_array_init(&calls[call_idx].request_metadata_recv);
+  grpc_server_request_call(
+      server, &calls[call_idx].call, &calls[call_idx].call_details,
+      &calls[call_idx].request_metadata_recv, cq, cq, &calls[call_idx]);
+}
+
+static void send_initial_metadata_unary(void *tag) {
+  grpc_metadata_array_init(&(*(fling_call *)tag).initial_metadata_send);
+  metadata_ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  metadata_ops[0].data.send_initial_metadata.count = 0;
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch((*(fling_call *)tag).call,
+                                                   metadata_ops, 1, tag, NULL));
+}
+
+static void send_status(void *tag) {
+  status_op.op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  status_op.data.send_status_from_server.status = GRPC_STATUS_OK;
+  status_op.data.send_status_from_server.trailing_metadata_count = 0;
+  status_op.data.send_status_from_server.status_details = "";
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch((*(fling_call *)tag).call,
+                                                   &status_op, 1, tag, NULL));
+}
+
+static void send_snapshot(void *tag, struct grpc_memory_counters *snapshot) {
+  grpc_op *op;
+
+  grpc_slice snapshot_slice =
+      grpc_slice_new(snapshot, sizeof(*snapshot), gpr_free);
+  payload_buffer = grpc_raw_byte_buffer_create(&snapshot_slice, 1);
+  grpc_metadata_array_init(&(*(fling_call *)tag).initial_metadata_send);
+
+  op = snapshot_ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op++;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &terminal_buffer;
+  op++;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  if (payload_buffer == NULL) {
+    gpr_log(GPR_INFO, "NULL payload buffer !!!");
+  }
+  op->data.send_message = payload_buffer;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.status = GRPC_STATUS_OK;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status_details = "";
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op++;
+
+  GPR_ASSERT(GRPC_CALL_OK ==
+             grpc_call_start_batch((*(fling_call *)tag).call, snapshot_ops,
+                                   (size_t)(op - snapshot_ops), tag, NULL));
+}
+/* We have some sort of deadlock, so let's not exit gracefully for now.
+   When that is resolved, please remove the #include <unistd.h> above. */
+static void sigint_handler(int x) { _exit(0); }
+
+int main(int argc, char **argv) {
+  grpc_memory_counters_init();
+  grpc_event ev;
+  char *addr_buf = NULL;
+  gpr_cmdline *cl;
+  int shutdown_started = 0;
+  int shutdown_finished = 0;
+
+  int secure = 0;
+  char *addr = NULL;
+
+  char *fake_argv[1];
+
+  GPR_ASSERT(argc >= 1);
+  fake_argv[0] = argv[0];
+  grpc_test_init(1, fake_argv);
+
+  grpc_init();
+  srand((unsigned)clock());
+
+  cl = gpr_cmdline_create("fling server");
+  gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr);
+  gpr_cmdline_add_flag(cl, "secure", "Run with security?", &secure);
+  gpr_cmdline_parse(cl, argc, argv);
+  gpr_cmdline_destroy(cl);
+
+  if (addr == NULL) {
+    gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die());
+    addr = addr_buf;
+  }
+  gpr_log(GPR_INFO, "creating server on: %s", addr);
+
+  cq = grpc_completion_queue_create(NULL);
+
+  struct grpc_memory_counters before_server_create =
+      grpc_memory_counters_snapshot();
+  if (secure) {
+    grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
+                                                    test_server1_cert};
+    grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(
+        NULL, &pem_key_cert_pair, 1, 0, NULL);
+    server = grpc_server_create(NULL, NULL);
+    GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
+    grpc_server_credentials_release(ssl_creds);
+  } else {
+    server = grpc_server_create(NULL, NULL);
+    GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr));
+  }
+
+  grpc_server_register_completion_queue(server, cq, NULL);
+  grpc_server_start(server);
+
+  struct grpc_memory_counters after_server_create =
+      grpc_memory_counters_snapshot();
+
+  gpr_free(addr_buf);
+  addr = addr_buf = NULL;
+
+  // initialize call instances
+  for (int i = 0; i < (int)(sizeof(calls) / sizeof(fling_call)); i++) {
+    grpc_call_details_init(&calls[i].call_details);
+    calls[i].state = FLING_SERVER_NEW_REQUEST;
+  }
+
+  int next_call_idx = 0;
+  struct grpc_memory_counters current_snapshot;
+
+  request_call_unary(next_call_idx);
+
+  signal(SIGINT, sigint_handler);
+
+  while (!shutdown_finished) {
+    if (got_sigint && !shutdown_started) {
+      gpr_log(GPR_INFO, "Shutting down due to SIGINT");
+      grpc_server_shutdown_and_notify(server, cq, tag(1000));
+      GPR_ASSERT(grpc_completion_queue_pluck(
+                     cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+                     .type == GRPC_OP_COMPLETE);
+      grpc_completion_queue_shutdown(cq);
+      shutdown_started = 1;
+    }
+    ev = grpc_completion_queue_next(
+        cq, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                         gpr_time_from_micros(1000000, GPR_TIMESPAN)),
+        NULL);
+    fling_call *s = ev.tag;
+    switch (ev.type) {
+      case GRPC_OP_COMPLETE:
+        switch (s->state) {
+          case FLING_SERVER_NEW_REQUEST:
+            request_call_unary(++next_call_idx);
+            if (0 ==
+                strcmp(s->call_details.method, "/Reflector/reflectUnary")) {
+              s->state = FLING_SERVER_SEND_INIT_METADATA;
+              send_initial_metadata_unary(s);
+            } else if (0 == strcmp(s->call_details.method,
+                                   "Reflector/GetBeforeSvrCreation")) {
+              s->state = FLING_SERVER_SEND_STATUS_SNAPSHOT;
+              send_snapshot(s, &before_server_create);
+            } else if (0 == strcmp(s->call_details.method,
+                                   "Reflector/GetAfterSvrCreation")) {
+              s->state = FLING_SERVER_SEND_STATUS_SNAPSHOT;
+              send_snapshot(s, &after_server_create);
+            } else if (0 == strcmp(s->call_details.method,
+                                   "Reflector/SimpleSnapshot")) {
+              s->state = FLING_SERVER_SEND_STATUS_SNAPSHOT;
+              current_snapshot = grpc_memory_counters_snapshot();
+              send_snapshot(s, &current_snapshot);
+            } else if (0 == strcmp(s->call_details.method,
+                                   "Reflector/DestroyCalls")) {
+              s->state = FLING_SERVER_BATCH_SEND_STATUS_FLING_CALL;
+              current_snapshot = grpc_memory_counters_snapshot();
+              send_snapshot(s, &current_snapshot);
+            } else {
+              gpr_log(GPR_ERROR, "Wrong call method");
+            }
+            break;
+          case FLING_SERVER_SEND_INIT_METADATA:
+            s->state = FLING_SERVER_WAIT_FOR_DESTROY;
+            break;
+          case FLING_SERVER_WAIT_FOR_DESTROY:
+            break;
+          case FLING_SERVER_SEND_STATUS_FLING_CALL:
+            grpc_call_destroy(s->call);
+            grpc_call_details_destroy(&s->call_details);
+            grpc_metadata_array_destroy(&s->initial_metadata_send);
+            grpc_metadata_array_destroy(&s->request_metadata_recv);
+            break;
+          case FLING_SERVER_BATCH_SEND_STATUS_FLING_CALL:
+            for (int k = 0; k < (int)(sizeof(calls) / sizeof(fling_call));
+                 ++k) {
+              if (calls[k].state == FLING_SERVER_WAIT_FOR_DESTROY) {
+                calls[k].state = FLING_SERVER_SEND_STATUS_FLING_CALL;
+                send_status(&calls[k]);
+              }
+            }
+          // no break here since we want to continue to case
+          // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call
+          case FLING_SERVER_SEND_STATUS_SNAPSHOT:
+            grpc_byte_buffer_destroy(payload_buffer);
+            grpc_byte_buffer_destroy(terminal_buffer);
+            grpc_call_destroy(s->call);
+            grpc_call_details_destroy(&s->call_details);
+            grpc_metadata_array_destroy(&s->initial_metadata_send);
+            grpc_metadata_array_destroy(&s->request_metadata_recv);
+            terminal_buffer = NULL;
+            payload_buffer = NULL;
+            break;
+        }
+        break;
+      case GRPC_QUEUE_SHUTDOWN:
+        GPR_ASSERT(shutdown_started);
+        shutdown_finished = 1;
+        break;
+      case GRPC_QUEUE_TIMEOUT:
+        break;
+    }
+  }
+
+  grpc_server_destroy(server);
+  grpc_completion_queue_destroy(cq);
+  grpc_shutdown();
+  grpc_memory_counters_destroy();
+  return 0;
+}
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 6539f96565..225991781e 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -848,34 +848,34 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
+doc/wait-for-ready.md \
+doc/stress_test_framework.md \
 doc/binary-logging.md \
+doc/load-balancing.md \
+doc/g_stands_for.md \
+doc/connectivity-semantics-and-api.md \
+doc/negative-http2-interop-test-descriptions.md \
 doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
+doc/fail_fast.md \
+doc/PROTOCOL-WEB.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/naming.md \
 doc/compression_cookbook.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
 doc/connection-backoff-interop-test-description.md \
+doc/command_line_tool.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
 doc/cpp-style-guide.md \
+doc/compression.md \
 doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
-doc/cpp/perf_notes.md
+doc/epoll-polling-engine.md \
+doc/interop-test-descriptions.md \
+doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ffef534fe2..2944b3ba38 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -894,34 +894,34 @@ src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time_cc.cc \
 src/cpp/codegen/codegen_init.cc \
+doc/wait-for-ready.md \
+doc/stress_test_framework.md \
 doc/binary-logging.md \
+doc/load-balancing.md \
+doc/g_stands_for.md \
+doc/connectivity-semantics-and-api.md \
+doc/negative-http2-interop-test-descriptions.md \
 doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
+doc/fail_fast.md \
+doc/PROTOCOL-WEB.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/naming.md \
 doc/compression_cookbook.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
 doc/connection-backoff-interop-test-description.md \
+doc/command_line_tool.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
 doc/cpp-style-guide.md \
+doc/compression.md \
 doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
-doc/cpp/pending_api_cleanups.md \
+doc/epoll-polling-engine.md \
+doc/interop-test-descriptions.md \
 doc/cpp/perf_notes.md \
+doc/cpp/pending_api_cleanups.md \
 src/cpp/README.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index f8a3970416..c6d7432e3f 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -826,32 +826,32 @@ include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
 include/grpc/impl/codegen/sync_windows.h \
+doc/wait-for-ready.md \
+doc/stress_test_framework.md \
 doc/binary-logging.md \
+doc/load-balancing.md \
+doc/g_stands_for.md \
+doc/connectivity-semantics-and-api.md \
+doc/negative-http2-interop-test-descriptions.md \
 doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
+doc/fail_fast.md \
+doc/PROTOCOL-WEB.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/naming.md \
 doc/compression_cookbook.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
 doc/connection-backoff-interop-test-description.md \
+doc/command_line_tool.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
 doc/cpp-style-guide.md \
+doc/compression.md \
 doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
+doc/epoll-polling-engine.md \
+doc/interop-test-descriptions.md \
 doc/core/pending_api_cleanups.md
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 1a945bec49..e0d3dc535b 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1281,54 +1281,54 @@ src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c \
+doc/wait-for-ready.md \
+doc/stress_test_framework.md \
 doc/binary-logging.md \
+doc/load-balancing.md \
+doc/g_stands_for.md \
+doc/connectivity-semantics-and-api.md \
+doc/negative-http2-interop-test-descriptions.md \
 doc/c-style-guide.md \
-doc/command_line_tool.md \
-doc/compression.md \
+doc/fail_fast.md \
+doc/PROTOCOL-WEB.md \
+doc/server_reflection_tutorial.md \
+doc/server-reflection.md \
+doc/naming.md \
 doc/compression_cookbook.md \
+doc/health-checking.md \
+doc/http-grpc-status-mapping.md \
 doc/connection-backoff-interop-test-description.md \
+doc/command_line_tool.md \
 doc/connection-backoff.md \
-doc/connectivity-semantics-and-api.md \
 doc/cpp-style-guide.md \
+doc/compression.md \
 doc/environment_variables.md \
-doc/epoll-polling-engine.md \
-doc/fail_fast.md \
-doc/g_stands_for.md \
-doc/health-checking.md \
-doc/http-grpc-status-mapping.md \
-doc/interop-test-descriptions.md \
-doc/load-balancing.md \
-doc/naming.md \
-doc/negative-http2-interop-test-descriptions.md \
 doc/PROTOCOL-HTTP2.md \
-doc/PROTOCOL-WEB.md \
-doc/server-reflection.md \
-doc/server_reflection_tutorial.md \
 doc/statuscodes.md \
-doc/stress_test_framework.md \
-doc/wait-for-ready.md \
+doc/epoll-polling-engine.md \
+doc/interop-test-descriptions.md \
 doc/core/pending_api_cleanups.md \
 src/core/README.md \
+src/core/lib/README.md \
+src/core/lib/channel/README.md \
+src/core/lib/transport/README.md \
+src/core/lib/tsi/README.md \
+src/core/lib/iomgr/README.md \
+src/core/lib/surface/README.md \
 src/core/ext/README.md \
+src/core/ext/transport/README.md \
+src/core/ext/transport/chttp2/README.md \
+src/core/ext/transport/chttp2/server/secure/README.md \
+src/core/ext/transport/chttp2/server/insecure/README.md \
+src/core/ext/transport/chttp2/transport/README.md \
+src/core/ext/transport/chttp2/client/secure/README.md \
+src/core/ext/transport/chttp2/client/insecure/README.md \
 src/core/ext/census/README.md \
 src/core/ext/census/gen/README.md \
 src/core/ext/client_channel/README.md \
 src/core/ext/resolver/README.md \
 src/core/ext/resolver/dns/native/README.md \
-src/core/ext/resolver/sockaddr/README.md \
-src/core/ext/transport/README.md \
-src/core/ext/transport/chttp2/README.md \
-src/core/ext/transport/chttp2/client/insecure/README.md \
-src/core/ext/transport/chttp2/client/secure/README.md \
-src/core/ext/transport/chttp2/server/insecure/README.md \
-src/core/ext/transport/chttp2/server/secure/README.md \
-src/core/ext/transport/chttp2/transport/README.md \
-src/core/lib/README.md \
-src/core/lib/channel/README.md \
-src/core/lib/iomgr/README.md \
-src/core/lib/surface/README.md \
-src/core/lib/transport/README.md \
-src/core/lib/tsi/README.md
+src/core/ext/resolver/sockaddr/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 8849dcc600..ea90f200b9 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -1508,6 +1508,57 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "memory_profile_client", 
+    "src": [
+      "test/core/memory_usage/client.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "memory_profile_server", 
+    "src": [
+      "test/core/memory_usage/server.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
+    "name": "memory_profile_test", 
+    "src": [
+      "test/core/memory_usage/memory_usage_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b76263b8b9..8b4427ba8c 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1565,6 +1565,26 @@
       "windows"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.5, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "memory_profile_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index d08a47aa86..f484f29a4b 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -1202,6 +1202,28 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_file_test", "vcxproj\t
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memory_profile_client", "vcxproj\test\memory_profile_client\memory_profile_client.vcxproj", "{98C01DBE-EFFE-6988-0762-829DC88F0EB4}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memory_profile_server", "vcxproj\test\memory_profile_server\memory_profile_server.vcxproj", "{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "message_compress_test", "vcxproj\test\message_compress_test\message_compress_test.vcxproj", "{07170557-CCB0-D23C-8018-C2909D115DF9}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -3377,6 +3399,38 @@ Global
 		{DC76C089-0D55-DF19-7CCA-49DAE5D29E49}.Release-DLL|Win32.Build.0 = Release|Win32
 		{DC76C089-0D55-DF19-7CCA-49DAE5D29E49}.Release-DLL|x64.ActiveCfg = Release|x64
 		{DC76C089-0D55-DF19-7CCA-49DAE5D29E49}.Release-DLL|x64.Build.0 = Release|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug|x64.ActiveCfg = Debug|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release|Win32.ActiveCfg = Release|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release|x64.ActiveCfg = Release|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug|Win32.Build.0 = Debug|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug|x64.Build.0 = Debug|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release|Win32.Build.0 = Release|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release|x64.Build.0 = Release|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Debug-DLL|x64.Build.0 = Debug|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release-DLL|Win32.Build.0 = Release|Win32
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release-DLL|x64.ActiveCfg = Release|x64
+		{98C01DBE-EFFE-6988-0762-829DC88F0EB4}.Release-DLL|x64.Build.0 = Release|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug|x64.ActiveCfg = Debug|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release|Win32.ActiveCfg = Release|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release|x64.ActiveCfg = Release|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug|Win32.Build.0 = Debug|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug|x64.Build.0 = Debug|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release|Win32.Build.0 = Release|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release|x64.Build.0 = Release|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Debug-DLL|x64.Build.0 = Debug|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release-DLL|Win32.Build.0 = Release|Win32
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release-DLL|x64.ActiveCfg = Release|x64
+		{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}.Release-DLL|x64.Build.0 = Release|x64
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Debug|x64.ActiveCfg = Debug|x64
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj b/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj
new file mode 100644
index 0000000000..b955bcae37
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{98C01DBE-EFFE-6988-0762-829DC88F0EB4}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>memory_profile_client</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>memory_profile_client</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\memory_usage\client.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj.filters b/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj.filters
new file mode 100644
index 0000000000..b250b538d1
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_profile_client/memory_profile_client.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\memory_usage\client.c">
+      <Filter>test\core\memory_usage</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{4445c589-fe29-9a74-3b53-c83c7bac669e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{8f263e3f-4f47-64ed-e45f-8f4385a6056d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\memory_usage">
+      <UniqueIdentifier>{2de23f1d-3faf-3318-2e31-b7cfa4a89220}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj b/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj
new file mode 100644
index 0000000000..0b3c87997e
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{7430B8AF-2A0E-EDF4-FD53-C8004DEE39EC}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>memory_profile_server</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>memory_profile_server</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\memory_usage\server.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj.filters b/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj.filters
new file mode 100644
index 0000000000..c95888e7a1
--- /dev/null
+++ b/vsprojects/vcxproj/test/memory_profile_server/memory_profile_server.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\memory_usage\server.c">
+      <Filter>test\core\memory_usage</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{0193b199-ddad-5387-8a4f-ab1e6c36b835}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{31db3ee2-d7ca-bedb-eacc-1bc7785dcae6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\memory_usage">
+      <UniqueIdentifier>{5b7c6ebd-9730-e59c-59bf-806a8b7ccda2}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
-- 
GitLab


From 0748f3925cf0892b4780de25199bdd82aab30e57 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 13 Jan 2017 09:22:44 -0800
Subject: [PATCH 311/344] Store subchannel address in a channel arg.

---
 src/core/ext/client_channel/connector.h       |  3 --
 src/core/ext/client_channel/subchannel.c      | 40 ++++++++++++++-----
 src/core/ext/client_channel/subchannel.h      |  8 +++-
 .../ext/client_channel/subchannel_index.c     | 12 ------
 .../ext/lb_policy/pick_first/pick_first.c     | 15 +++++--
 .../ext/lb_policy/round_robin/round_robin.c   | 15 +++++--
 .../chttp2/client/chttp2_connector.c          | 10 ++++-
 7 files changed, 69 insertions(+), 34 deletions(-)

diff --git a/src/core/ext/client_channel/connector.h b/src/core/ext/client_channel/connector.h
index 3de061620e..395f89b3b2 100644
--- a/src/core/ext/client_channel/connector.h
+++ b/src/core/ext/client_channel/connector.h
@@ -48,9 +48,6 @@ struct grpc_connector {
 typedef struct {
   /** set of pollsets interested in this connection */
   grpc_pollset_set *interested_parties;
-  /** address to connect to */
-  const grpc_resolved_address *addr;
-  size_t addr_len;
   /** initial connect string to send */
   grpc_slice initial_connect_string;
   /** deadline for connection */
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index 1bac82b451..7a2ad98433 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -41,9 +41,12 @@
 
 #include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/initial_connect_string.h"
+#include "src/core/ext/client_channel/parse_address.h"
 #include "src/core/ext/client_channel/subchannel_index.h"
+#include "src/core/ext/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
@@ -95,8 +98,6 @@ struct grpc_subchannel {
   size_t num_filters;
   /** channel arguments */
   grpc_channel_args *args;
-  /** address to connect to */
-  grpc_resolved_address *addr;
 
   grpc_subchannel_key *key;
 
@@ -211,7 +212,6 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
   grpc_subchannel *c = arg;
   gpr_free((void *)c->filters);
   grpc_channel_args_destroy(exec_ctx, c->args);
-  gpr_free(c->addr);
   grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
   grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
   grpc_connector_unref(exec_ctx, c->connector);
@@ -327,12 +327,22 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
   } else {
     c->filters = NULL;
   }
-  c->addr = gpr_malloc(sizeof(grpc_resolved_address));
-  if (args->addr->len)
-    memcpy(c->addr, args->addr, sizeof(grpc_resolved_address));
   c->pollset_set = grpc_pollset_set_create();
-  grpc_set_initial_connect_string(&c->addr, &c->initial_connect_string);
-  c->args = grpc_channel_args_copy(args->args);
+  const grpc_arg *addr_arg =
+      grpc_channel_args_find(args->args, GRPC_ARG_SUBCHANNEL_ADDRESS);
+  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
+  grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
+  grpc_uri_to_sockaddr(addr_arg->value.string, addr);
+  grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
+  static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
+  grpc_arg new_arg;
+  new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
+  new_arg.type = GRPC_ARG_STRING;
+  new_arg.value.string = grpc_sockaddr_to_uri(addr);
+  gpr_free(addr);
+  c->args = grpc_channel_args_copy_and_add_and_remove(
+      args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
+  gpr_free(new_arg.value.string);
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
   grpc_closure_init(&c->connected, subchannel_connected, c,
@@ -385,7 +395,6 @@ static void continue_connect_locked(grpc_exec_ctx *exec_ctx,
   grpc_connect_in_args args;
 
   args.interested_parties = c->pollset_set;
-  args.addr = c->addr;
   args.deadline = c->next_attempt;
   args.channel_args = c->args;
   args.initial_connect_string = c->initial_connect_string;
@@ -771,3 +780,16 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
     grpc_subchannel_call *subchannel_call) {
   return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
 }
+
+void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
+  grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
+  GPR_ASSERT(uri != NULL);
+  if (strcmp(uri->scheme, "ipv4") == 0) {
+    GPR_ASSERT(parse_ipv4(uri, addr));
+  } else if (strcmp(uri->scheme, "ipv6") == 0) {
+    GPR_ASSERT(parse_ipv6(uri, addr));
+  } else {
+    GPR_ASSERT(parse_unix(uri, addr));
+  }
+  grpc_uri_destroy(uri);
+}
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index 24aa9f73dc..4cc33fc79b 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -40,6 +40,9 @@
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/metadata.h"
 
+// Channel arg containing a grpc_resolved_address to connect to.
+#define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address"
+
 /** A (sub-)channel that knows how to connect to exactly one target
     address. Provides a target for load balancing. */
 typedef struct grpc_subchannel grpc_subchannel;
@@ -164,8 +167,6 @@ struct grpc_subchannel_args {
   size_t filter_count;
   /** Channel arguments to be supplied to the newly created channel */
   const grpc_channel_args *args;
-  /** Address to connect to */
-  grpc_resolved_address *addr;
 };
 
 /** create a subchannel given a connector */
@@ -173,4 +174,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
                                         grpc_connector *connector,
                                         const grpc_subchannel_args *args);
 
+/// Sets \a addr from \a uri_str.
+void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr);
+
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
index 1ebe03ef11..11889300a2 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/client_channel/subchannel_index.c
@@ -86,11 +86,6 @@ static grpc_subchannel_key *create_key(
   } else {
     k->args.filters = NULL;
   }
-  k->args.addr = gpr_malloc(sizeof(grpc_resolved_address));
-  k->args.addr->len = args->addr->len;
-  if (k->args.addr->len > 0) {
-    memcpy(k->args.addr, args->addr, sizeof(grpc_resolved_address));
-  }
   k->args.args = copy_channel_args(args->args);
   return k;
 }
@@ -108,14 +103,8 @@ static int subchannel_key_compare(grpc_subchannel_key *a,
                                   grpc_subchannel_key *b) {
   int c = GPR_ICMP(a->connector, b->connector);
   if (c != 0) return c;
-  c = GPR_ICMP(a->args.addr->len, b->args.addr->len);
-  if (c != 0) return c;
   c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
   if (c != 0) return c;
-  if (a->args.addr->len) {
-    c = memcmp(a->args.addr->addr, b->args.addr->addr, a->args.addr->len);
-    if (c != 0) return c;
-  }
   if (a->args.filter_count > 0) {
     c = memcmp(a->args.filters, b->args.filters,
                a->args.filter_count * sizeof(*a->args.filters));
@@ -129,7 +118,6 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
   grpc_connector_unref(exec_ctx, k->connector);
   gpr_free((grpc_channel_args *)k->args.filters);
   grpc_channel_args_destroy(exec_ctx, (grpc_channel_args *)k->args.args);
-  gpr_free(k->args.addr);
   gpr_free(k);
 }
 
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 821becff69..4677fb2343 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -36,7 +36,9 @@
 #include <grpc/support/alloc.h>
 
 #include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 typedef struct pending_pick {
@@ -466,11 +468,18 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
     }
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    sc_args.addr = &addresses->addresses[i].address;
-    sc_args.args = args->args;
-
+    grpc_arg addr_arg;
+    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
+    addr_arg.type = GRPC_ARG_STRING;
+    addr_arg.value.string =
+        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_channel_args *new_args =
+        grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
+    gpr_free(addr_arg.value.string);
+    sc_args.args = new_args;
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
         exec_ctx, args->client_channel_factory, &sc_args);
+    grpc_channel_args_destroy(exec_ctx, new_args);
 
     if (subchannel != NULL) {
       p->subchannels[subchannel_idx++] = subchannel;
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index cb679489c3..3fe157a23c 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -64,8 +64,10 @@
 #include <grpc/support/alloc.h>
 
 #include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/static_metadata.h"
 
@@ -729,11 +731,18 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
     if (addresses->addresses[i].is_balancer) continue;
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    sc_args.addr = &addresses->addresses[i].address;
-    sc_args.args = args->args;
-
+    grpc_arg addr_arg;
+    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
+    addr_arg.type = GRPC_ARG_STRING;
+    addr_arg.value.string =
+        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_channel_args *new_args =
+        grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
+    gpr_free(addr_arg.value.string);
+    sc_args.args = new_args;
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
         exec_ctx, args->client_channel_factory, &sc_args);
+    grpc_channel_args_destroy(exec_ctx, new_args);
 
     if (subchannel != NULL) {
       subchannel_data *sd = gpr_malloc(sizeof(*sd));
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 2c5dfaea60..ebe884b115 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -43,6 +43,7 @@
 
 #include "src/core/ext/client_channel/connector.h"
 #include "src/core/ext/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/client_channel/subchannel.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
@@ -220,6 +221,11 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
                                      grpc_connect_out_args *result,
                                      grpc_closure *notify) {
   chttp2_connector *c = (chttp2_connector *)con;
+  const grpc_arg *addr_arg =
+      grpc_channel_args_find(args->channel_args, GRPC_ARG_SUBCHANNEL_ADDRESS);
+  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
+  grpc_resolved_address addr;
+  grpc_uri_to_sockaddr(addr_arg->value.string, &addr);
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(c->notify == NULL);
   c->notify = notify;
@@ -231,8 +237,8 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(!c->connecting);
   c->connecting = true;
   grpc_tcp_client_connect(exec_ctx, &c->connected, &c->endpoint,
-                          args->interested_parties, args->channel_args,
-                          args->addr, args->deadline);
+                          args->interested_parties, args->channel_args, &addr,
+                          args->deadline);
   gpr_mu_unlock(&c->mu);
 }
 
-- 
GitLab


From 972b7975a6f25a76ef26aa9d2e7494c018a40e28 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Fri, 13 Jan 2017 09:28:09 -0800
Subject: [PATCH 312/344] Fixed package name in dockerfile

---
 .../tools/dockerfile/test/node_jessie_x64/Dockerfile.template   | 2 +-
 tools/dockerfile/test/node_jessie_x64/Dockerfile                | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
index fa5c8c3816..ceaa9aa5ab 100644
--- a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template
@@ -35,7 +35,7 @@
 
   # Install Electron apt dependencies
   RUN apt-get update && apt-get install -y ${'\\'}
-    libasound ${'\\'}
+    libasound2 ${'\\'}
     libgconf-2-4 ${'\\'}
     libgtk2.0-0 ${'\\'}
     libnss3 ${'\\'}
diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile
index 184298f913..7f93933eca 100644
--- a/tools/dockerfile/test/node_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile
@@ -66,7 +66,7 @@ RUN apt-get update && apt-get install -y time && apt-get clean
 
 # Install Electron apt dependencies
 RUN apt-get update && apt-get install -y \
-  libasound \
+  libasound2 \
   libgconf-2-4 \
   libgtk2.0-0 \
   libnss3 \
-- 
GitLab


From b19ac964876a694c58a2aa7527d456a765e85515 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Fri, 13 Jan 2017 10:56:36 -0800
Subject: [PATCH 313/344] Fix electron artifact builds

---
 binding.gyp                                       | 2 +-
 templates/binding.gyp.template                    | 2 +-
 tools/run_tests/artifacts/build_artifact_node.bat | 2 +-
 tools/run_tests/artifacts/build_artifact_node.sh  | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/binding.gyp b/binding.gyp
index fd48da875a..d9461dbe00 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -54,7 +54,7 @@
           'GRPC_UV'
         ]
       }],
-      ['runtime=="electron"', {
+      ['OS!="win" && runtime=="electron"', {
         "defines": [
           'OPENSSL_NO_THREADS'
         ]
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 7570aa5e7e..b0585475ec 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -56,7 +56,7 @@
             'GRPC_UV'
           ]
         }],
-        ['runtime=="electron"', {
+        ['OS!="win" && runtime=="electron"', {
           "defines": [
             'OPENSSL_NO_THREADS'
           ]
diff --git a/tools/run_tests/artifacts/build_artifact_node.bat b/tools/run_tests/artifacts/build_artifact_node.bat
index f1a5b8aaaf..0a2bc4b9d7 100644
--- a/tools/run_tests/artifacts/build_artifact_node.bat
+++ b/tools/run_tests/artifacts/build_artifact_node.bat
@@ -51,7 +51,7 @@ for %%v in (%node_versions%) do (
 )
 
 for %%v in (%electron_versions%) do (
-  call .\node_modules\.bin\node-pre-gyp.cmd configure rebuild package testpackage --runtime=electron --target=%%v --target_arch=%1 || goto :error
+  cmd /V /C "set "HOME=%HOMEDRIVE%%HOMEPATH%\electron-gyp" && call .\node_modules\.bin\node-pre-gyp.cmd configure rebuild package testpackage --runtime=electron --target=%%v --target_arch=%1 --disturl=https://atom.io/download/electron" || goto :error
 
   xcopy /Y /I /S build\stage\* artifacts\ || goto :error
 )
diff --git a/tools/run_tests/artifacts/build_artifact_node.sh b/tools/run_tests/artifacts/build_artifact_node.sh
index bb662d25d4..47b1f339fb 100755
--- a/tools/run_tests/artifacts/build_artifact_node.sh
+++ b/tools/run_tests/artifacts/build_artifact_node.sh
@@ -52,8 +52,8 @@ do
   cp -r build/stage/* artifacts/
 done
 
-for version in ${node_versions[@]}
+for version in ${electron_versions[@]}
 do
-  HOME=~/.electron-gyp ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --runtime=electron --target=$version --target_arch=$NODE_TARGET_ARCH
+  HOME=~/.electron-gyp ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --runtime=electron --target=$version --target_arch=$NODE_TARGET_ARCH --disturl=https://atom.io/download/electron
   cp -r build/stage/* artifacts/
 done
-- 
GitLab


From e8ec16da0ea70fd8d052d637e890af36cd91e951 Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Fri, 13 Jan 2017 11:00:53 -0800
Subject: [PATCH 314/344] Fix binding.gyp syntax

---
 binding.gyp                    | 2 +-
 templates/binding.gyp.template | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/binding.gyp b/binding.gyp
index d9461dbe00..479403ed21 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -54,7 +54,7 @@
           'GRPC_UV'
         ]
       }],
-      ['OS!="win" && runtime=="electron"', {
+      ['OS!="win" and runtime=="electron"', {
         "defines": [
           'OPENSSL_NO_THREADS'
         ]
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index b0585475ec..851effc4f3 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -56,7 +56,7 @@
             'GRPC_UV'
           ]
         }],
-        ['OS!="win" && runtime=="electron"', {
+        ['OS!="win" and runtime=="electron"', {
           "defines": [
             'OPENSSL_NO_THREADS'
           ]
-- 
GitLab


From df8f12203ce662860d514376af92c76237fd5b7f Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 13 Jan 2017 22:59:39 +0000
Subject: [PATCH 315/344] Fix API fuzzer tests.

---
 src/core/ext/client_channel/subchannel.c      | 35 ++++++++++++++-----
 src/core/ext/client_channel/subchannel.h      |  9 +++--
 .../ext/lb_policy/pick_first/pick_first.c     |  7 ++--
 .../ext/lb_policy/round_robin/round_robin.c   |  7 ++--
 .../chttp2/client/chttp2_connector.c          |  5 +--
 5 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index 7a2ad98433..f9de9993b7 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -38,6 +38,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/avl.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/initial_connect_string.h"
@@ -328,21 +329,16 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
     c->filters = NULL;
   }
   c->pollset_set = grpc_pollset_set_create();
-  const grpc_arg *addr_arg =
-      grpc_channel_args_find(args->args, GRPC_ARG_SUBCHANNEL_ADDRESS);
-  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
   grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
-  grpc_uri_to_sockaddr(addr_arg->value.string, addr);
+  grpc_get_subchannel_address_arg(args->args, addr);
   grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
   static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
-  grpc_arg new_arg;
-  new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-  new_arg.type = GRPC_ARG_STRING;
-  new_arg.value.string = grpc_sockaddr_to_uri(addr);
+  grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
   gpr_free(addr);
   c->args = grpc_channel_args_copy_and_add_and_remove(
       args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
   gpr_free(new_arg.value.string);
+
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
   grpc_closure_init(&c->connected, subchannel_connected, c,
@@ -781,7 +777,7 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
   return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
 }
 
-void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
+static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
   grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
   GPR_ASSERT(uri != NULL);
   if (strcmp(uri->scheme, "ipv4") == 0) {
@@ -793,3 +789,24 @@ void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
   }
   grpc_uri_destroy(uri);
 }
+
+void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+                                     grpc_resolved_address *addr) {
+  const grpc_arg *addr_arg =
+      grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
+  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
+  GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
+  memset(addr, 0, sizeof(*addr));
+  if (*addr_arg->value.string != '\0') {
+    grpc_uri_to_sockaddr(addr_arg->value.string, addr);
+  }
+}
+
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
+  grpc_arg new_arg;
+  new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
+  new_arg.type = GRPC_ARG_STRING;
+  new_arg.value.string =
+      addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("");
+  return new_arg;
+}
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index 4cc33fc79b..c7a9577ce9 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -174,7 +174,12 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
                                         grpc_connector *connector,
                                         const grpc_subchannel_args *args);
 
-/// Sets \a addr from \a uri_str.
-void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr);
+/// Sets \a addr from \a args.
+void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+                                     grpc_resolved_address *addr);
+
+/// Returns a new channel arg encoding the subchannel address as a string.
+/// Caller is responsible for freeing the string.
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr);
 
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 4677fb2343..9f2aa461be 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -468,11 +468,8 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
     }
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    grpc_arg addr_arg;
-    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-    addr_arg.type = GRPC_ARG_STRING;
-    addr_arg.value.string =
-        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_arg addr_arg =
+        grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
     grpc_channel_args *new_args =
         grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
     gpr_free(addr_arg.value.string);
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 3fe157a23c..d17d8fa057 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -731,11 +731,8 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
     if (addresses->addresses[i].is_balancer) continue;
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    grpc_arg addr_arg;
-    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-    addr_arg.type = GRPC_ARG_STRING;
-    addr_arg.value.string =
-        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_arg addr_arg =
+        grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
     grpc_channel_args *new_args =
         grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
     gpr_free(addr_arg.value.string);
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index ebe884b115..013c96dc70 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -221,11 +221,8 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
                                      grpc_connect_out_args *result,
                                      grpc_closure *notify) {
   chttp2_connector *c = (chttp2_connector *)con;
-  const grpc_arg *addr_arg =
-      grpc_channel_args_find(args->channel_args, GRPC_ARG_SUBCHANNEL_ADDRESS);
-  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
   grpc_resolved_address addr;
-  grpc_uri_to_sockaddr(addr_arg->value.string, &addr);
+  grpc_get_subchannel_address_arg(args->channel_args, &addr);
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(c->notify == NULL);
   c->notify = notify;
-- 
GitLab


From 92c93b99a0a46b7112288ca138df7e772a0431f0 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 13 Jan 2017 15:07:57 -0800
Subject: [PATCH 316/344] Ran generate_projects.sh.

---
 tools/doxygen/Doxyfile.c++           | 1 +
 tools/doxygen/Doxyfile.c++.internal  | 1 +
 tools/doxygen/Doxyfile.core          | 2 ++
 tools/doxygen/Doxyfile.core.internal | 2 ++
 4 files changed, 6 insertions(+)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index fa9b7057c5..84daed1041 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -866,6 +866,7 @@ include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/exec_ctx_fwd.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/port_platform.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index bca5652a46..37e4ad3f37 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -867,6 +867,7 @@ include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/exec_ctx_fwd.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/port_platform.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index ccbfe3a4e6..da990379ce 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -807,6 +807,8 @@ include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/exec_ctx_fwd.h \
+include/grpc/impl/codegen/gpr_slice.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/grpc_types.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index fc8fac32f0..4591aa50e3 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -807,6 +807,8 @@ include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/exec_ctx_fwd.h \
+include/grpc/impl/codegen/gpr_slice.h \
+include/grpc/impl/codegen/gpr_slice.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/gpr_types.h \
 include/grpc/impl/codegen/grpc_types.h \
-- 
GitLab


From 4242075c335473f8c3fc0b578196bdc878a3b9df Mon Sep 17 00:00:00 2001
From: Stanley Cheung <stanleycheung@google.com>
Date: Fri, 13 Jan 2017 15:23:11 -0800
Subject: [PATCH 317/344] PHP: Prepare for 1.1.0 release

---
 package.xml                    | 46 ++++++++++++++++++++++++++++------
 src/php/README.md              |  7 ++++++
 templates/package.xml.template | 46 ++++++++++++++++++++++++++++------
 3 files changed, 85 insertions(+), 14 deletions(-)

diff --git a/package.xml b/package.xml
index 4df1525827..ac5bcc54bf 100644
--- a/package.xml
+++ b/package.xml
@@ -10,19 +10,20 @@
   <email>grpc-packages@google.com</email>
   <active>yes</active>
  </lead>
- <date>2016-08-22</date>
+ <date>2017-01-13</date>
  <time>16:06:07</time>
  <version>
   <release>1.1.0dev</release>
   <api>1.1.0dev</api>
  </version>
  <stability>
-  <release>stable</release>
-  <api>stable</api>
+  <release>beta</release>
+  <api>beta</api>
  </stability>
  <license>BSD</license>
  <notes>
-- Reject metadata keys which are not legal #7881
+- PHP Proto3 adoption #8179
+- Various bug fixes     
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
@@ -1215,18 +1216,49 @@ Update to wrap gRPC C Core version 0.10.0
   </release>
   <release>
    <version>
-    <release>1.1.0dev</release>
-    <api>1.1.0dev</api>
+    <release>1.0.1RC1</release>
+    <api>1.0.1RC1</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2016-10-06</date>
+   <license>BSD</license>
+   <notes>
+- Reject metadata keys which are not legal #7881
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.1</release>
+    <api>1.0.1</api>
    </version>
    <stability>
     <release>stable</release>
     <api>stable</api>
    </stability>
-   <date>2016-08-22</date>
+   <date>2016-10-27</date>
    <license>BSD</license>
    <notes>
 - Reject metadata keys which are not legal #7881
    </notes>
   </release>
+  <release>
+   <version>
+    <release>1.1.0dev</release>
+    <api>1.1.0dev</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2017-01-13</date>
+   <license>BSD</license>
+   <notes>
+- PHP Proto3 adoption #8179
+- Various bug fixes     
+   </notes>
+  </release>
  </changelog>
 </package>
diff --git a/src/php/README.md b/src/php/README.md
index 1b15768d44..320220d3e4 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -163,6 +163,13 @@ of this repo. The plugin can be found in the `bins/opt` directory. We are
 planning to provide a better way to download and install the plugin
 in the future.
 
+You can also just build the gRPC PHP protoc plugin by running:
+
+```sh
+$ cd grpc
+$ make grpc_php_plugin
+```
+
 
 ### Client Stub
 
diff --git a/templates/package.xml.template b/templates/package.xml.template
index 32ed3b633e..80f1a1fe97 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,19 +12,20 @@
     <email>grpc-packages@google.com</email>
     <active>yes</active>
    </lead>
-   <date>2016-08-22</date>
+   <date>2017-01-13</date>
    <time>16:06:07</time>
    <version>
     <release>${settings.php_version.php()}</release>
     <api>${settings.php_version.php()}</api>
    </version>
    <stability>
-    <release>stable</release>
-    <api>stable</api>
+    <release>beta</release>
+    <api>beta</api>
    </stability>
    <license>BSD</license>
    <notes>
-  - Reject metadata keys which are not legal #7881
+  - PHP Proto3 adoption #8179
+  - Various bug fixes     
    </notes>
    <contents>
     <dir baseinstalldir="/" name="/">
@@ -281,18 +282,49 @@
     </release>
     <release>
      <version>
-      <release>${settings.php_version.php()}</release>
-      <api>${settings.php_version.php()}</api>
+      <release>1.0.1RC1</release>
+      <api>1.0.1RC1</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2016-10-06</date>
+     <license>BSD</license>
+     <notes>
+  - Reject metadata keys which are not legal #7881
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>1.0.1</release>
+      <api>1.0.1</api>
      </version>
      <stability>
       <release>stable</release>
       <api>stable</api>
      </stability>
-     <date>2016-08-22</date>
+     <date>2016-10-27</date>
      <license>BSD</license>
      <notes>
   - Reject metadata keys which are not legal #7881
      </notes>
     </release>
+    <release>
+     <version>
+      <release>1.1.0dev</release>
+      <api>1.1.0dev</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2017-01-13</date>
+     <license>BSD</license>
+     <notes>
+  - PHP Proto3 adoption #8179
+  - Various bug fixes     
+     </notes>
+    </release>
    </changelog>
   </package>
-- 
GitLab


From 0a5a31868a3166fd4e5b5581def5630e09e675a1 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Fri, 13 Jan 2017 16:54:03 -0800
Subject: [PATCH 318/344] Name constant

---
 src/core/ext/transport/chttp2/transport/chttp2_transport.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 339d2138c6..68a6a2155d 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -62,7 +62,7 @@
 #define DEFAULT_WINDOW 65535
 #define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
 #define MAX_WINDOW 0x7fffffffu
-
+#define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
 #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
 
 #define MAX_CLIENT_STREAM_ID 0x7fffffffu
@@ -326,7 +326,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                              GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
         t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
             &channel_args->args[i],
-            (grpc_integer_options){0, 0, 64 * 1024 * 1024});
+            (grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE});
       } else {
         static const struct {
           const char *channel_arg_name;
-- 
GitLab


From c1002c9f22e7bddc9d71831a6c20e0cb844f7846 Mon Sep 17 00:00:00 2001
From: Matt Kwong <mattkwong@google.com>
Date: Fri, 13 Jan 2017 17:26:11 -0800
Subject: [PATCH 319/344] Add api-fuzzer corpus

---
 .../08455b3ef9d516deb8155d8db7d51c43ce0ff07a  | Bin 0 -> 426 bytes
 .../0d19e60f4eb1b729e272dd5dec68e8b67f03a5f4  | Bin 0 -> 167 bytes
 .../14064ac4844c709b247a4345a92d8be9766785c4  | Bin 0 -> 316 bytes
 .../1901234bd7c9cb6ee19ff8b17179c481bdc7c5f2  | Bin 0 -> 345 bytes
 .../20ff1f8d5d34cb01d58aa334dc46a6644e6e1d12  | Bin 0 -> 199 bytes
 .../2378c3f1206f20711468391ce739116ffe58374b  | Bin 0 -> 216 bytes
 .../40640a91fda4e4e42d3063a28b9ffbba1b8c3701  | Bin 0 -> 226 bytes
 .../49f564289c79de9e0342f8b0821a167bc8c5ec00  | Bin 0 -> 183 bytes
 .../507865c4a5ce880b80400d93fa85def2682581cb  | Bin 0 -> 314 bytes
 .../5f2fdb01d8ff632803ca2b732a7c088c6843d7d3  | Bin 0 -> 349 bytes
 .../61de97a9d6c4b082602c02277d8d763921f5f95b  | Bin 0 -> 175 bytes
 .../62b039b8a318cc08471f13629da08c68c414d8e7  | Bin 0 -> 176 bytes
 .../641739453f7d4d3b55a1c7b79bed7da6dfd62ae0  | Bin 0 -> 175 bytes
 .../6589505362ffb5164a3c7cb1b9feadcddfba44e9  | Bin 0 -> 33 bytes
 .../724f5400f19e5a0be97022341c39eeaaaffeb390  | Bin 0 -> 336 bytes
 .../7254b9ff59ab3fcf345effdabbc25ebd2e907b23  | Bin 0 -> 167 bytes
 .../784d6f5c093ab5360670173ce001e1a446f95822  | Bin 0 -> 202 bytes
 .../79328fdc89d0af0e38da089dab062fd3ea5aae59  | Bin 0 -> 474 bytes
 .../7a2569f4daf4480ad142cb4ee7c675bed82db74c  | Bin 0 -> 547 bytes
 .../87a300cd25d2e57745bd00499d4d2352a10a2fa1  | Bin 0 -> 35 bytes
 .../8a1c629910280f8beebb88687696de98da988ecc  | Bin 0 -> 41 bytes
 .../8ff7b1568d2da2e4196c2e28617e1911d62021e6  | Bin 0 -> 371 bytes
 .../982f375b183d984958667461c7767206062eb4cb  | Bin 0 -> 429 bytes
 .../98739af631223fa05ad88f1e63a52052a9bb4b1c  | Bin 0 -> 178 bytes
 .../a78bca1ef8829d720dd5dedac3a9d4d12684da34  | Bin 0 -> 373 bytes
 .../ac763d89466ebfad676e75be0076831c03fe2a5d  | Bin 0 -> 473 bytes
 .../b165523f699e6ae9b2ad15873b9d56465d1af546  | Bin 0 -> 224 bytes
 .../b2a5ec3ef40c68d594638218e3c943a479f82215  | Bin 0 -> 474 bytes
 .../b92b1c5e0dba009a9516e7185f5df019c62c5cc9  | Bin 0 -> 414 bytes
 .../c5cd7af16e7bc0049445d5a0b92a3d4b7e5e3533  | Bin 0 -> 425 bytes
 ...h-da39a3ee5e6b4b0d3255bfef95601890afd80709 |   0
 .../e28ffd8c2816f12f6395805199c792d1718191df  | Bin 0 -> 371 bytes
 .../ec823f4018389e64a99f6580277fba28df6bd136  | Bin 0 -> 226 bytes
 .../ee2c1ac1e668f22836cf25a59495e778b0e2c7a8  | Bin 0 -> 338 bytes
 .../ee6855178435d2046d8763ecae46e1e0a71a95f4  | Bin 0 -> 178 bytes
 .../eeb310d91038cb02862e187e68c5d6578233485b  | Bin 0 -> 46 bytes
 .../f07bc2907c95f2aeb79ca60e2ad826e13b848f45  | Bin 0 -> 351 bytes
 .../fb655905396b768cf3ff015afdb0b564dae2cdfd  | Bin 0 -> 349 bytes
 .../fdb038087233cd176746558875932029f779221d  | Bin 0 -> 371 bytes
 tools/run_tests/generated/tests.json          | 932 +++++++++++++++++-
 40 files changed, 895 insertions(+), 37 deletions(-)
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/08455b3ef9d516deb8155d8db7d51c43ce0ff07a
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/0d19e60f4eb1b729e272dd5dec68e8b67f03a5f4
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/14064ac4844c709b247a4345a92d8be9766785c4
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/1901234bd7c9cb6ee19ff8b17179c481bdc7c5f2
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/20ff1f8d5d34cb01d58aa334dc46a6644e6e1d12
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/2378c3f1206f20711468391ce739116ffe58374b
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/40640a91fda4e4e42d3063a28b9ffbba1b8c3701
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/49f564289c79de9e0342f8b0821a167bc8c5ec00
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/507865c4a5ce880b80400d93fa85def2682581cb
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/5f2fdb01d8ff632803ca2b732a7c088c6843d7d3
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/61de97a9d6c4b082602c02277d8d763921f5f95b
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/62b039b8a318cc08471f13629da08c68c414d8e7
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/641739453f7d4d3b55a1c7b79bed7da6dfd62ae0
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/6589505362ffb5164a3c7cb1b9feadcddfba44e9
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/724f5400f19e5a0be97022341c39eeaaaffeb390
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/7254b9ff59ab3fcf345effdabbc25ebd2e907b23
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/784d6f5c093ab5360670173ce001e1a446f95822
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/79328fdc89d0af0e38da089dab062fd3ea5aae59
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/7a2569f4daf4480ad142cb4ee7c675bed82db74c
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/87a300cd25d2e57745bd00499d4d2352a10a2fa1
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/8a1c629910280f8beebb88687696de98da988ecc
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/8ff7b1568d2da2e4196c2e28617e1911d62021e6
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/982f375b183d984958667461c7767206062eb4cb
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/98739af631223fa05ad88f1e63a52052a9bb4b1c
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/a78bca1ef8829d720dd5dedac3a9d4d12684da34
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/ac763d89466ebfad676e75be0076831c03fe2a5d
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/b165523f699e6ae9b2ad15873b9d56465d1af546
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/b2a5ec3ef40c68d594638218e3c943a479f82215
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/b92b1c5e0dba009a9516e7185f5df019c62c5cc9
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/c5cd7af16e7bc0049445d5a0b92a3d4b7e5e3533
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/e28ffd8c2816f12f6395805199c792d1718191df
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/ec823f4018389e64a99f6580277fba28df6bd136
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/ee2c1ac1e668f22836cf25a59495e778b0e2c7a8
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/ee6855178435d2046d8763ecae46e1e0a71a95f4
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/eeb310d91038cb02862e187e68c5d6578233485b
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/f07bc2907c95f2aeb79ca60e2ad826e13b848f45
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/fb655905396b768cf3ff015afdb0b564dae2cdfd
 create mode 100644 test/core/end2end/fuzzers/api_fuzzer_corpus/fdb038087233cd176746558875932029f779221d

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/08455b3ef9d516deb8155d8db7d51c43ce0ff07a b/test/core/end2end/fuzzers/api_fuzzer_corpus/08455b3ef9d516deb8155d8db7d51c43ce0ff07a
new file mode 100644
index 0000000000000000000000000000000000000000..4b698ba9ee26c4cd200fcbdc446d61490dafbd70
GIT binary patch
literal 426
zcmZutJx;?g6#neANgz=db|fYcLp!n13vdf7G;UQX#L;t-iixEIOk98~^a>oN$EXnI
zIRP~wEWPD@fA6!jnp#c32&b4W&D>c1#tSL`0KE6a6;+~}3#xuoF3mTk$EjLOtu0hW
zD_yHHd(g_Tp4PdBo!U>gC{&%%yY|=-dUfvUEJ=egB>0Va#Nh>q1$sZ${A<Wj9`fNs
z;xRba!@VkpSNWqjxsN`eH_7!fYl>QBjo>TR^&`3x2qGEE*^T~S!L$F9uG5cPj5ZTZ
zrYUnp=6)?8LtjANCh2*rClrU9t826ZB4*cs#}lGCkfZ|SxbJok=fsv%gZ&OCF`^yr
F@CB$9iKhSn

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/0d19e60f4eb1b729e272dd5dec68e8b67f03a5f4 b/test/core/end2end/fuzzers/api_fuzzer_corpus/0d19e60f4eb1b729e272dd5dec68e8b67f03a5f4
new file mode 100644
index 0000000000000000000000000000000000000000..2889e7040e8eaf3d989ac735a1f866b4fef66b9f
GIT binary patch
literal 167
zcmZQ7PAw`+En;9`Vc=rWSI^If@EOyK3P3nnuedlTKCvo2wIn_-F*h|nAE>xUGczTX
zp;)i@-~Z&C_>#mTs4PShB-j7{|Nl_NdTt(OCI(gpFkt-E$-}_Fc$9@fn4O6&l}Xv)
wzkRTNM-dZSIbSMAQJIDoLm6Yyf1r|<Z;u%M|7UDrWO%fefs=z_ErSOG06jZ3Z~y=R

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/14064ac4844c709b247a4345a92d8be9766785c4 b/test/core/end2end/fuzzers/api_fuzzer_corpus/14064ac4844c709b247a4345a92d8be9766785c4
new file mode 100644
index 0000000000000000000000000000000000000000..fa731d4a050800e0341e9f837510685aa95af9b4
GIT binary patch
literal 316
zcmYL^F-rqM6oh9tvTig4Bw(oq!JGl3wy{WSD}wE^xjd7@GYRiD7gE_A7;XF&miH(8
zBf^1y!oqcfg|B+dz<e|NQUMU6vuEcCq!{x&?v3c)E>dUg!cAtJxD|r@XJuJxCeF<-
zF}06mW;rn@BSO~8eteu7XL(G{1oPi}^WHzTb{jPrP*PcO_5BjQaNdIk+{Te=0-vNC
z;s&*CsU%AXhWe5;eCH^Ks7iDWQ7@ix;5EcYQN4OP9$eg>uUV>PlQid17r9^`<`mUN
zJ0-p5yQu5K#ClPkZJ~uIP<P4z7KN^3+0-;Ri6?eCrPO5ZA-1MJq(wqWp0r04s)ZU-
Sxs^awiV&kw;(C*!`}hUu+gsTH

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/1901234bd7c9cb6ee19ff8b17179c481bdc7c5f2 b/test/core/end2end/fuzzers/api_fuzzer_corpus/1901234bd7c9cb6ee19ff8b17179c481bdc7c5f2
new file mode 100644
index 0000000000000000000000000000000000000000..ef09a0eaf535368d3ce7552dc17f084a12700661
GIT binary patch
literal 345
zcmZXQy-ve06ot=qi!rpSC_Dg2NPrkxb_T@8j+i4W+_p%8pzA0ZSu()HljJdYku1Cc
z0}>d!0i=Q@4?gGq_&Z~pWl)Z#WC8lv#Pl%FyEo0{KHhZVT$WgwbCKNHTTb#&EVG+y
zhMTxgpJqw%>vm@F{4>12qKBQqu&1zw<)QbdAwVyEZ0m}Rlxn0a&%Je}S?!<r-OE7`
z*?$PAZky9Bqjda?VNabzVy2IxbTx|YN5?2hd>C23wP7FCgmw>Y9g+SJjhCpQ(eT+p
ly0EL%vv2D2*B|N_$!Y|V@?RDWLS4Gx4TA<SpbMaY{Q^{(ZPx$*

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/20ff1f8d5d34cb01d58aa334dc46a6644e6e1d12 b/test/core/end2end/fuzzers/api_fuzzer_corpus/20ff1f8d5d34cb01d58aa334dc46a6644e6e1d12
new file mode 100644
index 0000000000000000000000000000000000000000..fc747d4a727b53e600bd04db9db113699e443c55
GIT binary patch
literal 199
zcmZQ7PAw`+En;9~VqjokVc=rWSI^G}iU9>3pQjfUFamM1UU6|wd}2|0YDs)vVs2`D
zK2S$;Mq*xGYEFD{Nn&z#d{Sv<P72VN#N7BitJJch%#_4}OospeLmBIZxp|nG7#M-Z
zGdO?<#$TO0K=LRH12a1lTPl;Xfwg_Gen$}#TRC4UM^T-I7Ivc<${36O12wjMdjvGt
Tim`=};n7+KP7a2(3?2*s9uhqz

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/2378c3f1206f20711468391ce739116ffe58374b b/test/core/end2end/fuzzers/api_fuzzer_corpus/2378c3f1206f20711468391ce739116ffe58374b
new file mode 100644
index 0000000000000000000000000000000000000000..ca3ce31cbe4d2f5cb8b0ac606ad2d411b042edc1
GIT binary patch
literal 216
zcmaKmF%E)26hvo{C<xIQEv=1EXivjYHY<FQh+vi#V`XDw<w>{{$FNx!?Ja&XlQ)?^
zGf@<<hS!Nh@hUk8t0viy1Z<44-B;DmvrL}*OEz^~a3y3$ikIR<yfSH-r-VP~rM14#
zJ)gmRC`&2;D`M{_;Q77fwGzpZBEDk?Fc@9>LFC9L4vo?Pdn~41iy$C|yvdiTp$4zR
TFY8(xuH(YYX3{a;wz_=)JcdB;

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/40640a91fda4e4e42d3063a28b9ffbba1b8c3701 b/test/core/end2end/fuzzers/api_fuzzer_corpus/40640a91fda4e4e42d3063a28b9ffbba1b8c3701
new file mode 100644
index 0000000000000000000000000000000000000000..f11821acc9a961be2847021d76fabc0f07f5bea6
GIT binary patch
literal 226
zcmZvVJ8r^26h-fh5nqdjB~XAUfEo%&M~|pS6Z^?n*kknkK{QE25f;NTvJo0~kRpxq
zkW$jz;(pH6IdMe{r6N8C)0~3Lg_h5zl)%`CTmcQBfi7mFEE8AyZx3nzFY?4#j;Jus
zrerdK1$*lpB_=Oya4_#>oP_dVQ{xs?aU9xXjJn>b&q2@kG?d`6ev10N`l8<rcrD!|
oJ)AFB+u0ZE=BZC@{uobQqfsfYWqA3y3wWU}3ilg2ZQQWIAAqMvQ~&?~

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/49f564289c79de9e0342f8b0821a167bc8c5ec00 b/test/core/end2end/fuzzers/api_fuzzer_corpus/49f564289c79de9e0342f8b0821a167bc8c5ec00
new file mode 100644
index 0000000000000000000000000000000000000000..c846377f0ae42e68a1ee99755acf49c31f2ff973
GIT binary patch
literal 183
zcmZQ7PAw`+En;9`Vc=rWSI^G}@__=5&(n(v7=buhuedlTKCvi0wIn_-F*h|nAE-Jx
zBQY;8H7C9}HMz7XH9j>jr64~uuY@5!&kCqJGbJ&T;s5_o#(H6H9%d#6#ttS11_lQp
zh6Bc5ojeRY3=E7%Ss0kvnb=a9lnt!ygY`R#nApnsQaOssG_)AX7>oV`m9%_&1T@Wx
Sv4xT05r-z{T86a@9t;3_wlwYl

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/507865c4a5ce880b80400d93fa85def2682581cb b/test/core/end2end/fuzzers/api_fuzzer_corpus/507865c4a5ce880b80400d93fa85def2682581cb
new file mode 100644
index 0000000000000000000000000000000000000000..c4473eacbb20789a2fb08b49a3affb734ee8e81f
GIT binary patch
literal 314
zcmXw!u}T9$6h-e$WSwY;NWj`4$Qno_ZJM<9g6%NbJd?$B6W>fWq_Wu}*!U4*xj*5L
z2n+s%h2t#Zs~-0h=iW0J0TANUtW!v_;B_*Z)4kbbPMeKet~hl&g!m6xo9U%<>oIck
zNP1Whb2=y3k^S*Wrk&vhIUS&0{j*o^{d4cQ(~`j?BO|_nR(PA6av$eW7x*OA5hrLx
zQsPiZW<+0-X73yqjXfD9l-nl@1@TeVFP<)@<J;>!%V^sr#qj`zU>}y0brW6Dp6}v8
zGpcOEN2rGf=phcuqYB=OQnj(|Dw<v<OOxl6Y3oe#KodRNq?8tEe@>yB;LzCZ1nNov
MZG{Rqcmvb~zi}X0q5uE@

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/5f2fdb01d8ff632803ca2b732a7c088c6843d7d3 b/test/core/end2end/fuzzers/api_fuzzer_corpus/5f2fdb01d8ff632803ca2b732a7c088c6843d7d3
new file mode 100644
index 0000000000000000000000000000000000000000..b91a052534a42714136e08b8481e1cc6604783b1
GIT binary patch
literal 349
zcmZ9GJxjw-6o%h(TVt#xi{R)74h<dJ&Rx2?m*QrK@el(x2`4eq$t9rv5GTpcaCLGQ
z0{#UD2d}3^7w>lNd!F|^reLX9fG&C%53)=)GsTq0B6&0_it8Yhn9CpymmFle99@NJ
z$`s2`V~(=)GL%(tqfJ2=b6Nu5*4hQ#?d|qETOe#6eLeO8dg-FGZ5%cyli7UyAja7@
zj{dKA$e^ROdNr41`LC1^3p6rg2bKww`DjhQdMbSDu`8AD4^fHwq#Tt=m6WTXD8rKR
zr=?bwXL5Yxc!0dK-gDms&WGWPCuK>fCbWJ<gr*%FHrR2|;1u;e4$iErmIiqCRkhbZ
UtQyy!Eza$9!x1!br%L={KQvrqO#lD@

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/61de97a9d6c4b082602c02277d8d763921f5f95b b/test/core/end2end/fuzzers/api_fuzzer_corpus/61de97a9d6c4b082602c02277d8d763921f5f95b
new file mode 100644
index 0000000000000000000000000000000000000000..a24008b1d47bcdfc98496cf9cf1243ae1791a920
GIT binary patch
literal 175
zcmZQ7PAw`+En;9`Vc=rWSI^If@Ey~O3K)SnS+BS_CqA(#J+&l0FEKYYJ|Cz!IU_MI
zFEuB=xFj(-J3gs2GbaUTLSk-wo>gj5QD#aiL;wH(|3ew;g}Hf{nHU%u85kH#7$AW0
zS0@jUdz6KNnVpF(l}Xv)zkRTNM-dZSIbSMAQJIDoLm6Yyf1r|<Z;u%M|F>dnVPtr;
NmVuLlVJ(9P0{}^oHBJBk

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/62b039b8a318cc08471f13629da08c68c414d8e7 b/test/core/end2end/fuzzers/api_fuzzer_corpus/62b039b8a318cc08471f13629da08c68c414d8e7
new file mode 100644
index 0000000000000000000000000000000000000000..e5e218acc372b72f89d20710875377e0a1ff8da9
GIT binary patch
literal 176
zcmZQ7PAw`+En;9`Vc=rWSI^If@EOyK3P3nnuehirH9kGDI43?YF*h|nAE-DvBQY;8
zH7CBfBr(Y}GAB8^GzDlvVlG&+C^IFMq5uE?|DlZa!rVN}Obm<+V89BY7=K;r<Y8c7
nJj%ih5n%XlAFSU|#Kcz4m&#EDwG?PwNn%lYY6-$tu)z!fK<hRe

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/641739453f7d4d3b55a1c7b79bed7da6dfd62ae0 b/test/core/end2end/fuzzers/api_fuzzer_corpus/641739453f7d4d3b55a1c7b79bed7da6dfd62ae0
new file mode 100644
index 0000000000000000000000000000000000000000..9dcc5c578cb20776ad4bfac86d5cc7a76bd13a14
GIT binary patch
literal 175
zcmZQ7PAw`+En;9`Vc=rWSI^If@Ey~O3K)SnS+BS_CqA(#J+&l0FEKYYJ|Cz!IU_MI
zFEuB=xFj(-J3gs2GbaUTLSk-wo>gj5QD#aiL;wH(|3ew;g}Hf{nHU%u85kH#KnMsJ
ze|7Qz$)hX`%<N2TsZ7cS|LueIJBpat%K1_`ipn&!7|Ixn{sWb?e0#+3|GyPu3nRm$
NwG5mb3~L!Y7yxLcHNyY^

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/6589505362ffb5164a3c7cb1b9feadcddfba44e9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/6589505362ffb5164a3c7cb1b9feadcddfba44e9
new file mode 100644
index 0000000000000000000000000000000000000000..10625da2fffb65152c5a7f18ff8bbd67053deeeb
GIT binary patch
literal 33
ocmZQ#<0?<JFDhf=V_;)SFDgjZOHR!zE-hwYD^KMp(qiHR0EWm2F8}}l

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/724f5400f19e5a0be97022341c39eeaaaffeb390 b/test/core/end2end/fuzzers/api_fuzzer_corpus/724f5400f19e5a0be97022341c39eeaaaffeb390
new file mode 100644
index 0000000000000000000000000000000000000000..1dbc5381926e4910170eb1d57ed0c71f72491987
GIT binary patch
literal 336
zcmZwBy$!-J5C!1p00ln<5))8C6$W4dN+brbtZ*ce;v}-Ih%OBc!!QM#Fajk7;rIyz
zfu$>+?)3b5mP|ngXrl+O8D^U-du9=u{64<5iBu+ZGS!MQDvXII1nb*t6(rK}ig>5A
z%(&9TYqg9~RpqEZXnE-1@x)~h3|9k>li=~WIPmp&D>YfGLXrukp^H$6bHyjS6IY0x
t_~ir*kJ9w|^X-}c1x3!~_yvJM$1jj-fKZD}S&L2wbf-9A!9sygx&ch5YXJZN

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/7254b9ff59ab3fcf345effdabbc25ebd2e907b23 b/test/core/end2end/fuzzers/api_fuzzer_corpus/7254b9ff59ab3fcf345effdabbc25ebd2e907b23
new file mode 100644
index 0000000000000000000000000000000000000000..92371e031fd5a3a16eb92dcc275eff45ee322ad8
GIT binary patch
literal 167
zcmZQ7PAw`+En;9`Vc=rWSI^HcP6zQB(~Al~I9ac_I47|vK0UQ0J})shH9j9GnU<N7
z%22FV{O^BqPJBsX5mXW^R|Jyl|NsAgC}X`aHxDxt11kd<F#hV~VPIf9`u{&OI}=+f
zld{2o`(XW!A||$SzEqB)G7T+;GRC6+KqW2T9x?p?&)CAq@MtXqCkMk?1`h@Rpp7>&

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/784d6f5c093ab5360670173ce001e1a446f95822 b/test/core/end2end/fuzzers/api_fuzzer_corpus/784d6f5c093ab5360670173ce001e1a446f95822
new file mode 100644
index 0000000000000000000000000000000000000000..79885b7f2a89ad24923574be3e4f35e300028aee
GIT binary patch
literal 202
zcmXYqy$%6E6ot>775~wA1O-u`)`(6o>dDx>Sz>oq?yeP;MnUCCJcbwX5DLwhgp-`&
zBwxOxa+Z<>sGx~)Kg)i59?PD5!%?0m+DOcWwkBnrc{tn{YdO(*VZxnWAGS&44JOrg
z$|Bo{ad*zG=-h3!0|g@B@8U4Ck&%-=_#16vwgsrbFZ8*!J^8F4sHrNe-o(w8<EyCZ
cvBPyK2Sb!3&Lfxi3(igHLU=vUsN;bJzG>1weE<Le

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/79328fdc89d0af0e38da089dab062fd3ea5aae59 b/test/core/end2end/fuzzers/api_fuzzer_corpus/79328fdc89d0af0e38da089dab062fd3ea5aae59
new file mode 100644
index 0000000000000000000000000000000000000000..4a5cbfd65419fde6e67ac0ecfb636e9cfd70d253
GIT binary patch
literal 474
zcmZ9IKTg9i6vm(3C{1XDgg600f{=kShoP{sBUmjrH6bERDkp>m2?-)ZCoaGhat0;_
zu91ZsFm%8?TSTI<Y|HPD?ceup@iYZm2w4dUV8I5A_wyWMOq_njazSuKheeSxE@M%$
zjL!wju{*lvS>}tB6(x^u*z`6@XZQx6vn<5x$&4=&Q0js_Y>&JF1@fZ+$BEv^>eIvh
z!-Bz(+TwBd=y-BIev#C^+Z2wh`~WH<v7gl6txh^(vS&VABh{d9h@u%g&U;q&KoLbi
zVI=fRy7H=&(uhQZ0oBVUt0ln5>%@tWty^@3KcirgR7SLM?>|J!${piYXO>|wHlihA
zO`vVSbqMfjtmPd5kw8)TrHO=tCqGa)-~ST*3er9e1LLS$w~h7eI^ZI^4jK#K41NK}
C*OFTR

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/7a2569f4daf4480ad142cb4ee7c675bed82db74c b/test/core/end2end/fuzzers/api_fuzzer_corpus/7a2569f4daf4480ad142cb4ee7c675bed82db74c
new file mode 100644
index 0000000000000000000000000000000000000000..75b55e7e107328f55f696cc1053637e8f9b78ed8
GIT binary patch
literal 547
zcmZuuJ5Iwu6r5crj=@$M`bbnDilm|m7vL6_v7dt_V_WM_L`9PVDlWhYka7hMlVe1P
z<*l87R$yt1-I+I^XQ{R7NC6|9Vv&|NWleAVAZ1M!!0+b1QkCe>xvFf+MR}kMxT@lL
zUFTt>R@8(=^gv<B^D0XS^}PPlaUM32`XGb-La$mso%w+?h6I1(F(CFYfG05M@r)5%
z{!wHvgBf>b4i{=Hnx#+-u~N>JQXh-G2lG7!m4wo$&6_Z41&}q5=v%;<NLMbd>67`-
zW+`U+{WvW~>nW+SEs{``cbR~6O#`{~gIPyY<+<z2D|7<F<AM$!Lzr+!KM+uw3vYJN
xT5Q<V*==#+VY0<7>~*LAulukbtG2zl9%_%j;wLrY`=}@==Qu#0xX;67zX1j|vuFSS

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/87a300cd25d2e57745bd00499d4d2352a10a2fa1 b/test/core/end2end/fuzzers/api_fuzzer_corpus/87a300cd25d2e57745bd00499d4d2352a10a2fa1
new file mode 100644
index 0000000000000000000000000000000000000000..c8f79862bc3c1721fbcccce5198bfe48ea3d3eec
GIT binary patch
literal 35
qcmZQ#<0?<JFDhf=V_;)SFDgjZOHR!zE-hwYU|=gx<tWl(;sXGa`Uo!o

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/8a1c629910280f8beebb88687696de98da988ecc b/test/core/end2end/fuzzers/api_fuzzer_corpus/8a1c629910280f8beebb88687696de98da988ecc
new file mode 100644
index 0000000000000000000000000000000000000000..ce3377fdc1e06745926690b5e3dbc5d7a5020e28
GIT binary patch
literal 41
ucmZQ#E9c{~x3y(ZV@PFWV%uNDSe#l^#*zA;v50}O<<VLO4u(f9AQAw_84B$H

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/8ff7b1568d2da2e4196c2e28617e1911d62021e6 b/test/core/end2end/fuzzers/api_fuzzer_corpus/8ff7b1568d2da2e4196c2e28617e1911d62021e6
new file mode 100644
index 0000000000000000000000000000000000000000..321520b870744d2441f1883a61d3337178b91fc3
GIT binary patch
literal 371
zcmZvYJx;_h5QU!|2xeJDLY#qyB9xTd(sKaIBtv#Z{xr4{L_?E?ij(A0IRYh(aT2YB
z#ExXmXhz@jo4Gb+2`Qx|?udaiY;gb5G*-r&r6me(=a;3{mfD%`f_mEVt*%W)x(N^;
z^5H*!0ybQbJ91bw_s+Es>Ap3uLHfBQZ4d91=9D#gaO3^Q&DA!NIL8v==M&h<rH(FS
zylPbDO=nG=^~_W|Z5@-TECMYCfoVh*_jgGu<31tvca_!7Yys;U1j3hJe-$x0nFNRw
scOm(ZrFsf7^QqKvkgSuAyuhWxh(|CaCOLN)VhCm<sGUcsr%`~_FX!rUK>z>%

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/982f375b183d984958667461c7767206062eb4cb b/test/core/end2end/fuzzers/api_fuzzer_corpus/982f375b183d984958667461c7767206062eb4cb
new file mode 100644
index 0000000000000000000000000000000000000000..01d07d64087e8f4ad4c927b72adff6746ad91a4b
GIT binary patch
literal 429
zcmZXQF;Bu!6ot=wkXnJ%7>y%pOcWV_nWd{cgJV<5wKkTP+&*fUTu8*pU*Xul;^c19
z#6RIuZ&h5p$s2C&yXT(o?E7(yBW(c+QmUasUIc>$M{}Q7-ZCTh{E!kObFJXm<emq&
zev*(zX8hoe#@=+Pt$T-T&fR_`8tcQovcP3TQ69xJVkou&-83OXwDr(JMGB+IV8hya
zb%^s`A2|o9$OcBX%*qpSL-@UoN{U=QJ+T~s-$`lMZw%{0)AWVaTA}RaE2U7B7smy5
zZ4|h|`Vrmh%C4;oTTfoAs2fXHbmnR;aJkq+6D<sH()6dV6ZlCX%VN*?9Fp-8e@<R1
z680Ff!_kZo4E}xCj-JKu!$G^F>R>osCNq!IX;j}<pHCRKN0Z@($J^Wlzte@v6@TYf
P3a^sL(AcTT{&>CsuV8#L

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/98739af631223fa05ad88f1e63a52052a9bb4b1c b/test/core/end2end/fuzzers/api_fuzzer_corpus/98739af631223fa05ad88f1e63a52052a9bb4b1c
new file mode 100644
index 0000000000000000000000000000000000000000..a4adb7aee6aed697073e4b761c17810c122928c5
GIT binary patch
literal 178
zcmWkmy$*sv80!J?m(53T&^V|wlWx9%^W}gGUW7Yx2du_~#fRZBd=VDkz`+GSnzTuq
zww{x=kroKBz+qzyc?!;-%$AIp?48TGu$ip57KP-7+R065EpzT-!RvdKs63?$QE(m6
zTBV{?7=|l*td^ngfjt?3(<md@?-i211Nc*KBE9v|np&sanpkPrX1hbf>_C<F+tW|P
NT86&Ee1;Ae`~e#lHnso&

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/a78bca1ef8829d720dd5dedac3a9d4d12684da34 b/test/core/end2end/fuzzers/api_fuzzer_corpus/a78bca1ef8829d720dd5dedac3a9d4d12684da34
new file mode 100644
index 0000000000000000000000000000000000000000..322d4ae019867b64b09253c957976c40ad9122cd
GIT binary patch
literal 373
zcmZvYJx;_x429n~5Qb$H32_D*icoNXZRt5cG$bawV)G-<C_ywd+fZ?moP=BC2$VF#
zB+*JpU}<E_*7xSwm&SV#k!9&vfD^26`_wd+;?>+zrL@z_Q)~B`GhZe5ypijyHWg=0
zfMi!3{__98MoM-^4zuRgx%MvIw&poVKkhlRyH`#N&YL2*@&4`VVjU4qF^Bqo2i7##
z(HX^yMrB^Iys7hEglm^sCu}N<K&yko=Qtpb`<q0k6!!`1-^(n9CKFf|VK6@Y@~?`~
wQ4%25(uL$hCjAg(reo>jAXz3Idxdk20rwCPMw&VTbqIDN=#59H$3a2#512u7HUIzs

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ac763d89466ebfad676e75be0076831c03fe2a5d b/test/core/end2end/fuzzers/api_fuzzer_corpus/ac763d89466ebfad676e75be0076831c03fe2a5d
new file mode 100644
index 0000000000000000000000000000000000000000..64c9720c9b9d11d6183076147266f1ea1cd0115f
GIT binary patch
literal 473
zcmZXQy-veG5QOKB=s1$dh#yfx5E6tGN$NCi=_x2J$610!Vn-XtQ7Rfsgo>x2^s7+O
zBU$1lkdRpeso3i7_I7sW+c!(HoNC7`OKR9Xe=@<5Hh_YZ+EQbl1>G5kQ=eDfVovP&
zV~P^#YX!%Wdmh~RQA8T^#1HOi;0+hrES*Z#?UbUC9qtx6E<*~_a55r>VhiY6GG>Uj
z?irM%(7*1kS({gfIBj>3auADbkjPZB@<co#{Ov|5MJ}JVj05mHDGmF^Fdv$RFRU_!
zqMfdkLS9^)<k+#uafR#=$2X;|tV=ddsr(W%nV7S>Eid)FY8hS9nUSEWrBbo0b#)fo
zsG*MDZ5;pJD>A=y=JSb{_&lb>i~K2hv546LWQM~LA?W`5uxUL@j)#NBj|rjDLXp8X
uRfUh^MKtm_9)^`C_4$NBqkr97^I$_)AT^JLZ>snQb0JtHvakiVw!Z;s1d5#i

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/b165523f699e6ae9b2ad15873b9d56465d1af546 b/test/core/end2end/fuzzers/api_fuzzer_corpus/b165523f699e6ae9b2ad15873b9d56465d1af546
new file mode 100644
index 0000000000000000000000000000000000000000..b0b7452924d35154493a18fe3db2c24b524d5e17
GIT binary patch
literal 224
zcmZQ7PAw`+En;9~OfM=()+;E=%uOt+j4uTW$0w$z=9MroF)%Q&FmN&GtLNtfMS-dv
zp99rG)E5`$#3vS|r<TO$CFZ8a=L3yO&PdG5OU;QdE=f$zj!!Dh%t-;7pO_n;XO&u3
zl$nxPkje1>e<)+UFgFh~69XgAcm@X$!T76_2S^@eVPIxwVoPOGHn6r2*6%1{Vk_rM
o<tVDt(86vsLm6Yyf1t*eZ;yZmTQRmUGCW$#z{$a|mcfGo0M<!HkN^Mx

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/b2a5ec3ef40c68d594638218e3c943a479f82215 b/test/core/end2end/fuzzers/api_fuzzer_corpus/b2a5ec3ef40c68d594638218e3c943a479f82215
new file mode 100644
index 0000000000000000000000000000000000000000..ac2b15440728cb62704432ed9b39919cb62f8bce
GIT binary patch
literal 474
zcmZXRKTiTd5XIlFWL<%r@lPxfW1>g_)HJmA6qc9c81W+9k>NN(WpjyG`6(>#t615a
zT;i87G3T6U<y5;nJ8$3n?V(wb<wQGXRZz_yc+)9Pv;mZY)Q+0)-0#den0dT*mkVOo
zn@|`-K`S_x1{eOF7lx#<h&}(F`tE3{&B`fN2kk<H(&PO+!&N{*5=_U$P;3ERi6;!v
z)?I^w6newXhP8Qhh?7<u3Hy=A`ms#KYgfc$!tdKCq-elrP2&LkPD;bRG0cai(F?0o
zA#WvXiIC-&ry2GvGF&5lMB}EgrFDtM2^C*rCKYp5x8$Unl`W$SIyVwDu~aA?XkD(w
zHY%v1dmBaDeMx3ZXR(;NvBwjN-O!tn8;O|hLuNP_6a3D<3xBO=$?<ShgKCKj!O}#Y
w!q!#EkE3Ncb~zdar789Kgnq3z>~6UKhgT@o8v-~{{KGjHE|OW`%E#?~1MAs}#Q*>R

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/b92b1c5e0dba009a9516e7185f5df019c62c5cc9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/b92b1c5e0dba009a9516e7185f5df019c62c5cc9
new file mode 100644
index 0000000000000000000000000000000000000000..3d542f38ec941b8daf69e53a4efdc309ce989ba2
GIT binary patch
literal 414
zcmZvYJx;_h5QU!|6wI=Ugg65YMJPDHw)7mpGRcr#kw1-10yH#fs5r@9YL7rkW1NIY
zD}g0z<Tvx4zVU@AOGqg#aYqcCV1=8<rm-?!O_C_M9dDLeTWV*%3hHUYSGqP8=_Z(X
zmk)pa|CkLI<Q5;M%&l|nZMtpEQ;2>jN!#5UrIa;!fbstQ@_Zdh%tw5G0Bea~nlM!7
zhF|q_VArOg+D&uOsf_3F%Dm_>l=aNC04gtr!ydKM)-joC5P%ilBZyhtUneS+ai5Sn
z-g)L8SuyWRAbk3XPsHeC5<H~13&n>j)qO}Azf>)aWbSn21<n-qxC2AtAV-BE2B?uf
Ng4%e5=V33v>IcTbfV%(y

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/c5cd7af16e7bc0049445d5a0b92a3d4b7e5e3533 b/test/core/end2end/fuzzers/api_fuzzer_corpus/c5cd7af16e7bc0049445d5a0b92a3d4b7e5e3533
new file mode 100644
index 0000000000000000000000000000000000000000..c8fca17ad38310b58ac412d25d5a72f963576097
GIT binary patch
literal 425
zcmZutJ5Iwu5S?8+w!u~!dL$|kMN-kg1-Qj(i6@aI<F#gOM^rQ^pyC2tAy?oqIYxw7
zW^JMv#7fi5d-FakEmDUB5W*?Um*&n`eCLIfe*oTl;)-g~&jr=LDVOGlGT>A%X4aNU
z(+V3^=|@zC@2SWU?96_-MX4H1ALy|o^yb|2S(*hCkic)kBlfQViGV?mZ~hfzD-U_|
zG4W`e<9M&CaVj5*od@eZ3?ex$bz3${w;ZBqo}ljlK`bLVzrj!DzxXfdD;=&yxSk@J
zw#pTmheCjiIDaT_)9k#%DJ9YR>KZx$B4O2l#}i_1m}UaVaox=hoD&<t@NNqy3B+5t
Fhi^>GiTD5j

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/e28ffd8c2816f12f6395805199c792d1718191df b/test/core/end2end/fuzzers/api_fuzzer_corpus/e28ffd8c2816f12f6395805199c792d1718191df
new file mode 100644
index 0000000000000000000000000000000000000000..a867a8b0be95755dba75d7a18e644d00086fbdc0
GIT binary patch
literal 371
zcmZvYJx;_h5QU!|6wI=Ugg65YMJPDHw)7mpGRcr#kw1;C1kuo>q2eUDRE|JNW1O{C
zLIO*p@yzIZe&Z`s*N{?L;(-`A!v=THU1w#wIkrT_{TfAXZLOX8s%WGg-{{sfq`Ls|
zp`8Bm|G<VTawiT)&AoH|eZKF_OOSr5N!!C4<s}te8QggPeto%3B;pa@AHX(N$+=9U
zL}Olc(Y3|MOs&(_F`339z+w_uW)$goo2gu;V@B%tD$&kr0dWli;nT-gMT$XY0V2gi
rNIqn#9)ryKRq8az;$$E%aG@~c0St*nt{sM$g7pMy=MnD9EWqjq_HuDR

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ec823f4018389e64a99f6580277fba28df6bd136 b/test/core/end2end/fuzzers/api_fuzzer_corpus/ec823f4018389e64a99f6580277fba28df6bd136
new file mode 100644
index 0000000000000000000000000000000000000000..2e6d409d39acb6f548711ddb81a46519a8061ab5
GIT binary patch
literal 226
zcmX|*F>b;@5JmqiW?2HF2nPsKil7ugp9`c%)E0t?g#>XlYuRNQ7oo~Ye2iSghoC@$
zVU4AXG{yWk^ZyvnlCuC29x#7N({`przM9_5yx+%bNjQr?*9VT%uq+?DEyK_JRX6)M
z`=>1oOn;%eqVMrw*s<v1UUWVV0s4#ZXbX0dn~^P)J3V9BJTLTVIS3-_ML=a;y}=pV
qJmXlYl}OzDM~p2-&H3~dIf(|#@>GXBDhc%jby=bBPyr6~9+Gbn%tuQA

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ee2c1ac1e668f22836cf25a59495e778b0e2c7a8 b/test/core/end2end/fuzzers/api_fuzzer_corpus/ee2c1ac1e668f22836cf25a59495e778b0e2c7a8
new file mode 100644
index 0000000000000000000000000000000000000000..f1990ac2315efdb5d9d0f2ee1dd090355d4811d6
GIT binary patch
literal 338
zcmXv}!AiqG6r9~kOtloG;MpQbEVSyimtMUKUYBk1OoK5kZ#OADdC8%8@gu}ze!?FS
z0{(;t*A3#FhM9qxIh6qbAx`urgA^%m;#oouy3DQ8rCqH#vpabC&oU-gD{D75DD)Gl
zX+_LgLNGJ)<KkRd%_&(`=&4%&d#}#9=h5+?Cw-F)wD<;ko_1L97-zu{_@r<kydFr2
zLm`<Fd`Viqb5wQh@hqmolm;QhN8P?SI=@?7U+q~2+aZM<iL~lchT?URXx^#P5G$Qh
zVKG4^*!h=r+r=+w&-c-!?!yIWrw14zngd4-oD+4}$95Rf;v!z@qM%$EtK&zSt7Vx{
bR%PRa{AR)aiQNgbjbGgl(cl(uKsd)QXscrT

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ee6855178435d2046d8763ecae46e1e0a71a95f4 b/test/core/end2end/fuzzers/api_fuzzer_corpus/ee6855178435d2046d8763ecae46e1e0a71a95f4
new file mode 100644
index 0000000000000000000000000000000000000000..6badaf36dc1c14580d3f6e18eb7e69a02908d72a
GIT binary patch
literal 178
zcmZQ7PAw`+En;9`Vc=rWSI^If@EOyK3P3nnuh_b%BsD%gu{b9_FEKYYJ|Cz$IU_MI
zFEuB=xFj(tJ~AgcyEFx8L}D&jvM4hpm7)Lt|No(k^}^gd%uEc7KnMklzb<w1FfcIw
z|9_N)ft7)QjR8ddw-46uC}LtO=S$@%D$~$nC}S-84^(yJ+arem|E(BX7#SX|W#Hss
JSj*tS000+0H&p-t

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/eeb310d91038cb02862e187e68c5d6578233485b b/test/core/end2end/fuzzers/api_fuzzer_corpus/eeb310d91038cb02862e187e68c5d6578233485b
new file mode 100644
index 0000000000000000000000000000000000000000..1b05cfb0367b6c63aa783bc2a6862382235d20df
GIT binary patch
literal 46
zcmZQ#E9Xn)C@Qm8W?*7UFDgjZOG!;jEX^s2Pb@9T$S=w)sbpYaU~GA`mVuLl0RS<H
B4Rrtj

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/f07bc2907c95f2aeb79ca60e2ad826e13b848f45 b/test/core/end2end/fuzzers/api_fuzzer_corpus/f07bc2907c95f2aeb79ca60e2ad826e13b848f45
new file mode 100644
index 0000000000000000000000000000000000000000..313d45626282eb3ad2035cad2187980293664282
GIT binary patch
literal 351
zcmZXQy-LJD6ot>suH)z~i>nWyAgEaE+FOX7y;z4K-u;1SmOCLSZBl6EljJdcku<)6
zg`ne2HY<n&GjPxSnfslwOA=^LoD(Ymee7a-nx>sH=arHhPrOee$8*Y}NB2NcD&;&|
z-V<W~J@Fxlvfu1FDY@{95bo5|!C=_a*plgT)aT1k-nTyX-D(L_kmX#DOcAKJtqtkp
zi*R^55Rt+cLzQ)Pxo5R$7P1u7T2gGM&#X-`YTD1vkt+@|w*08&PgN?^N2tpNjQ9`L
vxCNF*OIIiH!gcIj&8#E8e&3L{#%zMthKBT?9~H!rctJZB6|8J>17vVN67O#k

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/fb655905396b768cf3ff015afdb0b564dae2cdfd b/test/core/end2end/fuzzers/api_fuzzer_corpus/fb655905396b768cf3ff015afdb0b564dae2cdfd
new file mode 100644
index 0000000000000000000000000000000000000000..b02dabe03a80f708a041d18d13df473b2d7a97b5
GIT binary patch
literal 349
zcmZXQy-ve06ot=qOE9#mC_Dg2NPrkxb_T@8j+i4W-2O;`RM$~5vSfgXC&^>*B3XC?
z1|%?cQz{iKdGI;+$KM&6G=;J(1q;x{F2<)>*1l;fi*S>XwP|c*%6a@~9yrc?u}tRo
z3_G&lE=l8j?Y5@(+$)^Bqo;#jzoW2)<)P1)K0t3>?3=|LQOQ~gHHb>booyAdI=*m+
zw>>Yi`w~#q)R%i&Md3r59kmjP9zTnU%0Xy9J4Zp{{MhQF@jIy^G)HKvfc1xJxWx61
ony*fhnb{<ttjMq5f5}5En=u5^e|gmKb;*o(G-^PDZh#!-2MLpJ5dZ)H

literal 0
HcmV?d00001

diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/fdb038087233cd176746558875932029f779221d b/test/core/end2end/fuzzers/api_fuzzer_corpus/fdb038087233cd176746558875932029f779221d
new file mode 100644
index 0000000000000000000000000000000000000000..017fdbf661af95f27f13ae0a13ef31711144b563
GIT binary patch
literal 371
zcmZvYJx;_h5QU!|6wI=Ugg65YMJPDHw)7mpGRcr#kw1;C1kuo>q2eUDRE|JNW1O{C
zLIO*p@yzIZe&Z`s*N{?L;(-`A!v=THU1w#wIkrT_{TfAXZLOX8s%WGg-{{sfq`Ls|
zp`8Bm|G<VTawiT)&AoH|eZKF_OOSr5N!!C4<s}te8QggPeto%3B;pa@AHa64B$9KP
zMv2C}>Y{787@1n9tz$BcMS#U5u*@jZ@itSrOvjAW?^U9m)dJ!g1j46}uZk3d%mPG;
thmd^8QauKl^{dorkj2SBUf@Du#sfImTjbhdh$*;DpmrYNzRUuwegOCOaY6t9

literal 0
HcmV?d00001

diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index b76263b8b9..b595ef5055 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -40169,6 +40169,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/08455b3ef9d516deb8155d8db7d51c43ce0ff07a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/085865a209776911782f592c9f30ffe0ad3814a0"
@@ -40895,6 +40917,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/0d19e60f4eb1b729e272dd5dec68e8b67f03a5f4"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/0d604693a9d3e76f54d28a26142abd729b0a9acd"
@@ -41907,6 +41951,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/14064ac4844c709b247a4345a92d8be9766785c4"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/143789594154049441d565b65ce725fc4f8c12bc"
@@ -42677,6 +42743,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/1901234bd7c9cb6ee19ff8b17179c481bdc7c5f2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/190c4ca0cf29c99bc987d2792c7f62e1007c0245"
@@ -43777,6 +43865,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/20ff1f8d5d34cb01d58aa334dc46a6644e6e1d12"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/21357c3613a47180eb668b1c6c849ce9096a46eb"
@@ -44041,6 +44151,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/2378c3f1206f20711468391ce739116ffe58374b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/23982956d17d2f55e61a5d9111b1c0c7ee530214"
@@ -48639,6 +48771,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/40640a91fda4e4e42d3063a28b9ffbba1b8c3701"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/40b4b92460c4e76a39af9042fb3d86d491a98e16"
@@ -50157,6 +50311,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/49f564289c79de9e0342f8b0821a167bc8c5ec00"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/49ff30e0f070fe37b642dd0d361c5cbca139f223"
@@ -50971,6 +51147,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/507865c4a5ce880b80400d93fa85def2682581cb"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/507b8ecbb9fd3eea9084087bce22a94cca8a7c41"
@@ -53303,6 +53501,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/5f2fdb01d8ff632803ca2b732a7c088c6843d7d3"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/5f52309deaa1b641fe199889d18f921d6909fc14"
@@ -53679,7 +53899,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/61f410c711bc5d53be9e932217ebd035f2716417"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/61de97a9d6c4b082602c02277d8d763921f5f95b"
     ], 
     "ci_platforms": [
       "linux"
@@ -53701,7 +53921,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/622a3505d10767b795fc2c2922c0d5305d9b84e6"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/61f410c711bc5d53be9e932217ebd035f2716417"
     ], 
     "ci_platforms": [
       "linux"
@@ -53723,7 +53943,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/6230cce2862a18c4c92dc6fb4e034a1d15e1ff18"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/622a3505d10767b795fc2c2922c0d5305d9b84e6"
     ], 
     "ci_platforms": [
       "linux"
@@ -53745,7 +53965,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/6245a105123761558a71a9207b3048d2f3d691f0"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/6230cce2862a18c4c92dc6fb4e034a1d15e1ff18"
     ], 
     "ci_platforms": [
       "linux"
@@ -53767,7 +53987,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/629eac0e7443a273b5c351757c03fe15a0b87c1c"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/6245a105123761558a71a9207b3048d2f3d691f0"
     ], 
     "ci_platforms": [
       "linux"
@@ -53789,7 +54009,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/62c995646f15be1819bd13e32a60af46297d73b4"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/629eac0e7443a273b5c351757c03fe15a0b87c1c"
     ], 
     "ci_platforms": [
       "linux"
@@ -53811,7 +54031,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/62fbfe90a1b9ac471bc2644c896f64515f6b3c7e"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/62b039b8a318cc08471f13629da08c68c414d8e7"
     ], 
     "ci_platforms": [
       "linux"
@@ -53833,7 +54053,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/634d809c430738b89f0e677eec36506e537e86b3"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/62c995646f15be1819bd13e32a60af46297d73b4"
     ], 
     "ci_platforms": [
       "linux"
@@ -53855,7 +54075,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/63626e71d4e8e15905f13933f5b88d89073b3411"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/62fbfe90a1b9ac471bc2644c896f64515f6b3c7e"
     ], 
     "ci_platforms": [
       "linux"
@@ -53877,7 +54097,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/638c36cfe098b98008e594eddf90fdacfc078fae"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/634d809c430738b89f0e677eec36506e537e86b3"
     ], 
     "ci_platforms": [
       "linux"
@@ -53899,7 +54119,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/63b74d17bfbd015bb55dda59a05101bee001369c"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/63626e71d4e8e15905f13933f5b88d89073b3411"
     ], 
     "ci_platforms": [
       "linux"
@@ -53921,7 +54141,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/63b91deaac58a7b64fb5999628ff3ff5d32b719d"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/638c36cfe098b98008e594eddf90fdacfc078fae"
     ], 
     "ci_platforms": [
       "linux"
@@ -53943,7 +54163,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/63babc04d35adbe48add6e93386dfc838b0bbd25"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/63b74d17bfbd015bb55dda59a05101bee001369c"
     ], 
     "ci_platforms": [
       "linux"
@@ -53965,7 +54185,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/63d83cb5580d3222eb5e2d7982f7f995634ba5c1"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/63b91deaac58a7b64fb5999628ff3ff5d32b719d"
     ], 
     "ci_platforms": [
       "linux"
@@ -53987,7 +54207,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/6421db654fff309bc191aba0330fbcd1347655e3"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/63babc04d35adbe48add6e93386dfc838b0bbd25"
     ], 
     "ci_platforms": [
       "linux"
@@ -54009,7 +54229,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/645b8377f905399af625a01c76ff088745fe1640"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/63d83cb5580d3222eb5e2d7982f7f995634ba5c1"
     ], 
     "ci_platforms": [
       "linux"
@@ -54031,7 +54251,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/646c501021c79bf6eb1a39a9bcc82e018f31bca2"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/641739453f7d4d3b55a1c7b79bed7da6dfd62ae0"
     ], 
     "ci_platforms": [
       "linux"
@@ -54053,7 +54273,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/649cf0ee983cb5792042687181ce7e4d81f090a5"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/6421db654fff309bc191aba0330fbcd1347655e3"
     ], 
     "ci_platforms": [
       "linux"
@@ -54075,7 +54295,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/64c572e594c2d491a902e8fdff7b617ac0c6881b"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/645b8377f905399af625a01c76ff088745fe1640"
     ], 
     "ci_platforms": [
       "linux"
@@ -54097,7 +54317,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/64ce7e5553de2c081991af4fc386bffdd8d2e210"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/646c501021c79bf6eb1a39a9bcc82e018f31bca2"
     ], 
     "ci_platforms": [
       "linux"
@@ -54119,7 +54339,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/64d55e872c2148eefb0d7c3df101fd955b709f24"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/649cf0ee983cb5792042687181ce7e4d81f090a5"
     ], 
     "ci_platforms": [
       "linux"
@@ -54141,7 +54361,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/64eb970cc80162a4b80d49364f4227db3429e156"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/64c572e594c2d491a902e8fdff7b617ac0c6881b"
     ], 
     "ci_platforms": [
       "linux"
@@ -54163,7 +54383,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/6531f1c311678c9247ad6820519bc7e73f56cb81"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/64ce7e5553de2c081991af4fc386bffdd8d2e210"
     ], 
     "ci_platforms": [
       "linux"
@@ -54185,7 +54405,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/655b880459e6e00100727af9df52b64f6d77a653"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/64d55e872c2148eefb0d7c3df101fd955b709f24"
     ], 
     "ci_platforms": [
       "linux"
@@ -54207,7 +54427,95 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/655f952ec49cbc6176ad1bcfa45a87bd6c3542f0"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/64eb970cc80162a4b80d49364f4227db3429e156"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/6531f1c311678c9247ad6820519bc7e73f56cb81"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/655b880459e6e00100727af9df52b64f6d77a653"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/655f952ec49cbc6176ad1bcfa45a87bd6c3542f0"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/6589505362ffb5164a3c7cb1b9feadcddfba44e9"
     ], 
     "ci_platforms": [
       "linux"
@@ -56141,6 +56449,50 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/724f5400f19e5a0be97022341c39eeaaaffeb390"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/7254b9ff59ab3fcf345effdabbc25ebd2e907b23"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/727f43500183aec9c0d9be7d2363fa1761cda5d5"
@@ -57131,6 +57483,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/784d6f5c093ab5360670173ce001e1a446f95822"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/788f18727a0aeb5e200527bca7c889c9954be343"
@@ -57219,6 +57593,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/79328fdc89d0af0e38da089dab062fd3ea5aae59"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/7957953ca449974ec39c6a137c0acdedb71c3b02"
@@ -57417,6 +57813,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/7a2569f4daf4480ad142cb4ee7c675bed82db74c"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/7a5a769942efac79863bb154cf1e7574e6d98e22"
@@ -59397,6 +59815,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/87a300cd25d2e57745bd00499d4d2352a10a2fa1"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/87add83a18a25fe585df8adc124eae6d70733f74"
@@ -59793,6 +60233,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/8a1c629910280f8beebb88687696de98da988ecc"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/8a4183e6bb75036228a42039d678fca0ea6751b7"
@@ -60653,7 +61115,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/901c9a33205897999e7e78063ccdc5d363267568"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/8ff7b1568d2da2e4196c2e28617e1911d62021e6"
     ], 
     "ci_platforms": [
       "linux"
@@ -60675,7 +61137,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/90230730fae07c8eeb6b5bd571a119b486a21473"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/901c9a33205897999e7e78063ccdc5d363267568"
     ], 
     "ci_platforms": [
       "linux"
@@ -60697,7 +61159,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/904edc7bb14e4da0172f3d58a74c8abf141da9fb"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/90230730fae07c8eeb6b5bd571a119b486a21473"
     ], 
     "ci_platforms": [
       "linux"
@@ -60719,7 +61181,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/9080684608701e015c764f643dc45fa939d86ed3"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/904edc7bb14e4da0172f3d58a74c8abf141da9fb"
     ], 
     "ci_platforms": [
       "linux"
@@ -60741,7 +61203,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/908b1f170a721682465838d0c0eca40810beb722"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/9080684608701e015c764f643dc45fa939d86ed3"
     ], 
     "ci_platforms": [
       "linux"
@@ -60763,7 +61225,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/90a94b19bcf5aed7bfee94764acc906e889e47f8"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/908b1f170a721682465838d0c0eca40810beb722"
     ], 
     "ci_platforms": [
       "linux"
@@ -60785,7 +61247,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/90cd72030567bddbce06152fa0af1a024d542fa7"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/90a94b19bcf5aed7bfee94764acc906e889e47f8"
     ], 
     "ci_platforms": [
       "linux"
@@ -60807,7 +61269,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/910246d4e894dbf88b09e9c1994e0f7bd563bcc5"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/90cd72030567bddbce06152fa0af1a024d542fa7"
     ], 
     "ci_platforms": [
       "linux"
@@ -60829,7 +61291,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/913614cd0ae1b1210d2f1bc354b876080726f7a8"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/910246d4e894dbf88b09e9c1994e0f7bd563bcc5"
     ], 
     "ci_platforms": [
       "linux"
@@ -60851,7 +61313,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/91434e8bf241b54d98e0f664a12ecf5c9d144a8d"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/913614cd0ae1b1210d2f1bc354b876080726f7a8"
     ], 
     "ci_platforms": [
       "linux"
@@ -60873,7 +61335,7 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/91e2f574e7ceb7f69a93011aac68903cd014a6c7"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/91434e8bf241b54d98e0f664a12ecf5c9d144a8d"
     ], 
     "ci_platforms": [
       "linux"
@@ -60895,7 +61357,29 @@
   }, 
   {
     "args": [
-      "test/core/end2end/fuzzers/api_fuzzer_corpus/92273cf09f18534ae700c1f35dfab49faa091c54"
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/91e2f574e7ceb7f69a93011aac68903cd014a6c7"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/92273cf09f18534ae700c1f35dfab49faa091c54"
     ], 
     "ci_platforms": [
       "linux"
@@ -61597,6 +62081,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/982f375b183d984958667461c7767206062eb4cb"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/984b6ee241b92be62923c6dc5bacaadb36183b89"
@@ -61663,6 +62169,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/98739af631223fa05ad88f1e63a52052a9bb4b1c"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/988bd333d5dabe1561cf4429e7481ff110be0da4"
@@ -63797,6 +64325,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/a78bca1ef8829d720dd5dedac3a9d4d12684da34"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/a7ccc1f7db49512983fe4d42c16b2160357e3585"
@@ -64523,6 +65073,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/ac763d89466ebfad676e75be0076831c03fe2a5d"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/ac7b2971ff39a368145148524511dd68df83d522"
@@ -64985,6 +65557,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/b165523f699e6ae9b2ad15873b9d56465d1af546"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/b1e28018e26e6baaba5a907e5e6ff9b7a7942018"
@@ -65095,6 +65689,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/b2a5ec3ef40c68d594638218e3c943a479f82215"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/b2af0db70de3a6ddcb188d1f6f2a673133a8f9c7"
@@ -66239,6 +66855,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/b92b1c5e0dba009a9516e7185f5df019c62c5cc9"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/b9318513eb6b1db553855cd062ebbd4d1db9b846"
@@ -68373,6 +69011,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/c5cd7af16e7bc0049445d5a0b92a3d4b7e5e3533"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/c5dbc50d9174bde5542b2bb18c63f6583a23ff13"
@@ -71871,6 +72531,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-dc6abf90d5e8e1b96f7e25f418b1a7f572e6a738"
@@ -75039,6 +75721,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/e28ffd8c2816f12f6395805199c792d1718191df"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/e29bab478641dd412057dfb6b0a0d78afd96dd60"
@@ -76513,6 +77217,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/ec823f4018389e64a99f6580277fba28df6bd136"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/ec89eb7e84e6cf7859ab478362e0ae5227a5e154"
@@ -76843,6 +77569,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/ee2c1ac1e668f22836cf25a59495e778b0e2c7a8"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/ee624b408f8a50c79cdaebf4fb4195e6162b70da"
@@ -76865,6 +77613,50 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/ee6855178435d2046d8763ecae46e1e0a71a95f4"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/eeb310d91038cb02862e187e68c5d6578233485b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/eed65ac63a044c87423f333f3b9c5f0d3bc7bd3b"
@@ -77129,6 +77921,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/f07bc2907c95f2aeb79ca60e2ad826e13b848f45"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/f0a7e39c194ee3f30312ae2f4827bdbd43416a42"
@@ -78779,6 +79593,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/fb655905396b768cf3ff015afdb0b564dae2cdfd"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/fb76689d3c70bd5927b3256eda9738a2208e2b13"
@@ -79197,6 +80033,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/fdb038087233cd176746558875932029f779221d"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/fdecd05733278ece9993eb2bef13917675cc062c"
-- 
GitLab


From cc641688296a3cf7efbfd30b942b4cdf8d8049e7 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 17 Jan 2017 11:59:31 +0100
Subject: [PATCH 320/344] cmake support for generating from .proto files

---
 templates/CMakeLists.txt.template | 95 ++++++++++++++++++++++++++++---
 1 file changed, 87 insertions(+), 8 deletions(-)

diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 028c1b8c32..7868d41229 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -40,6 +40,17 @@
   # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
   <%!
+  
+  import re
+  
+  proto_re = re.compile('(.*)\\.proto')
+  
+  def proto_replace_ext(filename, ext):
+      m = proto_re.match(filename)
+      if not m:
+        return filename
+      return '${_gRPC_PROTO_GENS_DIR}/' + m.group(1) + ext
+  
   def get_deps(target_dict):
     deps = []
     if target_dict.get('baselib', False):
@@ -140,6 +151,9 @@
       if(TARGET libprotoc)
         set(_gRPC_PROTOBUF_PROTOC_LIBRARIES libprotoc)
       endif()
+      if(TARGET protoc)
+        set(_gRPC_PROTOBUF_PROTOC protoc)
+      endif()
     else()
         message(WARNING "gRPC_PROTOBUF_PROVIDER is \"module\" but PROTOBUF_ROOT_DIR is wrong")
     endif()
@@ -152,6 +166,9 @@
       if(TARGET protobuf::libprotoc)
         set(_gRPC_PROTOBUF_PROTOC_LIBRARIES protobuf::libprotoc)
       endif()
+      if(TARGET protobuf::protoc)
+        set(_gRPC_PROTOBUF_PROTOC protobuf::protoc)
+      endif()
       set(_gRPC_FIND_PROTOBUF "if(NOT protobuf_FOUND)\n  find_package(protobuf CONFIG)\nendif()")
     else()
       find_package(Protobuf MODULE)
@@ -192,16 +209,60 @@
   if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR)
     set(CMAKE_INSTALL_CMAKEDIR "<%text>${CMAKE_INSTALL_LIBDIR}</%text>/cmake/gRPC")
   endif()
-
+  
+  # Create directory for generated .proto files
+  set(_gRPC_PROTO_GENS_DIR <%text>${CMAKE_BINARY_DIR}/gens</%text>)
+  file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_GENS_DIR}</%text>)
+  
+  #  protobuf_generate_grpc_cpp
+  #  --------------------------
+  #
+  #   Add custom commands to process ``.proto`` files to C++ using protoc and
+  #   GRPC plugin::
+  #
+  #     protobuf_generate_grpc_cpp [<ARGN>...]
+  #
+  #   ``ARGN``
+  #     ``.proto`` files
+  #
+  function(protobuf_generate_grpc_cpp)
+    if(NOT ARGN)
+      message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files")
+      return()
+    endif()
+  
+    set(_protobuf_include_path -I .)
+    foreach(FIL <%text>${ARGN}</%text>)
+      get_filename_component(ABS_FIL <%text>${FIL}</%text> ABSOLUTE)
+      get_filename_component(FIL_WE <%text>${FIL}</%text> NAME_WE)
+      file(RELATIVE_PATH REL_FIL <%text>${CMAKE_SOURCE_DIR}</%text> <%text>${ABS_FIL}</%text>)
+      get_filename_component(REL_DIR <%text>${REL_FIL}</%text> DIRECTORY)
+      set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}</%text>")
+      
+      add_custom_command(
+        OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"</%text>
+               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"</%text>
+               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"</%text>
+               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"</%text>
+        COMMAND <%text>${_gRPC_PROTOBUF_PROTOC}</%text>
+        ARGS --grpc_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text>
+             --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text>
+             --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin>
+             <%text>${_protobuf_include_path}</%text>
+             <%text>${REL_FIL}</%text>
+        DEPENDS <%text>${ABS_FIL}</%text> <%text>${_gRPC_PROTOBUF_PROTOC}</%text> grpc_cpp_plugin
+        WORKING_DIRECTORY <%text>${CMAKE_SOURCE_DIR}</%text>
+        COMMENT "Running gRPC C++ protocol buffer compiler on <%text>${FIL}</%text>"
+        VERBATIM)
+        
+        <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)</%text>
+    endforeach()
+  endfunction()
+  
   % for lib in libs:
   % if lib.build in ["all", "protoc", "tool"] and lib.language in ['c', 'c++']:
-  ## TODO(jtattermusch): grpc++_reflection includes .proto files
-  ## which is not yet supported and thus fails the entire build.
-  ## Re-enable once fixed.
-  % if lib.name != 'grpc++_reflection':
-    ${cc_library(lib)}
-    ${cc_install(lib)}
-  % endif
+  ${cc_library(lib)}
+  ${cc_install(lib)}
   % endif
   % endfor
 
@@ -215,9 +276,24 @@
   <%def name="cc_library(lib)">
   add_library(${lib.name}
   % for src in lib.src:
+  % if not proto_re.match(src):
     ${src}
+  % else:
+    ${proto_replace_ext(src, '.pb.cc')}
+    ${proto_replace_ext(src, '.grpc.pb.cc')}
+    ${proto_replace_ext(src, '.pb.h')}
+    ${proto_replace_ext(src, '.grpc.pb.h')}
+  % endif
   % endfor
   )
+  
+  % for src in lib.src:
+  % if proto_re.match(src):
+  protobuf_generate_grpc_cpp(
+    ${src}
+  )
+  % endif
+  % endfor
 
   target_include_directories(${lib.name}
     PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>
@@ -226,6 +302,9 @@
     PRIVATE <%text>${PROTOBUF_ROOT_DIR}</%text>/src
     PRIVATE <%text>${ZLIB_INCLUDE_DIR}</%text>
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/zlib
+  % if any(proto_re.match(src) for src in lib.src):
+    PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
+  % endif
   )
 
   % if len(get_deps(lib)) > 0:
-- 
GitLab


From 54492aa70f366bfe9626f857c08702c5d010988c Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 17 Jan 2017 11:53:33 +0100
Subject: [PATCH 321/344] regenerate

---
 CMakeLists.txt | 142 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 126 insertions(+), 16 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4627c10e2e..a87e150b53 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,6 +122,9 @@ if("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module")
     if(TARGET libprotoc)
       set(_gRPC_PROTOBUF_PROTOC_LIBRARIES libprotoc)
     endif()
+    if(TARGET protoc)
+      set(_gRPC_PROTOBUF_PROTOC protoc)
+    endif()
   else()
       message(WARNING "gRPC_PROTOBUF_PROVIDER is \"module\" but PROTOBUF_ROOT_DIR is wrong")
   endif()
@@ -134,6 +137,9 @@ elseif("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package")
     if(TARGET protobuf::libprotoc)
       set(_gRPC_PROTOBUF_PROTOC_LIBRARIES protobuf::libprotoc)
     endif()
+    if(TARGET protobuf::protoc)
+      set(_gRPC_PROTOBUF_PROTOC protobuf::protoc)
+    endif()
     set(_gRPC_FIND_PROTOBUF "if(NOT protobuf_FOUND)\n  find_package(protobuf CONFIG)\nendif()")
   else()
     find_package(Protobuf MODULE)
@@ -175,7 +181,56 @@ if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR)
   set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/gRPC")
 endif()
 
-  
+# Create directory for generated .proto files
+set(_gRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens)
+file(MAKE_DIRECTORY ${_gRPC_PROTO_GENS_DIR})
+
+#  protobuf_generate_grpc_cpp
+#  --------------------------
+#
+#   Add custom commands to process ``.proto`` files to C++ using protoc and
+#   GRPC plugin::
+#
+#     protobuf_generate_grpc_cpp [<ARGN>...]
+#
+#   ``ARGN``
+#     ``.proto`` files
+#
+function(protobuf_generate_grpc_cpp)
+  if(NOT ARGN)
+    message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files")
+    return()
+  endif()
+
+  set(_protobuf_include_path -I .)
+  foreach(FIL ${ARGN})
+    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+    get_filename_component(FIL_WE ${FIL} NAME_WE)
+    file(RELATIVE_PATH REL_FIL ${CMAKE_SOURCE_DIR} ${ABS_FIL})
+    get_filename_component(REL_DIR ${REL_FIL} DIRECTORY)
+    set(RELFIL_WE "${REL_DIR}/${FIL_WE}")
+    
+    add_custom_command(
+      OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"
+             "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"
+             "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"
+             "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"
+      COMMAND ${_gRPC_PROTOBUF_PROTOC}
+      ARGS --grpc_out=${_gRPC_PROTO_GENS_DIR}
+           --cpp_out=${_gRPC_PROTO_GENS_DIR}
+           --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin>
+           ${_protobuf_include_path}
+           ${REL_FIL}
+      DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin
+      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+      COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}"
+      VERBATIM)
+      
+      set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)
+  endforeach()
+endfunction()
+
+
 add_library(gpr
   src/core/lib/profiling/basic_timers.c
   src/core/lib/profiling/stap_timers.c
@@ -223,6 +278,7 @@ add_library(gpr
   src/core/lib/support/wrap_memcpy.c
 )
 
+
 target_include_directories(gpr
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -279,7 +335,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS gpr EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -288,7 +344,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc
   src/core/lib/surface/init.c
   src/core/lib/channel/channel_args.c
@@ -509,6 +565,7 @@ add_library(grpc
   src/core/plugin_registry/grpc_plugin_registry.c
 )
 
+
 target_include_directories(grpc
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -563,7 +620,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -572,7 +629,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc_cronet
   src/core/lib/surface/init.c
   src/core/lib/channel/channel_args.c
@@ -764,6 +821,7 @@ add_library(grpc_cronet
   src/core/plugin_registry/grpc_cronet_plugin_registry.c
 )
 
+
 target_include_directories(grpc_cronet
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -817,7 +875,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc_cronet EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -826,7 +884,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc_unsecure
   src/core/lib/surface/init.c
   src/core/lib/surface/init_unsecure.c
@@ -1019,6 +1077,7 @@ add_library(grpc_unsecure
   src/core/plugin_registry/grpc_unsecure_plugin_registry.c
 )
 
+
 target_include_directories(grpc_unsecure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -1070,7 +1129,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc_unsecure EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -1079,7 +1138,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc++
   src/cpp/client/insecure_credentials.cc
   src/cpp/client/secure_credentials.cc
@@ -1120,6 +1179,7 @@ add_library(grpc++
   src/cpp/codegen/codegen_init.cc
 )
 
+
 target_include_directories(grpc++
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -1233,7 +1293,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc++ EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -1242,7 +1302,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc++_cronet
   src/cpp/client/cronet_credentials.cc
   src/cpp/client/insecure_credentials.cc
@@ -1456,6 +1516,7 @@ add_library(grpc++_cronet
   third_party/nanopb/pb_encode.c
 )
 
+
 target_include_directories(grpc++_cronet
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -1579,7 +1640,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc++_cronet EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -1588,7 +1649,54 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
+add_library(grpc++_reflection
+  src/cpp/ext/proto_server_reflection.cc
+  src/cpp/ext/proto_server_reflection_plugin.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/reflection/v1alpha/reflection.proto
+)
+
+target_include_directories(grpc++_reflection
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpc++_reflection
+  grpc++
+)
+
+foreach(_hdr
+  include/grpc++/ext/proto_server_reflection_plugin.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc++_reflection EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
 add_library(grpc++_unsecure
   src/cpp/client/insecure_credentials.cc
   src/cpp/common/insecure_create_auth_context.cc
@@ -1624,6 +1732,7 @@ add_library(grpc++_unsecure
   src/cpp/codegen/codegen_init.cc
 )
 
+
 target_include_directories(grpc++_unsecure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -1737,7 +1846,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc++_unsecure EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -1746,7 +1855,7 @@ if (gRPC_INSTALL)
   )
 endif()
 
-  
+
 add_library(grpc_plugin_support
   src/compiler/cpp_generator.cc
   src/compiler/csharp_generator.cc
@@ -1757,6 +1866,7 @@ add_library(grpc_plugin_support
   src/compiler/ruby_generator.cc
 )
 
+
 target_include_directories(grpc_plugin_support
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -1780,7 +1890,7 @@ foreach(_hdr
   )
 endforeach()
 
-  
+
 if (gRPC_INSTALL)
   install(TARGETS grpc_plugin_support EXPORT gRPCTargets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-- 
GitLab


From 31f2dd43e22f41c89cfdd3d25002972247d01954 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Tue, 17 Jan 2017 07:25:06 -0800
Subject: [PATCH 322/344] clang-format

---
 src/core/ext/client_channel/subchannel.c | 2 +-
 src/core/ext/client_channel/subchannel.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index f9de9993b7..8bd284507d 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -802,7 +802,7 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
   }
 }
 
-grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
   grpc_arg new_arg;
   new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
   new_arg.type = GRPC_ARG_STRING;
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index c7a9577ce9..684675eb37 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -180,6 +180,6 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
 
 /// Returns a new channel arg encoding the subchannel address as a string.
 /// Caller is responsible for freeing the string.
-grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr);
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);
 
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
-- 
GitLab


From ce0105fac4986f63ea86d75cc4c8b0f46a71d372 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Tue, 17 Jan 2017 07:36:51 -0800
Subject: [PATCH 323/344] Ran generate_projects.sh

---
 tools/doxygen/Doxyfile.c++           | 1 +
 tools/doxygen/Doxyfile.c++.internal  | 1 +
 tools/doxygen/Doxyfile.core          | 1 +
 tools/doxygen/Doxyfile.core.internal | 1 +
 4 files changed, 4 insertions(+)

diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index fa9b7057c5..ffa167898c 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -785,6 +785,7 @@ doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
+doc/service_config.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index bca5652a46..0a12e458d6 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -785,6 +785,7 @@ doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
+doc/service_config.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index ccbfe3a4e6..6e66ba0f39 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -784,6 +784,7 @@ doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
+doc/service_config.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index fc8fac32f0..d8c2f19704 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -784,6 +784,7 @@ doc/naming.md \
 doc/negative-http2-interop-test-descriptions.md \
 doc/server-reflection.md \
 doc/server_reflection_tutorial.md \
+doc/service_config.md \
 doc/statuscodes.md \
 doc/stress_test_framework.md \
 doc/wait-for-ready.md \
-- 
GitLab


From 886fb1245c97878725e0f82ffde0779e3ec8d394 Mon Sep 17 00:00:00 2001
From: Robbie Shade <rjshade@google.com>
Date: Tue, 17 Jan 2017 13:22:11 -0500
Subject: [PATCH 324/344] Force client to wait for server to start

---
 test/core/memory_usage/client.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c
index 9fc122b4c3..f4432bf572 100644
--- a/test/core/memory_usage/client.c
+++ b/test/core/memory_usage/client.c
@@ -79,6 +79,7 @@ static void init_ping_pong_request(int call_idx) {
   op = metadata_ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
+  op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
   op++;
   op->op = GRPC_OP_RECV_INITIAL_METADATA;
   op->data.recv_initial_metadata = &calls[call_idx].initial_metadata_recv;
@@ -133,6 +134,7 @@ static struct grpc_memory_counters send_snapshot_request(
 
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
+  op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
   op++;
   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
   op++;
-- 
GitLab


From 06dea573daa2175b244a430bb89b49bb5c8e8c5b Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Wed, 11 May 2016 12:01:40 -0700
Subject: [PATCH 325/344] Enable running Python formatting

---
 .gitignore                               |  1 +
 setup.cfg                                |  4 ++
 tools/distrib/pyformat_code.sh           | 60 ++++++++++++++++++++++++
 tools/run_tests/sanity/sanity_tests.yaml |  1 +
 4 files changed, 66 insertions(+)
 create mode 100755 tools/distrib/pyformat_code.sh

diff --git a/.gitignore b/.gitignore
index 3112445176..618c9ba5ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ objs
 # Python items
 cython_debug/
 python_build/
+python_format_venv/
 .coverage*
 .eggs
 htmlcov/
diff --git a/setup.cfg b/setup.cfg
index dd9161ca8b..218792e674 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -11,3 +11,7 @@ inplace=1
 
 [build_package_protos]
 exclude=.*protoc_plugin/protoc_plugin_test\.proto$
+
+# Style settings
+[yapf]
+based_on_style = google
diff --git a/tools/distrib/pyformat_code.sh b/tools/distrib/pyformat_code.sh
new file mode 100755
index 0000000000..e3ebf1c490
--- /dev/null
+++ b/tools/distrib/pyformat_code.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+# change to root directory
+cd $(dirname $0)/../..
+
+DIRS=src/python
+EXCLUSIONS='src/python/grpcio/grpc_*.py src/python/grpcio_health_checking/grpc_*.py src/python/grpcio_reflection/grpc_*.py src/python/grpcio_tests/grpc_*.py'
+
+VIRTUALENV=python_format_venv
+
+virtualenv $VIRTUALENV
+PYTHON=`realpath $VIRTUALENV/bin/python`
+$PYTHON -m pip install --upgrade futures yapf
+
+exclusion_args=""
+for exclusion in $EXCLUSIONS; do
+  exclusion_args="$exclusion_args --exclude $exclusion"
+done
+
+script_result=0
+for dir in $DIRS; do
+  tempdir=`mktemp -d`
+  cp -RT $dir $tempdir
+  $PYTHON -m yapf -i -r -p $exclusion_args $dir
+  if ! diff -rq $dir $tempdir; then
+    script_result=1
+  fi
+  rm -rf $tempdir
+done
+exit $script_result
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 37819166e3..f29b700572 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -12,5 +12,6 @@
 - script: tools/distrib/check_trailing_newlines.sh
 - script: tools/distrib/check_nanopb_output.sh
 - script: tools/distrib/check_include_guards.py
+- script: tools/distrib/pyformat_code.sh
 - script: tools/distrib/python/check_grpcio_tools.py
 
-- 
GitLab


From cc793703bfba6f661f523b6fec82ff8a913e1759 Mon Sep 17 00:00:00 2001
From: Masood Malekghassemi <atash@google.com>
Date: Fri, 13 Jan 2017 19:20:10 -0800
Subject: [PATCH 326/344] Run Python formatting

---
 src/python/grpcio/_spawn_patch.py             |   46 +-
 src/python/grpcio/commands.py                 |  352 ++--
 src/python/grpcio/grpc/__init__.py            |  744 ++++----
 src/python/grpcio/grpc/_auth.py               |   83 +-
 src/python/grpcio/grpc/_channel.py            | 1529 +++++++++--------
 src/python/grpcio/grpc/_common.py             |  123 +-
 .../grpcio/grpc/_credential_composition.py    |   18 +-
 src/python/grpcio/grpc/_plugin_wrapping.py    |  123 +-
 src/python/grpcio/grpc/_server.py             | 1092 ++++++------
 src/python/grpcio/grpc/_utilities.py          |  235 +--
 .../grpcio/grpc/beta/_client_adaptations.py   | 1028 ++++++-----
 .../grpcio/grpc/beta/_connectivity_channel.py |  213 +--
 .../grpcio/grpc/beta/_server_adaptations.py   |  544 +++---
 .../grpcio/grpc/beta/implementations.py       |  173 +-
 src/python/grpcio/grpc/beta/interfaces.py     |   78 +-
 src/python/grpcio/grpc/beta/utilities.py      |  202 ++-
 src/python/grpcio/grpc/framework/__init__.py  |    2 -
 .../grpcio/grpc/framework/common/__init__.py  |    2 -
 .../grpc/framework/common/cardinality.py      |   11 +-
 .../grpcio/grpc/framework/common/style.py     |    7 +-
 .../grpc/framework/foundation/__init__.py     |    2 -
 .../grpc/framework/foundation/abandonment.py  |    3 +-
 .../framework/foundation/callable_util.py     |   47 +-
 .../grpc/framework/foundation/future.py       |  129 +-
 .../grpc/framework/foundation/logging_pool.py |   55 +-
 .../grpc/framework/foundation/stream.py       |   28 +-
 .../grpc/framework/foundation/stream_util.py  |  227 ++-
 .../grpc/framework/interfaces/__init__.py     |    2 -
 .../framework/interfaces/base/__init__.py     |    2 -
 .../grpc/framework/interfaces/base/base.py    |  184 +-
 .../framework/interfaces/base/utilities.py    |   42 +-
 .../framework/interfaces/face/__init__.py     |    2 -
 .../grpc/framework/interfaces/face/face.py    |  610 ++++---
 .../framework/interfaces/face/utilities.py    |   87 +-
 src/python/grpcio/support.py                  |  103 +-
 .../grpc_health/__init__.py                   |    2 -
 .../grpc_health/v1/__init__.py                |    2 -
 .../grpc_health/v1/health.py                  |   33 +-
 .../grpcio_health_checking/health_commands.py |   53 +-
 src/python/grpcio_health_checking/setup.py    |   14 +-
 .../grpc_reflection/__init__.py               |    1 -
 .../grpc_reflection/v1alpha/__init__.py       |    1 -
 .../grpc_reflection/v1alpha/reflection.py     |  168 +-
 .../grpcio_reflection/reflection_commands.py  |   57 +-
 src/python/grpcio_reflection/setup.py         |   14 +-
 src/python/grpcio_tests/commands.py           |  266 ++-
 src/python/grpcio_tests/setup.py              |   42 +-
 src/python/grpcio_tests/tests/_loader.py      |   89 +-
 src/python/grpcio_tests/tests/_result.py      |  618 +++----
 src/python/grpcio_tests/tests/_runner.py      |  273 +--
 .../health_check/_health_servicer_test.py     |   87 +-
 .../tests/http2/_negative_http2_client.py     |  175 +-
 .../grpcio_tests/tests/interop/__init__.py    |    2 -
 .../tests/interop/_insecure_intraop_test.py   |   24 +-
 .../tests/interop/_intraop_test_case.py       |   38 +-
 .../tests/interop/_secure_intraop_test.py     |   35 +-
 .../grpcio_tests/tests/interop/client.py      |  163 +-
 .../grpcio_tests/tests/interop/methods.py     |  759 ++++----
 .../grpcio_tests/tests/interop/resources.py   |   21 +-
 .../grpcio_tests/tests/interop/server.py      |   57 +-
 .../tests/protoc_plugin/__init__.py           |    2 -
 .../protoc_plugin/_python_plugin_test.py      |  754 ++++----
 .../protoc_plugin/_split_definitions_test.py  |  446 ++---
 .../protoc_plugin/beta_python_plugin_test.py  |  716 ++++----
 .../tests/protoc_plugin/protos/__init__.py    |    2 -
 .../protos/invocation_testing/__init__.py     |    2 -
 .../split_messages/__init__.py                |    2 -
 .../split_services/__init__.py                |    2 -
 .../protoc_plugin/protos/payload/__init__.py  |    2 -
 .../protoc_plugin/protos/requests/__init__.py |    2 -
 .../protos/requests/r/__init__.py             |    2 -
 .../protos/responses/__init__.py              |    2 -
 .../protoc_plugin/protos/service/__init__.py  |    2 -
 .../tests/qps/benchmark_client.py             |  280 +--
 .../tests/qps/benchmark_server.py             |   32 +-
 .../grpcio_tests/tests/qps/client_runner.py   |  107 +-
 .../grpcio_tests/tests/qps/histogram.py       |   82 +-
 .../grpcio_tests/tests/qps/qps_worker.py      |   34 +-
 .../grpcio_tests/tests/qps/worker_server.py   |  297 ++--
 .../reflection/_reflection_servicer_test.py   |  234 ++-
 .../grpcio_tests/tests/stress/client.py       |  217 +--
 .../tests/stress/metrics_server.py            |   41 +-
 .../grpcio_tests/tests/stress/test_runner.py  |   59 +-
 .../grpcio_tests/tests/unit/__init__.py       |    2 -
 .../grpcio_tests/tests/unit/_api_test.py      |  117 +-
 .../grpcio_tests/tests/unit/_auth_test.py     |   69 +-
 .../tests/unit/_channel_args_test.py          |   20 +-
 .../tests/unit/_channel_connectivity_test.py  |  209 ++-
 .../tests/unit/_channel_ready_future_test.py  |  108 +-
 .../tests/unit/_compression_test.py           |  147 +-
 .../tests/unit/_credentials_test.py           |   56 +-
 .../unit/_cython/_cancel_many_calls_test.py   |  302 ++--
 .../tests/unit/_cython/_channel_test.py       |   55 +-
 .../_read_some_but_not_all_responses_test.py  |  402 ++---
 .../tests/unit/_cython/cygrpc_test.py         |  710 ++++----
 .../tests/unit/_cython/test_utilities.py      |   45 +-
 .../tests/unit/_empty_message_test.py         |  125 +-
 .../tests/unit/_exit_scenarios.py             |  269 ++-
 .../grpcio_tests/tests/unit/_exit_test.py     |  243 +--
 .../tests/unit/_invalid_metadata_test.py      |  223 +--
 .../tests/unit/_invocation_defects_test.py    |  316 ++--
 .../tests/unit/_junkdrawer/__init__.py        |    2 -
 .../tests/unit/_junkdrawer/stock_pb2.py       |  209 ++-
 .../tests/unit/_metadata_code_details_test.py |  901 +++++-----
 .../grpcio_tests/tests/unit/_metadata_test.py |  254 +--
 .../grpcio_tests/tests/unit/_rpc_test.py      | 1414 +++++++--------
 .../tests/unit/_sanity/__init__.py            |    2 -
 .../tests/unit/_sanity/_sanity_test.py        |   32 +-
 .../tests/unit/_thread_cleanup_test.py        |  143 +-
 .../grpcio_tests/tests/unit/_thread_pool.py   |   25 +-
 .../grpcio_tests/tests/unit/beta/__init__.py  |    2 -
 .../tests/unit/beta/_beta_features_test.py    |  528 +++---
 .../unit/beta/_connectivity_channel_test.py   |   15 +-
 .../tests/unit/beta/_face_interface_test.py   |  160 +-
 .../tests/unit/beta/_implementations_test.py  |   44 +-
 .../tests/unit/beta/_not_found_test.py        |   58 +-
 .../tests/unit/beta/_utilities_test.py        |  113 +-
 .../tests/unit/beta/test_utilities.py         |   17 +-
 .../tests/unit/framework/__init__.py          |    2 -
 .../tests/unit/framework/common/__init__.py   |    2 -
 .../unit/framework/common/test_constants.py   |    1 -
 .../unit/framework/common/test_control.py     |   97 +-
 .../unit/framework/common/test_coverage.py    |  117 +-
 .../unit/framework/foundation/__init__.py     |    2 -
 .../foundation/_logging_pool_test.py          |   64 +-
 .../framework/foundation/stream_testing.py    |   55 +-
 .../unit/framework/interfaces/__init__.py     |    2 -
 .../interfaces/face/_3069_test_constant.py    |    1 -
 .../framework/interfaces/face/__init__.py     |    2 -
 .../_blocking_invocation_inline_service.py    |  465 ++---
 .../unit/framework/interfaces/face/_digest.py |  550 +++---
 ...e_invocation_asynchronous_event_service.py |  876 +++++-----
 .../framework/interfaces/face/_invocation.py  |  187 +-
 .../framework/interfaces/face/_service.py     |  159 +-
 .../interfaces/face/_stock_service.py         |  519 +++---
 .../framework/interfaces/face/test_cases.py   |   27 +-
 .../interfaces/face/test_interfaces.py        |  144 +-
 .../grpcio_tests/tests/unit/resources.py      |   11 +-
 .../grpcio_tests/tests/unit/test_common.py    |   69 +-
 139 files changed, 12827 insertions(+), 12303 deletions(-)

diff --git a/src/python/grpcio/_spawn_patch.py b/src/python/grpcio/_spawn_patch.py
index 24306f0dd9..75d0a8b352 100644
--- a/src/python/grpcio/_spawn_patch.py
+++ b/src/python/grpcio/_spawn_patch.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Patches the spawn() command for windows compilers.
 
 Windows has an 8191 character command line limit, but some compilers
@@ -45,29 +44,32 @@ MAX_COMMAND_LENGTH = 8191
 
 _classic_spawn = ccompiler.CCompiler.spawn
 
+
 def _commandfile_spawn(self, command):
-  command_length = sum([len(arg) for arg in command])
-  if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
-    # Even if this command doesn't support the @command_file, it will
-    # fail as is so we try blindly
-    print('Command line length exceeded, using command file')
-    print(' '.join(command))
-    temporary_directory = tempfile.mkdtemp()
-    command_filename = os.path.abspath(
-    os.path.join(temporary_directory, 'command'))
-    with open(command_filename, 'w') as command_file:
-      escaped_args = ['"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]]
-      command_file.write(' '.join(escaped_args))
-    modified_command = command[:1] + ['@{}'.format(command_filename)]
-    try:
-      _classic_spawn(self, modified_command)
-    finally:
-      shutil.rmtree(temporary_directory)
-  else:
-    _classic_spawn(self, command)
+    command_length = sum([len(arg) for arg in command])
+    if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
+        # Even if this command doesn't support the @command_file, it will
+        # fail as is so we try blindly
+        print('Command line length exceeded, using command file')
+        print(' '.join(command))
+        temporary_directory = tempfile.mkdtemp()
+        command_filename = os.path.abspath(
+            os.path.join(temporary_directory, 'command'))
+        with open(command_filename, 'w') as command_file:
+            escaped_args = [
+                '"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]
+            ]
+            command_file.write(' '.join(escaped_args))
+        modified_command = command[:1] + ['@{}'.format(command_filename)]
+        try:
+            _classic_spawn(self, modified_command)
+        finally:
+            shutil.rmtree(temporary_directory)
+    else:
+        _classic_spawn(self, command)
 
 
 def monkeypatch_spawn():
-  """Monkeypatching is dumb, but it's either that or we become maintainers of
+    """Monkeypatching is dumb, but it's either that or we become maintainers of
      something much, much bigger."""
-  ccompiler.CCompiler.spawn = _commandfile_spawn
+    ccompiler.CCompiler.spawn = _commandfile_spawn
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 701c6af017..e09f922591 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Provides distutils command classes for the GRPC Python setup process."""
 
 import distutils
@@ -87,138 +86,144 @@ Glossary
 
 
 class CommandError(Exception):
-  """Simple exception class for GRPC custom commands."""
+    """Simple exception class for GRPC custom commands."""
 
 
 # TODO(atash): Remove this once PyPI has better Linux bdist support. See
 # https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
 def _get_grpc_custom_bdist(decorated_basename, target_bdist_basename):
-  """Returns a string path to a bdist file for Linux to install.
+    """Returns a string path to a bdist file for Linux to install.
 
   If we can retrieve a pre-compiled bdist from online, uses it. Else, emits a
   warning and builds from source.
   """
-  # TODO(atash): somehow the name that's returned from `wheel` is different
-  # between different versions of 'wheel' (but from a compatibility standpoint,
-  # the names are compatible); we should have some way of determining name
-  # compatibility in the same way `wheel` does to avoid having to rename all of
-  # the custom wheels that we build/upload to GCS.
-
-  # Break import style to ensure that setup.py has had a chance to install the
-  # relevant package.
-  from six.moves.urllib import request
-  decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT
-  try:
-    url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
-    bdist_data = request.urlopen(url).read()
-  except IOError as error:
-    raise CommandError(
-        '{}\n\nCould not find the bdist {}: {}'
-            .format(traceback.format_exc(), decorated_path, error.message))
-  # Our chosen local bdist path.
-  bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT
-  try:
-    with open(bdist_path, 'w') as bdist_file:
-      bdist_file.write(bdist_data)
-  except IOError as error:
-    raise CommandError(
-        '{}\n\nCould not write grpcio bdist: {}'
-            .format(traceback.format_exc(), error.message))
-  return bdist_path
+    # TODO(atash): somehow the name that's returned from `wheel` is different
+    # between different versions of 'wheel' (but from a compatibility standpoint,
+    # the names are compatible); we should have some way of determining name
+    # compatibility in the same way `wheel` does to avoid having to rename all of
+    # the custom wheels that we build/upload to GCS.
+
+    # Break import style to ensure that setup.py has had a chance to install the
+    # relevant package.
+    from six.moves.urllib import request
+    decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT
+    try:
+        url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
+        bdist_data = request.urlopen(url).read()
+    except IOError as error:
+        raise CommandError('{}\n\nCould not find the bdist {}: {}'.format(
+            traceback.format_exc(), decorated_path, error.message))
+    # Our chosen local bdist path.
+    bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT
+    try:
+        with open(bdist_path, 'w') as bdist_file:
+            bdist_file.write(bdist_data)
+    except IOError as error:
+        raise CommandError('{}\n\nCould not write grpcio bdist: {}'
+                           .format(traceback.format_exc(), error.message))
+    return bdist_path
 
 
 class SphinxDocumentation(setuptools.Command):
-  """Command to generate documentation via sphinx."""
-
-  description = 'generate sphinx documentation'
-  user_options = []
-
-  def initialize_options(self):
-    pass
-
-  def finalize_options(self):
-    pass
-
-  def run(self):
-    # We import here to ensure that setup.py has had a chance to install the
-    # relevant package eggs first.
-    import sphinx
-    import sphinx.apidoc
-    metadata = self.distribution.metadata
-    src_dir = os.path.join(PYTHON_STEM, 'grpc')
-    sys.path.append(src_dir)
-    sphinx.apidoc.main([
-        '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
-        '-V', metadata.version, '-R', metadata.version,
-        '-o', os.path.join('doc', 'src'), src_dir])
-    conf_filepath = os.path.join('doc', 'src', 'conf.py')
-    with open(conf_filepath, 'a') as conf_file:
-      conf_file.write(CONF_PY_ADDENDUM)
-    glossary_filepath = os.path.join('doc', 'src', 'grpc.rst')
-    with open(glossary_filepath, 'a') as glossary_filepath:
-      glossary_filepath.write(API_GLOSSARY)
-    sphinx.main(['', os.path.join('doc', 'src'), os.path.join('doc', 'build')])
+    """Command to generate documentation via sphinx."""
+
+    description = 'generate sphinx documentation'
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        # We import here to ensure that setup.py has had a chance to install the
+        # relevant package eggs first.
+        import sphinx
+        import sphinx.apidoc
+        metadata = self.distribution.metadata
+        src_dir = os.path.join(PYTHON_STEM, 'grpc')
+        sys.path.append(src_dir)
+        sphinx.apidoc.main([
+            '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
+            '-V', metadata.version, '-R', metadata.version, '-o',
+            os.path.join('doc', 'src'), src_dir
+        ])
+        conf_filepath = os.path.join('doc', 'src', 'conf.py')
+        with open(conf_filepath, 'a') as conf_file:
+            conf_file.write(CONF_PY_ADDENDUM)
+        glossary_filepath = os.path.join('doc', 'src', 'grpc.rst')
+        with open(glossary_filepath, 'a') as glossary_filepath:
+            glossary_filepath.write(API_GLOSSARY)
+        sphinx.main(
+            ['', os.path.join('doc', 'src'), os.path.join('doc', 'build')])
 
 
 class BuildProjectMetadata(setuptools.Command):
-  """Command to generate project metadata in a module."""
+    """Command to generate project metadata in a module."""
 
-  description = 'build grpcio project metadata files'
-  user_options = []
+    description = 'build grpcio project metadata files'
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'), 'w') as module_file:
-      module_file.write('__version__ = """{}"""'.format(
-          self.distribution.get_version()))
+    def run(self):
+        with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'),
+                  'w') as module_file:
+            module_file.write('__version__ = """{}"""'.format(
+                self.distribution.get_version()))
 
 
 class BuildPy(build_py.build_py):
-  """Custom project build command."""
+    """Custom project build command."""
 
-  def run(self):
-    self.run_command('build_project_metadata')
-    build_py.build_py.run(self)
+    def run(self):
+        self.run_command('build_project_metadata')
+        build_py.build_py.run(self)
 
 
 def _poison_extensions(extensions, message):
-  """Includes a file that will always fail to compile in all extensions."""
-  poison_filename = os.path.join(PYTHON_STEM, 'poison.c')
-  with open(poison_filename, 'w') as poison:
-    poison.write('#error {}'.format(message))
-  for extension in extensions:
-    extension.sources = [poison_filename]
+    """Includes a file that will always fail to compile in all extensions."""
+    poison_filename = os.path.join(PYTHON_STEM, 'poison.c')
+    with open(poison_filename, 'w') as poison:
+        poison.write('#error {}'.format(message))
+    for extension in extensions:
+        extension.sources = [poison_filename]
+
 
 def check_and_update_cythonization(extensions):
-  """Replace .pyx files with their generated counterparts and return whether or
+    """Replace .pyx files with their generated counterparts and return whether or
      not cythonization still needs to occur."""
-  for extension in extensions:
-    generated_pyx_sources = []
-    other_sources = []
-    for source in extension.sources:
-      base, file_ext = os.path.splitext(source)
-      if file_ext == '.pyx':
-        generated_pyx_source = next(
-            (base + gen_ext for gen_ext in ('.c', '.cpp',)
-             if os.path.isfile(base + gen_ext)), None)
-        if generated_pyx_source:
-          generated_pyx_sources.append(generated_pyx_source)
-        else:
-          sys.stderr.write('Cython-generated files are missing...\n')
-          return False
-      else:
-        other_sources.append(source)
-    extension.sources = generated_pyx_sources + other_sources
-  sys.stderr.write('Found cython-generated files...\n')
-  return True
+    for extension in extensions:
+        generated_pyx_sources = []
+        other_sources = []
+        for source in extension.sources:
+            base, file_ext = os.path.splitext(source)
+            if file_ext == '.pyx':
+                generated_pyx_source = next((base + gen_ext
+                                             for gen_ext in (
+                                                 '.c',
+                                                 '.cpp',)
+                                             if os.path.isfile(base + gen_ext)),
+                                            None)
+                if generated_pyx_source:
+                    generated_pyx_sources.append(generated_pyx_source)
+                else:
+                    sys.stderr.write('Cython-generated files are missing...\n')
+                    return False
+            else:
+                other_sources.append(source)
+        extension.sources = generated_pyx_sources + other_sources
+    sys.stderr.write('Found cython-generated files...\n')
+    return True
+
 
 def try_cythonize(extensions, linetracing=False, mandatory=True):
-  """Attempt to cythonize the extensions.
+    """Attempt to cythonize the extensions.
 
   Args:
     extensions: A list of `distutils.extension.Extension`.
@@ -226,78 +231,83 @@ def try_cythonize(extensions, linetracing=False, mandatory=True):
     mandatory: Whether or not having Cython-generated files is mandatory. If it
       is, extensions will be poisoned when they can't be fully generated.
   """
-  try:
-    # Break import style to ensure we have access to Cython post-setup_requires
-    import Cython.Build
-  except ImportError:
-    if mandatory:
-      sys.stderr.write(
-          "This package needs to generate C files with Cython but it cannot. "
-          "Poisoning extension sources to disallow extension commands...")
-      _poison_extensions(
-          extensions,
-          "Extensions have been poisoned due to missing Cython-generated code.")
-    return extensions
-  cython_compiler_directives = {}
-  if linetracing:
-    additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')]
-    cython_compiler_directives['linetrace'] = True
-  return Cython.Build.cythonize(
-    extensions,
-    include_path=[
-      include_dir for extension in extensions for include_dir in extension.include_dirs
-    ] + [CYTHON_STEM],
-    compiler_directives=cython_compiler_directives
-  )
+    try:
+        # Break import style to ensure we have access to Cython post-setup_requires
+        import Cython.Build
+    except ImportError:
+        if mandatory:
+            sys.stderr.write(
+                "This package needs to generate C files with Cython but it cannot. "
+                "Poisoning extension sources to disallow extension commands...")
+            _poison_extensions(
+                extensions,
+                "Extensions have been poisoned due to missing Cython-generated code."
+            )
+        return extensions
+    cython_compiler_directives = {}
+    if linetracing:
+        additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')]
+        cython_compiler_directives['linetrace'] = True
+    return Cython.Build.cythonize(
+        extensions,
+        include_path=[
+            include_dir
+            for extension in extensions
+            for include_dir in extension.include_dirs
+        ] + [CYTHON_STEM],
+        compiler_directives=cython_compiler_directives)
 
 
 class BuildExt(build_ext.build_ext):
-  """Custom build_ext command to enable compiler-specific flags."""
-
-  C_OPTIONS = {
-      'unix': ('-pthread', '-std=gnu99'),
-      'msvc': (),
-  }
-  LINK_OPTIONS = {}
-
-  def build_extensions(self):
-    compiler = self.compiler.compiler_type
-    if compiler in BuildExt.C_OPTIONS:
-      for extension in self.extensions:
-        extension.extra_compile_args += list(BuildExt.C_OPTIONS[compiler])
-    if compiler in BuildExt.LINK_OPTIONS:
-      for extension in self.extensions:
-        extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler])
-    if not check_and_update_cythonization(self.extensions):
-      self.extensions = try_cythonize(self.extensions)
-    try:
-      build_ext.build_ext.build_extensions(self)
-    except Exception as error:
-      formatted_exception = traceback.format_exc()
-      support.diagnose_build_ext_error(self, error, formatted_exception)
-      raise CommandError(
-          "Failed `build_ext` step:\n{}".format(formatted_exception))
+    """Custom build_ext command to enable compiler-specific flags."""
+
+    C_OPTIONS = {
+        'unix': ('-pthread', '-std=gnu99'),
+        'msvc': (),
+    }
+    LINK_OPTIONS = {}
+
+    def build_extensions(self):
+        compiler = self.compiler.compiler_type
+        if compiler in BuildExt.C_OPTIONS:
+            for extension in self.extensions:
+                extension.extra_compile_args += list(BuildExt.C_OPTIONS[
+                    compiler])
+        if compiler in BuildExt.LINK_OPTIONS:
+            for extension in self.extensions:
+                extension.extra_link_args += list(BuildExt.LINK_OPTIONS[
+                    compiler])
+        if not check_and_update_cythonization(self.extensions):
+            self.extensions = try_cythonize(self.extensions)
+        try:
+            build_ext.build_ext.build_extensions(self)
+        except Exception as error:
+            formatted_exception = traceback.format_exc()
+            support.diagnose_build_ext_error(self, error, formatted_exception)
+            raise CommandError("Failed `build_ext` step:\n{}".format(
+                formatted_exception))
 
 
 class Gather(setuptools.Command):
-  """Command to gather project dependencies."""
-
-  description = 'gather dependencies for grpcio'
-  user_options = [
-    ('test', 't', 'flag indicating to gather test dependencies'),
-    ('install', 'i', 'flag indicating to gather install dependencies')
-  ]
-
-  def initialize_options(self):
-    self.test = False
-    self.install = False
-
-  def finalize_options(self):
-    # distutils requires this override.
-    pass
-
-  def run(self):
-    if self.install and self.distribution.install_requires:
-      self.distribution.fetch_build_eggs(self.distribution.install_requires)
-    if self.test and self.distribution.tests_require:
-      self.distribution.fetch_build_eggs(self.distribution.tests_require)
+    """Command to gather project dependencies."""
+
+    description = 'gather dependencies for grpcio'
+    user_options = [
+        ('test', 't', 'flag indicating to gather test dependencies'),
+        ('install', 'i', 'flag indicating to gather install dependencies')
+    ]
+
+    def initialize_options(self):
+        self.test = False
+        self.install = False
+
+    def finalize_options(self):
+        # distutils requires this override.
+        pass
+
+    def run(self):
+        if self.install and self.distribution.install_requires:
+            self.distribution.fetch_build_eggs(
+                self.distribution.install_requires)
+        if self.test and self.distribution.tests_require:
+            self.distribution.fetch_build_eggs(self.distribution.tests_require)
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index e3c10156d0..abe14e7049 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -26,7 +26,6 @@
 # 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.
-
 """gRPC's Python API."""
 
 import abc
@@ -37,28 +36,27 @@ import six
 
 from grpc._cython import cygrpc as _cygrpc
 
-
 ############################## Future Interface  ###############################
 
 
 class FutureTimeoutError(Exception):
-  """Indicates that a method call on a Future timed out."""
+    """Indicates that a method call on a Future timed out."""
 
 
 class FutureCancelledError(Exception):
-  """Indicates that the computation underlying a Future was cancelled."""
+    """Indicates that the computation underlying a Future was cancelled."""
 
 
 class Future(six.with_metaclass(abc.ABCMeta)):
-  """A representation of a computation in another control flow.
+    """A representation of a computation in another control flow.
 
   Computations represented by a Future may be yet to be begun, may be ongoing,
   or may have already completed.
   """
 
-  @abc.abstractmethod
-  def cancel(self):
-    """Attempts to cancel the computation.
+    @abc.abstractmethod
+    def cancel(self):
+        """Attempts to cancel the computation.
 
     This method does not block.
 
@@ -71,11 +69,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         remote system for which a determination of whether or not it commenced
         before being cancelled cannot be made without blocking.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def cancelled(self):
-    """Describes whether the computation was cancelled.
+    @abc.abstractmethod
+    def cancelled(self):
+        """Describes whether the computation was cancelled.
 
     This method does not block.
 
@@ -85,11 +83,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         not limited to this object's cancel method not having been called and
         the computation's result having become immediately available.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def running(self):
-    """Describes whether the computation is taking place.
+    @abc.abstractmethod
+    def running(self):
+        """Describes whether the computation is taking place.
 
     This method does not block.
 
@@ -98,11 +96,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         taking place now, or False if the computation took place in the past or
         was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def done(self):
-    """Describes whether the computation has taken place.
+    @abc.abstractmethod
+    def done(self):
+        """Describes whether the computation has taken place.
 
     This method does not block.
 
@@ -111,11 +109,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         unscheduled or interrupted. False if the computation may possibly be
         executing or scheduled to execute later.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def result(self, timeout=None):
-    """Accesses the outcome of the computation or raises its exception.
+    @abc.abstractmethod
+    def result(self, timeout=None):
+        """Accesses the outcome of the computation or raises its exception.
 
     This method may return immediately or may block.
 
@@ -134,11 +132,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
       Exception: If the computation raised an exception, this call will raise
         the same exception.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def exception(self, timeout=None):
-    """Return the exception raised by the computation.
+    @abc.abstractmethod
+    def exception(self, timeout=None):
+        """Return the exception raised by the computation.
 
     This method may return immediately or may block.
 
@@ -157,11 +155,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         not terminate within the allotted time.
       FutureCancelledError: If the computation was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def traceback(self, timeout=None):
-    """Access the traceback of the exception raised by the computation.
+    @abc.abstractmethod
+    def traceback(self, timeout=None):
+        """Access the traceback of the exception raised by the computation.
 
     This method may return immediately or may block.
 
@@ -180,11 +178,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         not terminate within the allotted time.
       FutureCancelledError: If the computation was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_done_callback(self, fn):
-    """Adds a function to be called at completion of the computation.
+    @abc.abstractmethod
+    def add_done_callback(self, fn):
+        """Adds a function to be called at completion of the computation.
 
     The callback will be passed this Future object describing the outcome of
     the computation.
@@ -195,7 +193,7 @@ class Future(six.with_metaclass(abc.ABCMeta)):
     Args:
       fn: A callable taking this Future object as its single parameter.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 ################################  gRPC Enums  ##################################
@@ -203,7 +201,7 @@ class Future(six.with_metaclass(abc.ABCMeta)):
 
 @enum.unique
 class ChannelConnectivity(enum.Enum):
-  """Mirrors grpc_connectivity_state in the gRPC Core.
+    """Mirrors grpc_connectivity_state in the gRPC Core.
 
   Attributes:
     IDLE: The channel is idle.
@@ -213,81 +211,80 @@ class ChannelConnectivity(enum.Enum):
       recover.
     SHUTDOWN: The channel has seen a failure from which it cannot recover.
   """
-  IDLE              = (_cygrpc.ConnectivityState.idle, 'idle')
-  CONNECTING        = (_cygrpc.ConnectivityState.connecting, 'connecting')
-  READY             = (_cygrpc.ConnectivityState.ready, 'ready')
-  TRANSIENT_FAILURE = (
-      _cygrpc.ConnectivityState.transient_failure, 'transient failure')
-  SHUTDOWN          = (_cygrpc.ConnectivityState.shutdown, 'shutdown')
+    IDLE = (_cygrpc.ConnectivityState.idle, 'idle')
+    CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting')
+    READY = (_cygrpc.ConnectivityState.ready, 'ready')
+    TRANSIENT_FAILURE = (_cygrpc.ConnectivityState.transient_failure,
+                         'transient failure')
+    SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown')
 
 
 @enum.unique
 class StatusCode(enum.Enum):
-  """Mirrors grpc_status_code in the gRPC Core."""
-  OK                  = (_cygrpc.StatusCode.ok, 'ok')
-  CANCELLED           = (_cygrpc.StatusCode.cancelled, 'cancelled')
-  UNKNOWN             = (_cygrpc.StatusCode.unknown, 'unknown')
-  INVALID_ARGUMENT    = (
-      _cygrpc.StatusCode.invalid_argument, 'invalid argument')
-  DEADLINE_EXCEEDED   = (
-      _cygrpc.StatusCode.deadline_exceeded, 'deadline exceeded')
-  NOT_FOUND           = (_cygrpc.StatusCode.not_found, 'not found')
-  ALREADY_EXISTS      = (_cygrpc.StatusCode.already_exists, 'already exists')
-  PERMISSION_DENIED   = (
-      _cygrpc.StatusCode.permission_denied, 'permission denied')
-  RESOURCE_EXHAUSTED  = (
-      _cygrpc.StatusCode.resource_exhausted, 'resource exhausted')
-  FAILED_PRECONDITION = (
-      _cygrpc.StatusCode.failed_precondition, 'failed precondition')
-  ABORTED             = (_cygrpc.StatusCode.aborted, 'aborted')
-  OUT_OF_RANGE        = (_cygrpc.StatusCode.out_of_range, 'out of range')
-  UNIMPLEMENTED       = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
-  INTERNAL            = (_cygrpc.StatusCode.internal, 'internal')
-  UNAVAILABLE         = (_cygrpc.StatusCode.unavailable, 'unavailable')
-  DATA_LOSS           = (_cygrpc.StatusCode.data_loss, 'data loss')
-  UNAUTHENTICATED     = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
+    """Mirrors grpc_status_code in the gRPC Core."""
+    OK = (_cygrpc.StatusCode.ok, 'ok')
+    CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled')
+    UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown')
+    INVALID_ARGUMENT = (_cygrpc.StatusCode.invalid_argument, 'invalid argument')
+    DEADLINE_EXCEEDED = (_cygrpc.StatusCode.deadline_exceeded,
+                         'deadline exceeded')
+    NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found')
+    ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists')
+    PERMISSION_DENIED = (_cygrpc.StatusCode.permission_denied,
+                         'permission denied')
+    RESOURCE_EXHAUSTED = (_cygrpc.StatusCode.resource_exhausted,
+                          'resource exhausted')
+    FAILED_PRECONDITION = (_cygrpc.StatusCode.failed_precondition,
+                           'failed precondition')
+    ABORTED = (_cygrpc.StatusCode.aborted, 'aborted')
+    OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range')
+    UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
+    INTERNAL = (_cygrpc.StatusCode.internal, 'internal')
+    UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable')
+    DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss')
+    UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
 
 
 #############################  gRPC Exceptions  ################################
 
 
 class RpcError(Exception):
-  """Raised by the gRPC library to indicate non-OK-status RPC termination."""
+    """Raised by the gRPC library to indicate non-OK-status RPC termination."""
 
 
 ##############################  Shared Context  ################################
 
 
 class RpcContext(six.with_metaclass(abc.ABCMeta)):
-  """Provides RPC-related information and action."""
+    """Provides RPC-related information and action."""
 
-  @abc.abstractmethod
-  def is_active(self):
-    """Describes whether the RPC is active or has terminated."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def is_active(self):
+        """Describes whether the RPC is active or has terminated."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def time_remaining(self):
-    """Describes the length of allowed time remaining for the RPC.
+    @abc.abstractmethod
+    def time_remaining(self):
+        """Describes the length of allowed time remaining for the RPC.
 
     Returns:
       A nonnegative float indicating the length of allowed time in seconds
       remaining for the RPC to complete before it is considered to have timed
       out, or None if no deadline was specified for the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def cancel(self):
-    """Cancels the RPC.
+    @abc.abstractmethod
+    def cancel(self):
+        """Cancels the RPC.
 
     Idempotent and has no effect if the RPC has already terminated.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_callback(self, callback):
-    """Registers a callback to be called on RPC termination.
+    @abc.abstractmethod
+    def add_callback(self, callback):
+        """Registers a callback to be called on RPC termination.
 
     Args:
       callback: A no-parameter callable to be called on RPC termination.
@@ -297,76 +294,76 @@ class RpcContext(six.with_metaclass(abc.ABCMeta)):
         callback was not added and will not later be called (because the RPC
         already terminated or some other reason).
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 #########################  Invocation-Side Context  ############################
 
 
 class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
-  """Invocation-side utility object for an RPC."""
+    """Invocation-side utility object for an RPC."""
 
-  @abc.abstractmethod
-  def initial_metadata(self):
-    """Accesses the initial metadata from the service-side of the RPC.
+    @abc.abstractmethod
+    def initial_metadata(self):
+        """Accesses the initial metadata from the service-side of the RPC.
 
     This method blocks until the value is available.
 
     Returns:
       The initial :term:`metadata`.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def trailing_metadata(self):
-    """Accesses the trailing metadata from the service-side of the RPC.
+    @abc.abstractmethod
+    def trailing_metadata(self):
+        """Accesses the trailing metadata from the service-side of the RPC.
 
     This method blocks until the value is available.
 
     Returns:
       The trailing :term:`metadata`.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def code(self):
-    """Accesses the status code emitted by the service-side of the RPC.
+    @abc.abstractmethod
+    def code(self):
+        """Accesses the status code emitted by the service-side of the RPC.
 
     This method blocks until the value is available.
 
     Returns:
       The StatusCode value for the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def details(self):
-    """Accesses the details value emitted by the service-side of the RPC.
+    @abc.abstractmethod
+    def details(self):
+        """Accesses the details value emitted by the service-side of the RPC.
 
     This method blocks until the value is available.
 
     Returns:
       The details string of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 ############  Authentication & Authorization Interfaces & Classes  #############
 
 
 class ChannelCredentials(object):
-  """A value encapsulating the data required to create a secure Channel.
+    """A value encapsulating the data required to create a secure Channel.
 
   This class has no supported interface - it exists to define the type of its
   instances and its instances exist to be passed to other functions.
   """
 
-  def __init__(self, credentials):
-    self._credentials = credentials
+    def __init__(self, credentials):
+        self._credentials = credentials
 
 
 class CallCredentials(object):
-  """A value encapsulating data asserting an identity over a channel.
+    """A value encapsulating data asserting an identity over a channel.
 
   A CallCredentials may be composed with ChannelCredentials to always assert
   identity for every call over that Channel.
@@ -375,12 +372,12 @@ class CallCredentials(object):
   instances and its instances exist to be passed to other functions.
   """
 
-  def __init__(self, credentials):
-    self._credentials = credentials
+    def __init__(self, credentials):
+        self._credentials = credentials
 
 
 class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
-  """Provides information to call credentials metadata plugins.
+    """Provides information to call credentials metadata plugins.
 
   Attributes:
     service_url: A string URL of the service being called into.
@@ -389,23 +386,23 @@ class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
 
 
 class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)):
-  """Callback object received by a metadata plugin."""
+    """Callback object received by a metadata plugin."""
 
-  def __call__(self, metadata, error):
-    """Inform the gRPC runtime of the metadata to construct a CallCredentials.
+    def __call__(self, metadata, error):
+        """Inform the gRPC runtime of the metadata to construct a CallCredentials.
 
     Args:
       metadata: The :term:`metadata` used to construct the CallCredentials.
       error: An Exception to indicate error or None to indicate success.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
-  """A specification for custom authentication."""
+    """A specification for custom authentication."""
 
-  def __call__(self, context, callback):
-    """Implements authentication by passing metadata to a callback.
+    def __call__(self, context, callback):
+        """Implements authentication by passing metadata to a callback.
 
     Implementations of this method must not block.
 
@@ -415,29 +412,29 @@ class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
       callback: An AuthMetadataPluginCallback to be invoked either synchronously
         or asynchronously.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class ServerCredentials(object):
-  """A value encapsulating the data required to open a secure port on a Server.
+    """A value encapsulating the data required to open a secure port on a Server.
 
   This class has no supported interface - it exists to define the type of its
   instances and its instances exist to be passed to other functions.
   """
 
-  def __init__(self, credentials):
-    self._credentials = credentials
+    def __init__(self, credentials):
+        self._credentials = credentials
 
 
 ########################  Multi-Callable Interfaces  ###########################
 
 
 class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a unary-unary RPC."""
+    """Affords invoking a unary-unary RPC."""
 
-  @abc.abstractmethod
-  def __call__(self, request, timeout=None, metadata=None, credentials=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self, request, timeout=None, metadata=None, credentials=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -454,11 +451,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         raised RpcError will also be a Call for the RPC affording the RPC's
         metadata, status code, and details.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def with_call(self, request, timeout=None, metadata=None, credentials=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def with_call(self, request, timeout=None, metadata=None, credentials=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -475,11 +472,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         raised RpcError will also be a Call for the RPC affording the RPC's
         metadata, status code, and details.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def future(self, request, timeout=None, metadata=None, credentials=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def future(self, request, timeout=None, metadata=None, credentials=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -494,15 +491,15 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         message of the RPC. Should the event terminate with non-OK status, the
         returned Future's exception value will be an RpcError.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a unary-stream RPC."""
+    """Affords invoking a unary-stream RPC."""
 
-  @abc.abstractmethod
-  def __call__(self, request, timeout=None, metadata=None, credentials=None):
-    """Invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self, request, timeout=None, metadata=None, credentials=None):
+        """Invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -516,16 +513,19 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         RpcError indicating termination of the RPC with non-OK status.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a stream-unary RPC in any call style."""
+    """Affords invoking a stream-unary RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self,
+                 request_iterator,
+                 timeout=None,
+                 metadata=None,
+                 credentials=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -543,12 +543,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         raised RpcError will also be a Call for the RPC affording the RPC's
         metadata, status code, and details.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def with_call(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def with_call(self,
+                  request_iterator,
+                  timeout=None,
+                  metadata=None,
+                  credentials=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -565,12 +568,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         raised RpcError will also be a Call for the RPC affording the RPC's
         metadata, status code, and details.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def future(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def future(self,
+               request_iterator,
+               timeout=None,
+               metadata=None,
+               credentials=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -585,16 +591,19 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         message of the RPC. Should the event terminate with non-OK status, the
         returned Future's exception value will be an RpcError.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a stream-stream RPC in any call style."""
+    """Affords invoking a stream-stream RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    """Invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self,
+                 request_iterator,
+                 timeout=None,
+                 metadata=None,
+                 credentials=None):
+        """Invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -608,18 +617,18 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         RpcError indicating termination of the RPC with non-OK status.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 #############################  Channel Interface  ##############################
 
 
 class Channel(six.with_metaclass(abc.ABCMeta)):
-  """Affords RPC invocation via generic methods."""
+    """Affords RPC invocation via generic methods."""
 
-  @abc.abstractmethod
-  def subscribe(self, callback, try_to_connect=False):
-    """Subscribes to this Channel's connectivity.
+    @abc.abstractmethod
+    def subscribe(self, callback, try_to_connect=False):
+        """Subscribes to this Channel's connectivity.
 
     Args:
       callback: A callable to be invoked and passed a ChannelConnectivity value
@@ -631,22 +640,24 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
         attempt to connect if it is not already connected and ready to conduct
         RPCs.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unsubscribe(self, callback):
-    """Unsubscribes a callback from this Channel's connectivity.
+    @abc.abstractmethod
+    def unsubscribe(self, callback):
+        """Unsubscribes a callback from this Channel's connectivity.
 
     Args:
       callback: A callable previously registered with this Channel from having
         been passed to its "subscribe" method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unary_unary(
-      self, method, request_serializer=None, response_deserializer=None):
-    """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+    @abc.abstractmethod
+    def unary_unary(self,
+                    method,
+                    request_serializer=None,
+                    response_deserializer=None):
+        """Creates a UnaryUnaryMultiCallable for a unary-unary method.
 
     Args:
       method: The name of the RPC method.
@@ -658,12 +669,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A UnaryUnaryMultiCallable value for the named unary-unary method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unary_stream(
-      self, method, request_serializer=None, response_deserializer=None):
-    """Creates a UnaryStreamMultiCallable for a unary-stream method.
+    @abc.abstractmethod
+    def unary_stream(self,
+                     method,
+                     request_serializer=None,
+                     response_deserializer=None):
+        """Creates a UnaryStreamMultiCallable for a unary-stream method.
 
     Args:
       method: The name of the RPC method.
@@ -675,12 +688,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A UnaryStreamMultiCallable value for the name unary-stream method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_unary(
-      self, method, request_serializer=None, response_deserializer=None):
-    """Creates a StreamUnaryMultiCallable for a stream-unary method.
+    @abc.abstractmethod
+    def stream_unary(self,
+                     method,
+                     request_serializer=None,
+                     response_deserializer=None):
+        """Creates a StreamUnaryMultiCallable for a stream-unary method.
 
     Args:
       method: The name of the RPC method.
@@ -692,12 +707,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A StreamUnaryMultiCallable value for the named stream-unary method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_stream(
-      self, method, request_serializer=None, response_deserializer=None):
-    """Creates a StreamStreamMultiCallable for a stream-stream method.
+    @abc.abstractmethod
+    def stream_stream(self,
+                      method,
+                      request_serializer=None,
+                      response_deserializer=None):
+        """Creates a StreamStreamMultiCallable for a stream-stream method.
 
     Args:
       method: The name of the RPC method.
@@ -709,36 +726,36 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A StreamStreamMultiCallable value for the named stream-stream method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 ##########################  Service-Side Context  ##############################
 
 
 class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
-  """A context object passed to method implementations."""
+    """A context object passed to method implementations."""
 
-  @abc.abstractmethod
-  def invocation_metadata(self):
-    """Accesses the metadata from the invocation-side of the RPC.
+    @abc.abstractmethod
+    def invocation_metadata(self):
+        """Accesses the metadata from the invocation-side of the RPC.
 
     Returns:
       The invocation :term:`metadata`.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def peer(self):
-    """Identifies the peer that invoked the RPC being serviced.
+    @abc.abstractmethod
+    def peer(self):
+        """Identifies the peer that invoked the RPC being serviced.
 
     Returns:
       A string identifying the peer that invoked the RPC being serviced.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def send_initial_metadata(self, initial_metadata):
-    """Sends the initial metadata value to the invocation-side of the RPC.
+    @abc.abstractmethod
+    def send_initial_metadata(self, initial_metadata):
+        """Sends the initial metadata value to the invocation-side of the RPC.
 
     This method need not be called by method implementations if they have no
     service-side initial metadata to transmit.
@@ -746,11 +763,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
     Args:
       initial_metadata: The initial :term:`metadata`.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def set_trailing_metadata(self, trailing_metadata):
-    """Accepts the trailing metadata value of the RPC.
+    @abc.abstractmethod
+    def set_trailing_metadata(self, trailing_metadata):
+        """Accepts the trailing metadata value of the RPC.
 
     This method need not be called by method implementations if they have no
     service-side trailing metadata to transmit.
@@ -758,11 +775,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
     Args:
       trailing_metadata: The trailing :term:`metadata`.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def set_code(self, code):
-    """Accepts the status code of the RPC.
+    @abc.abstractmethod
+    def set_code(self, code):
+        """Accepts the status code of the RPC.
 
     This method need not be called by method implementations if they wish the
     gRPC runtime to determine the status code of the RPC.
@@ -771,11 +788,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       code: A StatusCode value to be transmitted to the invocation side of the
         RPC as the status code of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def set_details(self, details):
-    """Accepts the service-side details of the RPC.
+    @abc.abstractmethod
+    def set_details(self, details):
+        """Accepts the service-side details of the RPC.
 
     This method need not be called by method implementations if they have no
     details to transmit.
@@ -784,14 +801,14 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       details: A string to be transmitted to the invocation side of the RPC as
         the status details of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 #####################  Service-Side Handler Interfaces  ########################
 
 
 class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
-  """An implementation of a single RPC method.
+    """An implementation of a single RPC method.
 
   Attributes:
     request_streaming: Whether the RPC supports exactly one request message or
@@ -826,7 +843,7 @@ class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
 
 
 class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
-  """Describes an RPC that has just arrived for service.
+    """Describes an RPC that has just arrived for service.
   Attributes:
     method: The method name of the RPC.
     invocation_metadata: The :term:`metadata` from the invocation side of the RPC.
@@ -834,11 +851,11 @@ class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
 
 
 class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
-  """An implementation of arbitrarily many RPC methods."""
+    """An implementation of arbitrarily many RPC methods."""
 
-  @abc.abstractmethod
-  def service(self, handler_call_details):
-    """Services an RPC (or not).
+    @abc.abstractmethod
+    def service(self, handler_call_details):
+        """Services an RPC (or not).
 
     Args:
       handler_call_details: A HandlerCallDetails describing the RPC.
@@ -847,11 +864,11 @@ class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
       An RpcMethodHandler with which the RPC may be serviced, or None to
         indicate that this object will not be servicing the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)):
-  """An implementation of RPC methods belonging to a service.
+    """An implementation of RPC methods belonging to a service.
 
   A service handles RPC methods with structured names of the form
   '/Service.Name/Service.MethodX', where 'Service.Name' is the value
@@ -860,25 +877,25 @@ class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)):
   service name.
   """
 
-  @abc.abstractmethod
-  def service_name(self):
-    """Returns this services name.
+    @abc.abstractmethod
+    def service_name(self):
+        """Returns this services name.
 
     Returns:
       The service name.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 #############################  Server Interface  ###############################
 
 
 class Server(six.with_metaclass(abc.ABCMeta)):
-  """Services RPCs."""
+    """Services RPCs."""
 
-  @abc.abstractmethod
-  def add_generic_rpc_handlers(self, generic_rpc_handlers):
-    """Registers GenericRpcHandlers with this Server.
+    @abc.abstractmethod
+    def add_generic_rpc_handlers(self, generic_rpc_handlers):
+        """Registers GenericRpcHandlers with this Server.
 
     This method is only safe to call before the server is started.
 
@@ -886,11 +903,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
       generic_rpc_handlers: An iterable of GenericRpcHandlers that will be used
         to service RPCs after this Server is started.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_insecure_port(self, address):
-    """Reserves a port for insecure RPC service once this Server becomes active.
+    @abc.abstractmethod
+    def add_insecure_port(self, address):
+        """Reserves a port for insecure RPC service once this Server becomes active.
 
     This method may only be called before calling this Server's start method is
     called.
@@ -904,11 +921,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
         in the passed address, but will likely be different if the port number
         contained in the passed address was zero.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_secure_port(self, address, server_credentials):
-    """Reserves a port for secure RPC service after this Server becomes active.
+    @abc.abstractmethod
+    def add_secure_port(self, address, server_credentials):
+        """Reserves a port for secure RPC service after this Server becomes active.
 
     This method may only be called before calling this Server's start method is
     called.
@@ -923,20 +940,20 @@ class Server(six.with_metaclass(abc.ABCMeta)):
         in the passed address, but will likely be different if the port number
         contained in the passed address was zero.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def start(self):
-    """Starts this Server's service of RPCs.
+    @abc.abstractmethod
+    def start(self):
+        """Starts this Server's service of RPCs.
 
     This method may only be called while the server is not serving RPCs (i.e. it
     is not idempotent).
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stop(self, grace):
-    """Stops this Server's service of RPCs.
+    @abc.abstractmethod
+    def stop(self, grace):
+        """Stops this Server's service of RPCs.
 
     All calls to this method immediately stop service of new RPCs. When existing
     RPCs are aborted is controlled by the grace period parameter passed to this
@@ -967,15 +984,16 @@ class Server(six.with_metaclass(abc.ABCMeta)):
       at the time it was stopped or if all RPCs that it had underway completed
       very early in the grace period).
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 #################################  Functions    ################################
 
 
-def unary_unary_rpc_method_handler(
-    behavior, request_deserializer=None, response_serializer=None):
-  """Creates an RpcMethodHandler for a unary-unary RPC method.
+def unary_unary_rpc_method_handler(behavior,
+                                   request_deserializer=None,
+                                   response_serializer=None):
+    """Creates an RpcMethodHandler for a unary-unary RPC method.
 
   Args:
     behavior: The implementation of an RPC method as a callable behavior taking
@@ -987,15 +1005,16 @@ def unary_unary_rpc_method_handler(
     An RpcMethodHandler for a unary-unary RPC method constructed from the given
       parameters.
   """
-  from grpc import _utilities
-  return _utilities.RpcMethodHandler(
-      False, False, request_deserializer, response_serializer, behavior, None,
-      None, None)
+    from grpc import _utilities
+    return _utilities.RpcMethodHandler(False, False, request_deserializer,
+                                       response_serializer, behavior, None,
+                                       None, None)
 
 
-def unary_stream_rpc_method_handler(
-    behavior, request_deserializer=None, response_serializer=None):
-  """Creates an RpcMethodHandler for a unary-stream RPC method.
+def unary_stream_rpc_method_handler(behavior,
+                                    request_deserializer=None,
+                                    response_serializer=None):
+    """Creates an RpcMethodHandler for a unary-stream RPC method.
 
   Args:
     behavior: The implementation of an RPC method as a callable behavior taking
@@ -1007,15 +1026,16 @@ def unary_stream_rpc_method_handler(
     An RpcMethodHandler for a unary-stream RPC method constructed from the
       given parameters.
   """
-  from grpc import _utilities
-  return _utilities.RpcMethodHandler(
-      False, True, request_deserializer, response_serializer, None, behavior,
-      None, None)
+    from grpc import _utilities
+    return _utilities.RpcMethodHandler(False, True, request_deserializer,
+                                       response_serializer, None, behavior,
+                                       None, None)
 
 
-def stream_unary_rpc_method_handler(
-    behavior, request_deserializer=None, response_serializer=None):
-  """Creates an RpcMethodHandler for a stream-unary RPC method.
+def stream_unary_rpc_method_handler(behavior,
+                                    request_deserializer=None,
+                                    response_serializer=None):
+    """Creates an RpcMethodHandler for a stream-unary RPC method.
 
   Args:
     behavior: The implementation of an RPC method as a callable behavior taking
@@ -1027,15 +1047,16 @@ def stream_unary_rpc_method_handler(
     An RpcMethodHandler for a stream-unary RPC method constructed from the
       given parameters.
   """
-  from grpc import _utilities
-  return _utilities.RpcMethodHandler(
-      True, False, request_deserializer, response_serializer, None, None,
-      behavior, None)
+    from grpc import _utilities
+    return _utilities.RpcMethodHandler(True, False, request_deserializer,
+                                       response_serializer, None, None,
+                                       behavior, None)
 
 
-def stream_stream_rpc_method_handler(
-        behavior, request_deserializer=None, response_serializer=None):
-  """Creates an RpcMethodHandler for a stream-stream RPC method.
+def stream_stream_rpc_method_handler(behavior,
+                                     request_deserializer=None,
+                                     response_serializer=None):
+    """Creates an RpcMethodHandler for a stream-stream RPC method.
 
   Args:
     behavior: The implementation of an RPC method as a callable behavior taking
@@ -1048,14 +1069,14 @@ def stream_stream_rpc_method_handler(
     An RpcMethodHandler for a stream-stream RPC method constructed from the
       given parameters.
   """
-  from grpc import _utilities
-  return _utilities.RpcMethodHandler(
-      True, True, request_deserializer, response_serializer, None, None, None,
-      behavior)
+    from grpc import _utilities
+    return _utilities.RpcMethodHandler(True, True, request_deserializer,
+                                       response_serializer, None, None, None,
+                                       behavior)
 
 
 def method_handlers_generic_handler(service, method_handlers):
-  """Creates a grpc.GenericRpcHandler from RpcMethodHandlers.
+    """Creates a grpc.GenericRpcHandler from RpcMethodHandlers.
 
   Args:
     service: A service name to be used for the given method handlers.
@@ -1065,13 +1086,14 @@ def method_handlers_generic_handler(service, method_handlers):
   Returns:
     A GenericRpcHandler constructed from the given parameters.
   """
-  from grpc import _utilities
-  return _utilities.DictionaryGenericHandler(service, method_handlers)
+    from grpc import _utilities
+    return _utilities.DictionaryGenericHandler(service, method_handlers)
 
 
-def ssl_channel_credentials(
-    root_certificates=None, private_key=None, certificate_chain=None):
-  """Creates a ChannelCredentials for use with an SSL-enabled Channel.
+def ssl_channel_credentials(root_certificates=None,
+                            private_key=None,
+                            certificate_chain=None):
+    """Creates a ChannelCredentials for use with an SSL-enabled Channel.
 
   Args:
     root_certificates: The PEM-encoded root certificates or unset to ask for
@@ -1084,16 +1106,16 @@ def ssl_channel_credentials(
   Returns:
     A ChannelCredentials for use with an SSL-enabled Channel.
   """
-  if private_key is not None or certificate_chain is not None:
-    pair = _cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
-  else:
-    pair = None
-  return ChannelCredentials(
-      _cygrpc.channel_credentials_ssl(root_certificates, pair))
+    if private_key is not None or certificate_chain is not None:
+        pair = _cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
+    else:
+        pair = None
+    return ChannelCredentials(
+        _cygrpc.channel_credentials_ssl(root_certificates, pair))
 
 
 def metadata_call_credentials(metadata_plugin, name=None):
-  """Construct CallCredentials from an AuthMetadataPlugin.
+    """Construct CallCredentials from an AuthMetadataPlugin.
 
   Args:
     metadata_plugin: An AuthMetadataPlugin to use as the authentication behavior
@@ -1103,21 +1125,21 @@ def metadata_call_credentials(metadata_plugin, name=None):
   Returns:
     A CallCredentials.
   """
-  from grpc import _plugin_wrapping
-  if name is None:
-    try:
-      effective_name = metadata_plugin.__name__
-    except AttributeError:
-      effective_name = metadata_plugin.__class__.__name__
-  else:
-    effective_name = name
-  return CallCredentials(
-      _plugin_wrapping.call_credentials_metadata_plugin(
-          metadata_plugin, effective_name))
+    from grpc import _plugin_wrapping
+    if name is None:
+        try:
+            effective_name = metadata_plugin.__name__
+        except AttributeError:
+            effective_name = metadata_plugin.__class__.__name__
+    else:
+        effective_name = name
+    return CallCredentials(
+        _plugin_wrapping.call_credentials_metadata_plugin(metadata_plugin,
+                                                          effective_name))
 
 
 def access_token_call_credentials(access_token):
-  """Construct CallCredentials from an access token.
+    """Construct CallCredentials from an access token.
 
   Args:
     access_token: A string to place directly in the http request
@@ -1126,13 +1148,13 @@ def access_token_call_credentials(access_token):
   Returns:
     A CallCredentials.
   """
-  from grpc import _auth
-  return metadata_call_credentials(
-      _auth.AccessTokenCallCredentials(access_token))
+    from grpc import _auth
+    return metadata_call_credentials(
+        _auth.AccessTokenCallCredentials(access_token))
 
 
 def composite_call_credentials(*call_credentials):
-  """Compose multiple CallCredentials to make a new CallCredentials.
+    """Compose multiple CallCredentials to make a new CallCredentials.
 
   Args:
     *call_credentials: At least two CallCredentials objects.
@@ -1140,16 +1162,16 @@ def composite_call_credentials(*call_credentials):
   Returns:
     A CallCredentials object composed of the given CallCredentials objects.
   """
-  from grpc import _credential_composition
-  cygrpc_call_credentials = tuple(
-      single_call_credentials._credentials
-      for single_call_credentials in call_credentials)
-  return CallCredentials(
-      _credential_composition.call(cygrpc_call_credentials))
+    from grpc import _credential_composition
+    cygrpc_call_credentials = tuple(
+        single_call_credentials._credentials
+        for single_call_credentials in call_credentials)
+    return CallCredentials(
+        _credential_composition.call(cygrpc_call_credentials))
 
 
 def composite_channel_credentials(channel_credentials, *call_credentials):
-  """Compose a ChannelCredentials and one or more CallCredentials objects.
+    """Compose a ChannelCredentials and one or more CallCredentials objects.
 
   Args:
     channel_credentials: A ChannelCredentials.
@@ -1159,19 +1181,19 @@ def composite_channel_credentials(channel_credentials, *call_credentials):
     A ChannelCredentials composed of the given ChannelCredentials and
       CallCredentials objects.
   """
-  from grpc import _credential_composition
-  cygrpc_call_credentials = tuple(
-      single_call_credentials._credentials
-      for single_call_credentials in call_credentials)
-  return ChannelCredentials(
-      _credential_composition.channel(
-          channel_credentials._credentials, cygrpc_call_credentials))
+    from grpc import _credential_composition
+    cygrpc_call_credentials = tuple(
+        single_call_credentials._credentials
+        for single_call_credentials in call_credentials)
+    return ChannelCredentials(
+        _credential_composition.channel(channel_credentials._credentials,
+                                        cygrpc_call_credentials))
 
 
-def ssl_server_credentials(
-    private_key_certificate_chain_pairs, root_certificates=None,
-    require_client_auth=False):
-  """Creates a ServerCredentials for use with an SSL-enabled Server.
+def ssl_server_credentials(private_key_certificate_chain_pairs,
+                           root_certificates=None,
+                           require_client_auth=False):
+    """Creates a ServerCredentials for use with an SSL-enabled Server.
 
   Args:
     private_key_certificate_chain_pairs: A nonempty sequence each element of
@@ -1187,23 +1209,23 @@ def ssl_server_credentials(
   Returns:
     A ServerCredentials for use with an SSL-enabled Server.
   """
-  if len(private_key_certificate_chain_pairs) == 0:
-    raise ValueError(
-        'At least one private key-certificate chain pair is required!')
-  elif require_client_auth and root_certificates is None:
-    raise ValueError(
-        'Illegal to require client auth without providing root certificates!')
-  else:
-    return ServerCredentials(
-        _cygrpc.server_credentials_ssl(
-        root_certificates,
-        [_cygrpc.SslPemKeyCertPair(key, pem)
-         for key, pem in private_key_certificate_chain_pairs],
-        require_client_auth))
+    if len(private_key_certificate_chain_pairs) == 0:
+        raise ValueError(
+            'At least one private key-certificate chain pair is required!')
+    elif require_client_auth and root_certificates is None:
+        raise ValueError(
+            'Illegal to require client auth without providing root certificates!'
+        )
+    else:
+        return ServerCredentials(
+            _cygrpc.server_credentials_ssl(root_certificates, [
+                _cygrpc.SslPemKeyCertPair(key, pem)
+                for key, pem in private_key_certificate_chain_pairs
+            ], require_client_auth))
 
 
 def channel_ready_future(channel):
-  """Creates a Future tracking when a Channel is ready.
+    """Creates a Future tracking when a Channel is ready.
 
   Cancelling the returned Future does not tell the given Channel to abandon
   attempts it may have been making to connect; cancelling merely deactivates the
@@ -1216,12 +1238,12 @@ def channel_ready_future(channel):
     A Future that matures when the given Channel has connectivity
       ChannelConnectivity.READY.
   """
-  from grpc import _utilities
-  return _utilities.channel_ready_future(channel)
+    from grpc import _utilities
+    return _utilities.channel_ready_future(channel)
 
 
 def insecure_channel(target, options=None):
-  """Creates an insecure Channel to a server.
+    """Creates an insecure Channel to a server.
 
   Args:
     target: The target to which to connect.
@@ -1231,12 +1253,12 @@ def insecure_channel(target, options=None):
   Returns:
     A Channel to the target through which RPCs may be conducted.
   """
-  from grpc import _channel
-  return _channel.Channel(target, () if options is None else options, None)
+    from grpc import _channel
+    return _channel.Channel(target, () if options is None else options, None)
 
 
 def secure_channel(target, credentials, options=None):
-  """Creates a secure Channel to a server.
+    """Creates a secure Channel to a server.
 
   Args:
     target: The target to which to connect.
@@ -1247,13 +1269,13 @@ def secure_channel(target, credentials, options=None):
   Returns:
     A Channel to the target through which RPCs may be conducted.
   """
-  from grpc import _channel
-  return _channel.Channel(target, () if options is None else options,
-                          credentials._credentials)
+    from grpc import _channel
+    return _channel.Channel(target, () if options is None else options,
+                            credentials._credentials)
 
 
 def server(thread_pool, handlers=None, options=None):
-  """Creates a Server with which RPCs can be serviced.
+    """Creates a Server with which RPCs can be serviced.
 
   Args:
     thread_pool: A futures.ThreadPoolExecutor to be used by the returned Server
@@ -1269,14 +1291,13 @@ def server(thread_pool, handlers=None, options=None):
   Returns:
     A Server with which RPCs can be serviced.
   """
-  from grpc import _server
-  return _server.Server(thread_pool, () if handlers is None else handlers,
-                        () if options is None else options)
+    from grpc import _server
+    return _server.Server(thread_pool, () if handlers is None else handlers, ()
+                          if options is None else options)
 
 
 ###################################  __all__  #################################
 
-
 __all__ = (
     'FutureTimeoutError',
     'FutureCancelledError',
@@ -1317,26 +1338,23 @@ __all__ = (
     'channel_ready_future',
     'insecure_channel',
     'secure_channel',
-    'server',
-)
-
+    'server',)
 
 ############################### Extension Shims ################################
 
-
 # Here to maintain backwards compatibility; avoid using these in new code!
 try:
-  import grpc_tools
-  sys.modules.update({'grpc.tools': grpc_tools})
+    import grpc_tools
+    sys.modules.update({'grpc.tools': grpc_tools})
 except ImportError:
-  pass
+    pass
 try:
-  import grpc_health
-  sys.modules.update({'grpc.health': grpc_health})
+    import grpc_health
+    sys.modules.update({'grpc.health': grpc_health})
 except ImportError:
-  pass
+    pass
 try:
-  import grpc_reflection
-  sys.modules.update({'grpc.reflection': grpc_reflection})
+    import grpc_reflection
+    sys.modules.update({'grpc.reflection': grpc_reflection})
 except ImportError:
-  pass
+    pass
diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py
index dea3221c9d..e8a90cf504 100644
--- a/src/python/grpcio/grpc/_auth.py
+++ b/src/python/grpcio/grpc/_auth.py
@@ -26,7 +26,6 @@
 # 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.
-
 """GRPCAuthMetadataPlugins for standard authentication."""
 
 import inspect
@@ -36,51 +35,53 @@ import grpc
 
 
 def _sign_request(callback, token, error):
-  metadata = (('authorization', 'Bearer {}'.format(token)),)
-  callback(metadata, error)
+    metadata = (('authorization', 'Bearer {}'.format(token)),)
+    callback(metadata, error)
 
 
 class GoogleCallCredentials(grpc.AuthMetadataPlugin):
-  """Metadata wrapper for GoogleCredentials from the oauth2client library."""
-
-  def __init__(self, credentials):
-    self._credentials = credentials
-    self._pool = futures.ThreadPoolExecutor(max_workers=1)
-
-    # Hack to determine if these are JWT creds and we need to pass
-    # additional_claims when getting a token
-    if 'additional_claims' in inspect.getargspec(
-        credentials.get_access_token).args:
-      self._is_jwt = True
-    else:
-      self._is_jwt = False
-
-  def __call__(self, context, callback):
-    # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
-    if self._is_jwt:
-      future = self._pool.submit(self._credentials.get_access_token,
-                                 additional_claims={'aud': context.service_url})
-    else:
-      future = self._pool.submit(self._credentials.get_access_token)
-    future.add_done_callback(lambda x: self._get_token_callback(callback, x))
-
-  def _get_token_callback(self, callback, future):
-    try:
-      access_token = future.result().access_token
-    except Exception as e:
-      _sign_request(callback, None, e)
-    else:
-      _sign_request(callback, access_token, None)
-
-  def __del__(self):
-    self._pool.shutdown(wait=False)
+    """Metadata wrapper for GoogleCredentials from the oauth2client library."""
+
+    def __init__(self, credentials):
+        self._credentials = credentials
+        self._pool = futures.ThreadPoolExecutor(max_workers=1)
+
+        # Hack to determine if these are JWT creds and we need to pass
+        # additional_claims when getting a token
+        if 'additional_claims' in inspect.getargspec(
+                credentials.get_access_token).args:
+            self._is_jwt = True
+        else:
+            self._is_jwt = False
+
+    def __call__(self, context, callback):
+        # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
+        if self._is_jwt:
+            future = self._pool.submit(
+                self._credentials.get_access_token,
+                additional_claims={'aud': context.service_url})
+        else:
+            future = self._pool.submit(self._credentials.get_access_token)
+        future.add_done_callback(
+            lambda x: self._get_token_callback(callback, x))
+
+    def _get_token_callback(self, callback, future):
+        try:
+            access_token = future.result().access_token
+        except Exception as e:
+            _sign_request(callback, None, e)
+        else:
+            _sign_request(callback, access_token, None)
+
+    def __del__(self):
+        self._pool.shutdown(wait=False)
 
 
 class AccessTokenCallCredentials(grpc.AuthMetadataPlugin):
-  """Metadata wrapper for raw access token credentials."""
+    """Metadata wrapper for raw access token credentials."""
 
-  def __init__(self, access_token):
-    self._access_token = access_token
+    def __init__(self, access_token):
+        self._access_token = access_token
 
-  def __call__(self, context, callback):
-    _sign_request(callback, self._access_token, None)
+    def __call__(self, context, callback):
+        _sign_request(callback, self._access_token, None)
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index e8c6a99cb1..77412236cc 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Invocation-side implementation of gRPC Python."""
 
 import sys
@@ -52,692 +51,710 @@ _UNARY_UNARY_INITIAL_DUE = (
     cygrpc.OperationType.send_close_from_client,
     cygrpc.OperationType.receive_initial_metadata,
     cygrpc.OperationType.receive_message,
-    cygrpc.OperationType.receive_status_on_client,
-)
+    cygrpc.OperationType.receive_status_on_client,)
 _UNARY_STREAM_INITIAL_DUE = (
     cygrpc.OperationType.send_initial_metadata,
     cygrpc.OperationType.send_message,
     cygrpc.OperationType.send_close_from_client,
     cygrpc.OperationType.receive_initial_metadata,
-    cygrpc.OperationType.receive_status_on_client,
-)
+    cygrpc.OperationType.receive_status_on_client,)
 _STREAM_UNARY_INITIAL_DUE = (
     cygrpc.OperationType.send_initial_metadata,
     cygrpc.OperationType.receive_initial_metadata,
     cygrpc.OperationType.receive_message,
-    cygrpc.OperationType.receive_status_on_client,
-)
+    cygrpc.OperationType.receive_status_on_client,)
 _STREAM_STREAM_INITIAL_DUE = (
     cygrpc.OperationType.send_initial_metadata,
     cygrpc.OperationType.receive_initial_metadata,
-    cygrpc.OperationType.receive_status_on_client,
-)
+    cygrpc.OperationType.receive_status_on_client,)
 
 _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
     'Exception calling channel subscription callback!')
 
 
 def _deadline(timeout):
-  if timeout is None:
-    return None, _INFINITE_FUTURE
-  else:
-    deadline = time.time() + timeout
-    return deadline, cygrpc.Timespec(deadline)
+    if timeout is None:
+        return None, _INFINITE_FUTURE
+    else:
+        deadline = time.time() + timeout
+        return deadline, cygrpc.Timespec(deadline)
 
 
 def _unknown_code_details(unknown_cygrpc_code, details):
-  return 'Server sent unknown code {} and details "{}"'.format(
-      unknown_cygrpc_code, details)
+    return 'Server sent unknown code {} and details "{}"'.format(
+        unknown_cygrpc_code, details)
 
 
 def _wait_once_until(condition, until):
-  if until is None:
-    condition.wait()
-  else:
-    remaining = until - time.time()
-    if remaining < 0:
-      raise grpc.FutureTimeoutError()
+    if until is None:
+        condition.wait()
     else:
-      condition.wait(timeout=remaining)
+        remaining = until - time.time()
+        if remaining < 0:
+            raise grpc.FutureTimeoutError()
+        else:
+            condition.wait(timeout=remaining)
+
 
 _INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
     'Internal gRPC call error %d. ' +
     'Please report to https://github.com/grpc/grpc/issues')
 
+
 def _check_call_error(call_error, metadata):
-  if call_error == cygrpc.CallError.invalid_metadata:
-    raise ValueError('metadata was invalid: %s' % metadata)
-  elif call_error != cygrpc.CallError.ok:
-    raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+    if call_error == cygrpc.CallError.invalid_metadata:
+        raise ValueError('metadata was invalid: %s' % metadata)
+    elif call_error != cygrpc.CallError.ok:
+        raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+
 
 def _call_error_set_RPCstate(state, call_error, metadata):
-  if call_error == cygrpc.CallError.invalid_metadata:
-    _abort(state, grpc.StatusCode.INTERNAL, 'metadata was invalid: %s' % metadata)
-  else:
-    _abort(state, grpc.StatusCode.INTERNAL, 
-        _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+    if call_error == cygrpc.CallError.invalid_metadata:
+        _abort(state, grpc.StatusCode.INTERNAL,
+               'metadata was invalid: %s' % metadata)
+    else:
+        _abort(state, grpc.StatusCode.INTERNAL,
+               _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+
 
 class _RPCState(object):
 
-  def __init__(self, due, initial_metadata, trailing_metadata, code, details):
-    self.condition = threading.Condition()
-    # The cygrpc.OperationType objects representing events due from the RPC's
-    # completion queue.
-    self.due = set(due)
-    self.initial_metadata = initial_metadata
-    self.response = None
-    self.trailing_metadata = trailing_metadata
-    self.code = code
-    self.details = details
-    # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
-    # slightly wonky, so they have to be tracked separately from the rest of the
-    # result of the RPC. This field tracks whether cancellation was requested
-    # prior to termination of the RPC.
-    self.cancelled = False
-    self.callbacks = []
+    def __init__(self, due, initial_metadata, trailing_metadata, code, details):
+        self.condition = threading.Condition()
+        # The cygrpc.OperationType objects representing events due from the RPC's
+        # completion queue.
+        self.due = set(due)
+        self.initial_metadata = initial_metadata
+        self.response = None
+        self.trailing_metadata = trailing_metadata
+        self.code = code
+        self.details = details
+        # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
+        # slightly wonky, so they have to be tracked separately from the rest of the
+        # result of the RPC. This field tracks whether cancellation was requested
+        # prior to termination of the RPC.
+        self.cancelled = False
+        self.callbacks = []
 
 
 def _abort(state, code, details):
-  if state.code is None:
-    state.code = code
-    state.details = details
-    if state.initial_metadata is None:
-      state.initial_metadata = _EMPTY_METADATA
-    state.trailing_metadata = _EMPTY_METADATA
+    if state.code is None:
+        state.code = code
+        state.details = details
+        if state.initial_metadata is None:
+            state.initial_metadata = _EMPTY_METADATA
+        state.trailing_metadata = _EMPTY_METADATA
 
 
 def _handle_event(event, state, response_deserializer):
-  callbacks = []
-  for batch_operation in event.batch_operations:
-    operation_type = batch_operation.type
-    state.due.remove(operation_type)
-    if operation_type == cygrpc.OperationType.receive_initial_metadata:
-      state.initial_metadata = batch_operation.received_metadata
-    elif operation_type == cygrpc.OperationType.receive_message:
-      serialized_response = batch_operation.received_message.bytes()
-      if serialized_response is not None:
-        response = _common.deserialize(
-            serialized_response, response_deserializer)
-        if response is None:
-          details = 'Exception deserializing response!'
-          _abort(state, grpc.StatusCode.INTERNAL, details)
-        else:
-          state.response = response
-    elif operation_type == cygrpc.OperationType.receive_status_on_client:
-      state.trailing_metadata = batch_operation.received_metadata
-      if state.code is None:
-        code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
-            batch_operation.received_status_code)
-        if code is None:
-          state.code = grpc.StatusCode.UNKNOWN
-          state.details = _unknown_code_details(
-              batch_operation.received_status_code,
-              batch_operation.received_status_details)
-        else:
-          state.code = code
-          state.details = batch_operation.received_status_details
-      callbacks.extend(state.callbacks)
-      state.callbacks = None
-  return callbacks
+    callbacks = []
+    for batch_operation in event.batch_operations:
+        operation_type = batch_operation.type
+        state.due.remove(operation_type)
+        if operation_type == cygrpc.OperationType.receive_initial_metadata:
+            state.initial_metadata = batch_operation.received_metadata
+        elif operation_type == cygrpc.OperationType.receive_message:
+            serialized_response = batch_operation.received_message.bytes()
+            if serialized_response is not None:
+                response = _common.deserialize(serialized_response,
+                                               response_deserializer)
+                if response is None:
+                    details = 'Exception deserializing response!'
+                    _abort(state, grpc.StatusCode.INTERNAL, details)
+                else:
+                    state.response = response
+        elif operation_type == cygrpc.OperationType.receive_status_on_client:
+            state.trailing_metadata = batch_operation.received_metadata
+            if state.code is None:
+                code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
+                    batch_operation.received_status_code)
+                if code is None:
+                    state.code = grpc.StatusCode.UNKNOWN
+                    state.details = _unknown_code_details(
+                        batch_operation.received_status_code,
+                        batch_operation.received_status_details)
+                else:
+                    state.code = code
+                    state.details = batch_operation.received_status_details
+            callbacks.extend(state.callbacks)
+            state.callbacks = None
+    return callbacks
 
 
 def _event_handler(state, call, response_deserializer):
-  def handle_event(event):
-    with state.condition:
-      callbacks = _handle_event(event, state, response_deserializer)
-      state.condition.notify_all()
-      done = not state.due
-    for callback in callbacks:
-      callback()
-    return call if done else None
-  return handle_event
-
-
-def _consume_request_iterator(
-    request_iterator, state, call, request_serializer):
-  event_handler = _event_handler(state, call, None)
-
-  def consume_request_iterator():
-    while True:
-      try:
-        request = next(request_iterator)
-      except StopIteration:
-        break
-      except Exception as e:
-        logging.exception("Exception iterating requests!")
-        call.cancel()
-        _abort(state, grpc.StatusCode.UNKNOWN, "Exception iterating requests!")
-        return
-      serialized_request = _common.serialize(request, request_serializer)
-      with state.condition:
-        if state.code is None and not state.cancelled:
-          if serialized_request is None:
-            call.cancel()
-            details = 'Exception serializing request!'
-            _abort(state, grpc.StatusCode.INTERNAL, details)
-            return
-          else:
-            operations = (
-                cygrpc.operation_send_message(
-                    serialized_request, _EMPTY_FLAGS),
-            )
-            call.start_client_batch(cygrpc.Operations(operations),
-                                    event_handler)
-            state.due.add(cygrpc.OperationType.send_message)
-            while True:
-              state.condition.wait()
-              if state.code is None:
-                if cygrpc.OperationType.send_message not in state.due:
-                  break
-              else:
+
+    def handle_event(event):
+        with state.condition:
+            callbacks = _handle_event(event, state, response_deserializer)
+            state.condition.notify_all()
+            done = not state.due
+        for callback in callbacks:
+            callback()
+        return call if done else None
+
+    return handle_event
+
+
+def _consume_request_iterator(request_iterator, state, call,
+                              request_serializer):
+    event_handler = _event_handler(state, call, None)
+
+    def consume_request_iterator():
+        while True:
+            try:
+                request = next(request_iterator)
+            except StopIteration:
+                break
+            except Exception as e:
+                logging.exception("Exception iterating requests!")
+                call.cancel()
+                _abort(state, grpc.StatusCode.UNKNOWN,
+                       "Exception iterating requests!")
                 return
-        else:
-          return
-    with state.condition:
-      if state.code is None:
-        operations = (
-            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-        )
-        call.start_client_batch(cygrpc.Operations(operations), event_handler)
-        state.due.add(cygrpc.OperationType.send_close_from_client)
-
-  def stop_consumption_thread(timeout):
-    with state.condition:
-      if state.code is None:
-        call.cancel()
-        state.cancelled = True
-        _abort(state, grpc.StatusCode.CANCELLED, 'Cancelled!')
-        state.condition.notify_all()
-
-  consumption_thread = _common.CleanupThread(
-      stop_consumption_thread, target=consume_request_iterator)
-  consumption_thread.start()
+            serialized_request = _common.serialize(request, request_serializer)
+            with state.condition:
+                if state.code is None and not state.cancelled:
+                    if serialized_request is None:
+                        call.cancel()
+                        details = 'Exception serializing request!'
+                        _abort(state, grpc.StatusCode.INTERNAL, details)
+                        return
+                    else:
+                        operations = (cygrpc.operation_send_message(
+                            serialized_request, _EMPTY_FLAGS),)
+                        call.start_client_batch(
+                            cygrpc.Operations(operations), event_handler)
+                        state.due.add(cygrpc.OperationType.send_message)
+                        while True:
+                            state.condition.wait()
+                            if state.code is None:
+                                if cygrpc.OperationType.send_message not in state.due:
+                                    break
+                            else:
+                                return
+                else:
+                    return
+        with state.condition:
+            if state.code is None:
+                operations = (
+                    cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),)
+                call.start_client_batch(
+                    cygrpc.Operations(operations), event_handler)
+                state.due.add(cygrpc.OperationType.send_close_from_client)
+
+    def stop_consumption_thread(timeout):
+        with state.condition:
+            if state.code is None:
+                call.cancel()
+                state.cancelled = True
+                _abort(state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+                state.condition.notify_all()
+
+    consumption_thread = _common.CleanupThread(
+        stop_consumption_thread, target=consume_request_iterator)
+    consumption_thread.start()
 
 
 class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
 
-  def __init__(self, state, call, response_deserializer, deadline):
-    super(_Rendezvous, self).__init__()
-    self._state = state
-    self._call = call
-    self._response_deserializer = response_deserializer
-    self._deadline = deadline
-
-  def cancel(self):
-    with self._state.condition:
-      if self._state.code is None:
-        self._call.cancel()
-        self._state.cancelled = True
-        _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
-        self._state.condition.notify_all()
-      return False
-
-  def cancelled(self):
-    with self._state.condition:
-      return self._state.cancelled
-
-  def running(self):
-    with self._state.condition:
-      return self._state.code is None
-
-  def done(self):
-    with self._state.condition:
-      return self._state.code is not None
-
-  def result(self, timeout=None):
-    until = None if timeout is None else time.time() + timeout
-    with self._state.condition:
-      while True:
-        if self._state.code is None:
-          _wait_once_until(self._state.condition, until)
-        elif self._state.code is grpc.StatusCode.OK:
-          return self._state.response
-        elif self._state.cancelled:
-          raise grpc.FutureCancelledError()
-        else:
-          raise self
-
-  def exception(self, timeout=None):
-    until = None if timeout is None else time.time() + timeout
-    with self._state.condition:
-      while True:
-        if self._state.code is None:
-          _wait_once_until(self._state.condition, until)
-        elif self._state.code is grpc.StatusCode.OK:
-          return None
-        elif self._state.cancelled:
-          raise grpc.FutureCancelledError()
-        else:
-          return self
-
-  def traceback(self, timeout=None):
-    until = None if timeout is None else time.time() + timeout
-    with self._state.condition:
-      while True:
-        if self._state.code is None:
-          _wait_once_until(self._state.condition, until)
-        elif self._state.code is grpc.StatusCode.OK:
-          return None
-        elif self._state.cancelled:
-          raise grpc.FutureCancelledError()
+    def __init__(self, state, call, response_deserializer, deadline):
+        super(_Rendezvous, self).__init__()
+        self._state = state
+        self._call = call
+        self._response_deserializer = response_deserializer
+        self._deadline = deadline
+
+    def cancel(self):
+        with self._state.condition:
+            if self._state.code is None:
+                self._call.cancel()
+                self._state.cancelled = True
+                _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+                self._state.condition.notify_all()
+            return False
+
+    def cancelled(self):
+        with self._state.condition:
+            return self._state.cancelled
+
+    def running(self):
+        with self._state.condition:
+            return self._state.code is None
+
+    def done(self):
+        with self._state.condition:
+            return self._state.code is not None
+
+    def result(self, timeout=None):
+        until = None if timeout is None else time.time() + timeout
+        with self._state.condition:
+            while True:
+                if self._state.code is None:
+                    _wait_once_until(self._state.condition, until)
+                elif self._state.code is grpc.StatusCode.OK:
+                    return self._state.response
+                elif self._state.cancelled:
+                    raise grpc.FutureCancelledError()
+                else:
+                    raise self
+
+    def exception(self, timeout=None):
+        until = None if timeout is None else time.time() + timeout
+        with self._state.condition:
+            while True:
+                if self._state.code is None:
+                    _wait_once_until(self._state.condition, until)
+                elif self._state.code is grpc.StatusCode.OK:
+                    return None
+                elif self._state.cancelled:
+                    raise grpc.FutureCancelledError()
+                else:
+                    return self
+
+    def traceback(self, timeout=None):
+        until = None if timeout is None else time.time() + timeout
+        with self._state.condition:
+            while True:
+                if self._state.code is None:
+                    _wait_once_until(self._state.condition, until)
+                elif self._state.code is grpc.StatusCode.OK:
+                    return None
+                elif self._state.cancelled:
+                    raise grpc.FutureCancelledError()
+                else:
+                    try:
+                        raise self
+                    except grpc.RpcError:
+                        return sys.exc_info()[2]
+
+    def add_done_callback(self, fn):
+        with self._state.condition:
+            if self._state.code is None:
+                self._state.callbacks.append(lambda: fn(self))
+                return
+
+        fn(self)
+
+    def _next(self):
+        with self._state.condition:
+            if self._state.code is None:
+                event_handler = _event_handler(self._state, self._call,
+                                               self._response_deserializer)
+                self._call.start_client_batch(
+                    cygrpc.Operations(
+                        (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+                    event_handler)
+                self._state.due.add(cygrpc.OperationType.receive_message)
+            elif self._state.code is grpc.StatusCode.OK:
+                raise StopIteration()
+            else:
+                raise self
+            while True:
+                self._state.condition.wait()
+                if self._state.response is not None:
+                    response = self._state.response
+                    self._state.response = None
+                    return response
+                elif cygrpc.OperationType.receive_message not in self._state.due:
+                    if self._state.code is grpc.StatusCode.OK:
+                        raise StopIteration()
+                    elif self._state.code is not None:
+                        raise self
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        return self._next()
+
+    def next(self):
+        return self._next()
+
+    def is_active(self):
+        with self._state.condition:
+            return self._state.code is None
+
+    def time_remaining(self):
+        if self._deadline is None:
+            return None
         else:
-          try:
-            raise self
-          except grpc.RpcError:
-            return sys.exc_info()[2]
-
-  def add_done_callback(self, fn):
-    with self._state.condition:
-      if self._state.code is None:
-        self._state.callbacks.append(lambda: fn(self))
-        return
-
-    fn(self)
-
-  def _next(self):
-    with self._state.condition:
-      if self._state.code is None:
-        event_handler = _event_handler(
-            self._state, self._call, self._response_deserializer)
-        self._call.start_client_batch(
-            cygrpc.Operations(
-                (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
-            event_handler)
-        self._state.due.add(cygrpc.OperationType.receive_message)
-      elif self._state.code is grpc.StatusCode.OK:
-        raise StopIteration()
-      else:
-        raise self
-      while True:
-        self._state.condition.wait()
-        if self._state.response is not None:
-          response = self._state.response
-          self._state.response = None
-          return response
-        elif cygrpc.OperationType.receive_message not in self._state.due:
-          if self._state.code is grpc.StatusCode.OK:
-            raise StopIteration()
-          elif self._state.code is not None:
-            raise self
-
-  def __iter__(self):
-    return self
-
-  def __next__(self):
-    return self._next()
-
-  def next(self):
-    return self._next()
-
-  def is_active(self):
-    with self._state.condition:
-      return self._state.code is None
-
-  def time_remaining(self):
-    if self._deadline is None:
-      return None
-    else:
-      return max(self._deadline - time.time(), 0)
-
-  def add_callback(self, callback):
-    with self._state.condition:
-      if self._state.callbacks is None:
-        return False
-      else:
-        self._state.callbacks.append(callback)
-        return True
-
-  def initial_metadata(self):
-    with self._state.condition:
-      while self._state.initial_metadata is None:
-        self._state.condition.wait()
-      return _common.application_metadata(self._state.initial_metadata)
-
-  def trailing_metadata(self):
-    with self._state.condition:
-      while self._state.trailing_metadata is None:
-        self._state.condition.wait()
-      return _common.application_metadata(self._state.trailing_metadata)
-
-  def code(self):
-    with self._state.condition:
-      while self._state.code is None:
-        self._state.condition.wait()
-      return self._state.code
-
-  def details(self):
-    with self._state.condition:
-      while self._state.details is None:
-        self._state.condition.wait()
-      return _common.decode(self._state.details)
-
-  def _repr(self):
-    with self._state.condition:
-      if self._state.code is None:
-        return '<_Rendezvous object of in-flight RPC>'
-      else:
-        return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
-            self._state.code, _common.decode(self._state.details))
-
-  def __repr__(self):
-    return self._repr()
-
-  def __str__(self):
-    return self._repr()
-
-  def __del__(self):
-    with self._state.condition:
-      if self._state.code is None:
-        self._call.cancel()
-        self._state.cancelled = True
-        self._state.code = grpc.StatusCode.CANCELLED
-        self._state.condition.notify_all()
+            return max(self._deadline - time.time(), 0)
+
+    def add_callback(self, callback):
+        with self._state.condition:
+            if self._state.callbacks is None:
+                return False
+            else:
+                self._state.callbacks.append(callback)
+                return True
+
+    def initial_metadata(self):
+        with self._state.condition:
+            while self._state.initial_metadata is None:
+                self._state.condition.wait()
+            return _common.application_metadata(self._state.initial_metadata)
+
+    def trailing_metadata(self):
+        with self._state.condition:
+            while self._state.trailing_metadata is None:
+                self._state.condition.wait()
+            return _common.application_metadata(self._state.trailing_metadata)
+
+    def code(self):
+        with self._state.condition:
+            while self._state.code is None:
+                self._state.condition.wait()
+            return self._state.code
+
+    def details(self):
+        with self._state.condition:
+            while self._state.details is None:
+                self._state.condition.wait()
+            return _common.decode(self._state.details)
+
+    def _repr(self):
+        with self._state.condition:
+            if self._state.code is None:
+                return '<_Rendezvous object of in-flight RPC>'
+            else:
+                return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
+                    self._state.code, _common.decode(self._state.details))
+
+    def __repr__(self):
+        return self._repr()
+
+    def __str__(self):
+        return self._repr()
+
+    def __del__(self):
+        with self._state.condition:
+            if self._state.code is None:
+                self._call.cancel()
+                self._state.cancelled = True
+                self._state.code = grpc.StatusCode.CANCELLED
+                self._state.condition.notify_all()
 
 
 def _start_unary_request(request, timeout, request_serializer):
-  deadline, deadline_timespec = _deadline(timeout)
-  serialized_request = _common.serialize(request, request_serializer)
-  if serialized_request is None:
-    state = _RPCState(
-        (), _EMPTY_METADATA, _EMPTY_METADATA, grpc.StatusCode.INTERNAL,
-        'Exception serializing request!')
-    rendezvous = _Rendezvous(state, None, None, deadline)
-    return deadline, deadline_timespec, None, rendezvous
-  else:
-    return deadline, deadline_timespec, serialized_request, None
+    deadline, deadline_timespec = _deadline(timeout)
+    serialized_request = _common.serialize(request, request_serializer)
+    if serialized_request is None:
+        state = _RPCState((), _EMPTY_METADATA, _EMPTY_METADATA,
+                          grpc.StatusCode.INTERNAL,
+                          'Exception serializing request!')
+        rendezvous = _Rendezvous(state, None, None, deadline)
+        return deadline, deadline_timespec, None, rendezvous
+    else:
+        return deadline, deadline_timespec, serialized_request, None
 
 
 def _end_unary_response_blocking(state, with_call, deadline):
-  if state.code is grpc.StatusCode.OK:
-    if with_call:
-      rendezvous = _Rendezvous(state, None, None, deadline)
-      return state.response, rendezvous
+    if state.code is grpc.StatusCode.OK:
+        if with_call:
+            rendezvous = _Rendezvous(state, None, None, deadline)
+            return state.response, rendezvous
+        else:
+            return state.response
     else:
-      return state.response
-  else:
-    raise _Rendezvous(state, None, None, deadline)
+        raise _Rendezvous(state, None, None, deadline)
 
 
 class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
 
-  def __init__(
-      self, channel, managed_call, method, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._managed_call = managed_call
-    self._method = method
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def _prepare(self, request, timeout, metadata):
-    deadline, deadline_timespec, serialized_request, rendezvous = (
-        _start_unary_request(request, timeout, self._request_serializer))
-    if serialized_request is None:
-      return None, None, None, None, rendezvous
-    else:
-      state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
-      operations = (
-          cygrpc.operation_send_initial_metadata(
-              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
-          cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
-          cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-          cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
-          cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-      )
-      return state, operations, deadline, deadline_timespec, None
-
-  def _blocking(self, request, timeout, metadata, credentials):
-    state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
-        request, timeout, metadata)
-    if rendezvous:
-      raise rendezvous
-    else:
-      completion_queue = cygrpc.CompletionQueue()
-      call = self._channel.create_call(
-          None, 0, completion_queue, self._method, None, deadline_timespec)
-      if credentials is not None:
-        call.set_credentials(credentials._credentials)
-      call_error = call.start_client_batch(cygrpc.Operations(operations), None)
-      _check_call_error(call_error, metadata)
-      _handle_event(completion_queue.poll(), state, self._response_deserializer)
-      return state, deadline
-
-  def __call__(self, request, timeout=None, metadata=None, credentials=None):
-    state, deadline, = self._blocking(request, timeout, metadata, credentials)
-    return _end_unary_response_blocking(state, False, deadline)
-
-  def with_call(self, request, timeout=None, metadata=None, credentials=None):
-    state, deadline, = self._blocking(request, timeout, metadata, credentials)
-    return _end_unary_response_blocking(state, True, deadline)
-
-  def future(self, request, timeout=None, metadata=None, credentials=None):
-    state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
-        request, timeout, metadata)
-    if rendezvous:
-      return rendezvous
-    else:
-      call, drive_call = self._managed_call(
-          None, 0, self._method, None, deadline_timespec)
-      if credentials is not None:
-        call.set_credentials(credentials._credentials)
-      event_handler = _event_handler(state, call, self._response_deserializer)
-      with state.condition:
-        call_error = call.start_client_batch(cygrpc.Operations(operations),
-            event_handler)
-        if call_error != cygrpc.CallError.ok:
-          _call_error_set_RPCstate(state, call_error, metadata)
-          return _Rendezvous(state, None, None, deadline)
-        drive_call()
-      return _Rendezvous(state, call, self._response_deserializer, deadline)
+    def __init__(self, channel, managed_call, method, request_serializer,
+                 response_deserializer):
+        self._channel = channel
+        self._managed_call = managed_call
+        self._method = method
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def _prepare(self, request, timeout, metadata):
+        deadline, deadline_timespec, serialized_request, rendezvous = (
+            _start_unary_request(request, timeout, self._request_serializer))
+        if serialized_request is None:
+            return None, None, None, None, rendezvous
+        else:
+            state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
+            operations = (
+                cygrpc.operation_send_initial_metadata(
+                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
+                cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+                cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+                cygrpc.operation_receive_message(_EMPTY_FLAGS),
+                cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+            return state, operations, deadline, deadline_timespec, None
+
+    def _blocking(self, request, timeout, metadata, credentials):
+        state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+            request, timeout, metadata)
+        if rendezvous:
+            raise rendezvous
+        else:
+            completion_queue = cygrpc.CompletionQueue()
+            call = self._channel.create_call(None, 0, completion_queue,
+                                             self._method, None,
+                                             deadline_timespec)
+            if credentials is not None:
+                call.set_credentials(credentials._credentials)
+            call_error = call.start_client_batch(
+                cygrpc.Operations(operations), None)
+            _check_call_error(call_error, metadata)
+            _handle_event(completion_queue.poll(), state,
+                          self._response_deserializer)
+            return state, deadline
+
+    def __call__(self, request, timeout=None, metadata=None, credentials=None):
+        state, deadline, = self._blocking(request, timeout, metadata,
+                                          credentials)
+        return _end_unary_response_blocking(state, False, deadline)
+
+    def with_call(self, request, timeout=None, metadata=None, credentials=None):
+        state, deadline, = self._blocking(request, timeout, metadata,
+                                          credentials)
+        return _end_unary_response_blocking(state, True, deadline)
+
+    def future(self, request, timeout=None, metadata=None, credentials=None):
+        state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+            request, timeout, metadata)
+        if rendezvous:
+            return rendezvous
+        else:
+            call, drive_call = self._managed_call(None, 0, self._method, None,
+                                                  deadline_timespec)
+            if credentials is not None:
+                call.set_credentials(credentials._credentials)
+            event_handler = _event_handler(state, call,
+                                           self._response_deserializer)
+            with state.condition:
+                call_error = call.start_client_batch(
+                    cygrpc.Operations(operations), event_handler)
+                if call_error != cygrpc.CallError.ok:
+                    _call_error_set_RPCstate(state, call_error, metadata)
+                    return _Rendezvous(state, None, None, deadline)
+                drive_call()
+            return _Rendezvous(state, call, self._response_deserializer,
+                               deadline)
 
 
 class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
 
-  def __init__(
-      self, channel, managed_call, method, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._managed_call = managed_call
-    self._method = method
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(self, request, timeout=None, metadata=None, credentials=None):
-    deadline, deadline_timespec, serialized_request, rendezvous = (
-        _start_unary_request(request, timeout, self._request_serializer))
-    if serialized_request is None:
-      raise rendezvous
-    else:
-      state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
-      call, drive_call = self._managed_call(
-          None, 0, self._method, None, deadline_timespec)
-      if credentials is not None:
-        call.set_credentials(credentials._credentials)
-      event_handler = _event_handler(state, call, self._response_deserializer)
-      with state.condition:
-        call.start_client_batch(
-            cygrpc.Operations(
-                (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
-            event_handler)
-        operations = (
-            cygrpc.operation_send_initial_metadata(
-                _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
-            cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
-            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-            cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-        )
-        call_error = call.start_client_batch(cygrpc.Operations(operations),
-            event_handler)
-        if call_error != cygrpc.CallError.ok:
-          _call_error_set_RPCstate(state, call_error, metadata)
-          return _Rendezvous(state, None, None, deadline)
-        drive_call()
-      return _Rendezvous(state, call, self._response_deserializer, deadline)
+    def __init__(self, channel, managed_call, method, request_serializer,
+                 response_deserializer):
+        self._channel = channel
+        self._managed_call = managed_call
+        self._method = method
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self, request, timeout=None, metadata=None, credentials=None):
+        deadline, deadline_timespec, serialized_request, rendezvous = (
+            _start_unary_request(request, timeout, self._request_serializer))
+        if serialized_request is None:
+            raise rendezvous
+        else:
+            state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
+            call, drive_call = self._managed_call(None, 0, self._method, None,
+                                                  deadline_timespec)
+            if credentials is not None:
+                call.set_credentials(credentials._credentials)
+            event_handler = _event_handler(state, call,
+                                           self._response_deserializer)
+            with state.condition:
+                call.start_client_batch(
+                    cygrpc.Operations((
+                        cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+                    )), event_handler)
+                operations = (
+                    cygrpc.operation_send_initial_metadata(
+                        _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                    cygrpc.operation_send_message(serialized_request,
+                                                  _EMPTY_FLAGS),
+                    cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+                    cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+                call_error = call.start_client_batch(
+                    cygrpc.Operations(operations), event_handler)
+                if call_error != cygrpc.CallError.ok:
+                    _call_error_set_RPCstate(state, call_error, metadata)
+                    return _Rendezvous(state, None, None, deadline)
+                drive_call()
+            return _Rendezvous(state, call, self._response_deserializer,
+                               deadline)
 
 
 class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
 
-  def __init__(
-      self, channel, managed_call, method, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._managed_call = managed_call
-    self._method = method
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def _blocking(self, request_iterator, timeout, metadata, credentials):
-    deadline, deadline_timespec = _deadline(timeout)
-    state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
-    completion_queue = cygrpc.CompletionQueue()
-    call = self._channel.create_call(
-        None, 0, completion_queue, self._method, None, deadline_timespec)
-    if credentials is not None:
-      call.set_credentials(credentials._credentials)
-    with state.condition:
-      call.start_client_batch(
-          cygrpc.Operations(
-              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
-          None)
-      operations = (
-          cygrpc.operation_send_initial_metadata(
-              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
-          cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-      )
-      call_error = call.start_client_batch(cygrpc.Operations(operations), None)
-      _check_call_error(call_error, metadata)
-      _consume_request_iterator(
-          request_iterator, state, call, self._request_serializer)
-    while True:
-      event = completion_queue.poll()
-      with state.condition:
-        _handle_event(event, state, self._response_deserializer)
-        state.condition.notify_all()
-        if not state.due:
-          break
-    return state, deadline
-
-  def __call__(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    state, deadline, = self._blocking(
-        request_iterator, timeout, metadata, credentials)
-    return _end_unary_response_blocking(state, False, deadline)
-
-  def with_call(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    state, deadline, = self._blocking(
-        request_iterator, timeout, metadata, credentials)
-    return _end_unary_response_blocking(state, True, deadline)
-
-  def future(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    deadline, deadline_timespec = _deadline(timeout)
-    state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
-    call, drive_call = self._managed_call(
-        None, 0, self._method, None, deadline_timespec)
-    if credentials is not None:
-      call.set_credentials(credentials._credentials)
-    event_handler = _event_handler(state, call, self._response_deserializer)
-    with state.condition:
-      call.start_client_batch(
-          cygrpc.Operations(
-              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
-          event_handler)
-      operations = (
-          cygrpc.operation_send_initial_metadata(
-              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
-          cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-      )
-      call_error = call.start_client_batch(cygrpc.Operations(operations),
-          event_handler)
-      if call_error != cygrpc.CallError.ok:
-        _call_error_set_RPCstate(state, call_error, metadata)
-        return _Rendezvous(state, None, None, deadline)
-      drive_call()
-      _consume_request_iterator(
-          request_iterator, state, call, self._request_serializer)
-    return _Rendezvous(state, call, self._response_deserializer, deadline)
+    def __init__(self, channel, managed_call, method, request_serializer,
+                 response_deserializer):
+        self._channel = channel
+        self._managed_call = managed_call
+        self._method = method
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def _blocking(self, request_iterator, timeout, metadata, credentials):
+        deadline, deadline_timespec = _deadline(timeout)
+        state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+        completion_queue = cygrpc.CompletionQueue()
+        call = self._channel.create_call(None, 0, completion_queue,
+                                         self._method, None, deadline_timespec)
+        if credentials is not None:
+            call.set_credentials(credentials._credentials)
+        with state.condition:
+            call.start_client_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+                None)
+            operations = (
+                cygrpc.operation_send_initial_metadata(
+                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                cygrpc.operation_receive_message(_EMPTY_FLAGS),
+                cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+            call_error = call.start_client_batch(
+                cygrpc.Operations(operations), None)
+            _check_call_error(call_error, metadata)
+            _consume_request_iterator(request_iterator, state, call,
+                                      self._request_serializer)
+        while True:
+            event = completion_queue.poll()
+            with state.condition:
+                _handle_event(event, state, self._response_deserializer)
+                state.condition.notify_all()
+                if not state.due:
+                    break
+        return state, deadline
+
+    def __call__(self,
+                 request_iterator,
+                 timeout=None,
+                 metadata=None,
+                 credentials=None):
+        state, deadline, = self._blocking(request_iterator, timeout, metadata,
+                                          credentials)
+        return _end_unary_response_blocking(state, False, deadline)
+
+    def with_call(self,
+                  request_iterator,
+                  timeout=None,
+                  metadata=None,
+                  credentials=None):
+        state, deadline, = self._blocking(request_iterator, timeout, metadata,
+                                          credentials)
+        return _end_unary_response_blocking(state, True, deadline)
+
+    def future(self,
+               request_iterator,
+               timeout=None,
+               metadata=None,
+               credentials=None):
+        deadline, deadline_timespec = _deadline(timeout)
+        state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+        call, drive_call = self._managed_call(None, 0, self._method, None,
+                                              deadline_timespec)
+        if credentials is not None:
+            call.set_credentials(credentials._credentials)
+        event_handler = _event_handler(state, call, self._response_deserializer)
+        with state.condition:
+            call.start_client_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+                event_handler)
+            operations = (
+                cygrpc.operation_send_initial_metadata(
+                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                cygrpc.operation_receive_message(_EMPTY_FLAGS),
+                cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+            call_error = call.start_client_batch(
+                cygrpc.Operations(operations), event_handler)
+            if call_error != cygrpc.CallError.ok:
+                _call_error_set_RPCstate(state, call_error, metadata)
+                return _Rendezvous(state, None, None, deadline)
+            drive_call()
+            _consume_request_iterator(request_iterator, state, call,
+                                      self._request_serializer)
+        return _Rendezvous(state, call, self._response_deserializer, deadline)
 
 
 class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
 
-  def __init__(
-      self, channel, managed_call, method, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._managed_call = managed_call
-    self._method = method
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(
-      self, request_iterator, timeout=None, metadata=None, credentials=None):
-    deadline, deadline_timespec = _deadline(timeout)
-    state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
-    call, drive_call = self._managed_call(
-        None, 0, self._method, None, deadline_timespec)
-    if credentials is not None:
-      call.set_credentials(credentials._credentials)
-    event_handler = _event_handler(state, call, self._response_deserializer)
-    with state.condition:
-      call.start_client_batch(
-          cygrpc.Operations(
-              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
-          event_handler)
-      operations = (
-          cygrpc.operation_send_initial_metadata(
-              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
-          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-      )
-      call_error = call.start_client_batch(cygrpc.Operations(operations),
-          event_handler)
-      if call_error != cygrpc.CallError.ok:
-        _call_error_set_RPCstate(state, call_error, metadata)
-        return _Rendezvous(state, None, None, deadline)
-      drive_call()
-      _consume_request_iterator(
-          request_iterator, state, call, self._request_serializer)
-    return _Rendezvous(state, call, self._response_deserializer, deadline)
+    def __init__(self, channel, managed_call, method, request_serializer,
+                 response_deserializer):
+        self._channel = channel
+        self._managed_call = managed_call
+        self._method = method
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self,
+                 request_iterator,
+                 timeout=None,
+                 metadata=None,
+                 credentials=None):
+        deadline, deadline_timespec = _deadline(timeout)
+        state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
+        call, drive_call = self._managed_call(None, 0, self._method, None,
+                                              deadline_timespec)
+        if credentials is not None:
+            call.set_credentials(credentials._credentials)
+        event_handler = _event_handler(state, call, self._response_deserializer)
+        with state.condition:
+            call.start_client_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+                event_handler)
+            operations = (
+                cygrpc.operation_send_initial_metadata(
+                    _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+                cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+            call_error = call.start_client_batch(
+                cygrpc.Operations(operations), event_handler)
+            if call_error != cygrpc.CallError.ok:
+                _call_error_set_RPCstate(state, call_error, metadata)
+                return _Rendezvous(state, None, None, deadline)
+            drive_call()
+            _consume_request_iterator(request_iterator, state, call,
+                                      self._request_serializer)
+        return _Rendezvous(state, call, self._response_deserializer, deadline)
 
 
 class _ChannelCallState(object):
 
-  def __init__(self, channel):
-    self.lock = threading.Lock()
-    self.channel = channel
-    self.completion_queue = cygrpc.CompletionQueue()
-    self.managed_calls = None
+    def __init__(self, channel):
+        self.lock = threading.Lock()
+        self.channel = channel
+        self.completion_queue = cygrpc.CompletionQueue()
+        self.managed_calls = None
 
 
 def _run_channel_spin_thread(state):
-  def channel_spin():
-    while True:
-      event = state.completion_queue.poll()
-      completed_call = event.tag(event)
-      if completed_call is not None:
-        with state.lock:
-          state.managed_calls.remove(completed_call)
-          if not state.managed_calls:
-            state.managed_calls = None
-            return
 
-  def stop_channel_spin(timeout):
-    with state.lock:
-      if state.managed_calls is not None:
-        for call in state.managed_calls:
-          call.cancel()
+    def channel_spin():
+        while True:
+            event = state.completion_queue.poll()
+            completed_call = event.tag(event)
+            if completed_call is not None:
+                with state.lock:
+                    state.managed_calls.remove(completed_call)
+                    if not state.managed_calls:
+                        state.managed_calls = None
+                        return
+
+    def stop_channel_spin(timeout):
+        with state.lock:
+            if state.managed_calls is not None:
+                for call in state.managed_calls:
+                    call.cancel()
 
-  channel_spin_thread = _common.CleanupThread(
-      stop_channel_spin, target=channel_spin)
-  channel_spin_thread.start()
+    channel_spin_thread = _common.CleanupThread(
+        stop_channel_spin, target=channel_spin)
+    channel_spin_thread.start()
 
 
 def _channel_managed_call_management(state):
-  def create(parent, flags, method, host, deadline):
-    """Creates a managed cygrpc.Call and a function to call to drive it.
+
+    def create(parent, flags, method, host, deadline):
+        """Creates a managed cygrpc.Call and a function to call to drive it.
 
     If operations are successfully added to the returned cygrpc.Call, the
     returned function must be called. If operations are not successfully added
@@ -754,193 +771,213 @@ def _channel_managed_call_management(state):
       A cygrpc.Call with which to conduct an RPC and a function to call if
         operations are successfully started on the call.
     """
-    call = state.channel.create_call(
-        parent, flags, state.completion_queue, method, host, deadline)
-
-    def drive():
-      with state.lock:
-        if state.managed_calls is None:
-          state.managed_calls = set((call,))
-          _run_channel_spin_thread(state)
-        else:
-          state.managed_calls.add(call)
+        call = state.channel.create_call(parent, flags, state.completion_queue,
+                                         method, host, deadline)
+
+        def drive():
+            with state.lock:
+                if state.managed_calls is None:
+                    state.managed_calls = set((call,))
+                    _run_channel_spin_thread(state)
+                else:
+                    state.managed_calls.add(call)
+
+        return call, drive
 
-    return call, drive
-  return create
+    return create
 
 
 class _ChannelConnectivityState(object):
 
-  def __init__(self, channel):
-    self.lock = threading.Lock()
-    self.channel = channel
-    self.polling = False
-    self.connectivity = None
-    self.try_to_connect = False
-    self.callbacks_and_connectivities = []
-    self.delivering = False
+    def __init__(self, channel):
+        self.lock = threading.Lock()
+        self.channel = channel
+        self.polling = False
+        self.connectivity = None
+        self.try_to_connect = False
+        self.callbacks_and_connectivities = []
+        self.delivering = False
 
 
 def _deliveries(state):
-  callbacks_needing_update = []
-  for callback_and_connectivity in state.callbacks_and_connectivities:
-    callback, callback_connectivity, = callback_and_connectivity
-    if callback_connectivity is not state.connectivity:
-      callbacks_needing_update.append(callback)
-      callback_and_connectivity[1] = state.connectivity
-  return callbacks_needing_update
+    callbacks_needing_update = []
+    for callback_and_connectivity in state.callbacks_and_connectivities:
+        callback, callback_connectivity, = callback_and_connectivity
+        if callback_connectivity is not state.connectivity:
+            callbacks_needing_update.append(callback)
+            callback_and_connectivity[1] = state.connectivity
+    return callbacks_needing_update
 
 
 def _deliver(state, initial_connectivity, initial_callbacks):
-  connectivity = initial_connectivity
-  callbacks = initial_callbacks
-  while True:
-    for callback in callbacks:
-      callable_util.call_logging_exceptions(
-          callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
-          connectivity)
-    with state.lock:
-      callbacks = _deliveries(state)
-      if callbacks:
-        connectivity = state.connectivity
-      else:
-        state.delivering = False
-        return
+    connectivity = initial_connectivity
+    callbacks = initial_callbacks
+    while True:
+        for callback in callbacks:
+            callable_util.call_logging_exceptions(
+                callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
+                connectivity)
+        with state.lock:
+            callbacks = _deliveries(state)
+            if callbacks:
+                connectivity = state.connectivity
+            else:
+                state.delivering = False
+                return
 
 
 def _spawn_delivery(state, callbacks):
-  delivering_thread = threading.Thread(
-      target=_deliver, args=(state, state.connectivity, callbacks,))
-  delivering_thread.start()
-  state.delivering = True
+    delivering_thread = threading.Thread(
+        target=_deliver, args=(
+            state,
+            state.connectivity,
+            callbacks,))
+    delivering_thread.start()
+    state.delivering = True
 
 
 # NOTE(https://github.com/grpc/grpc/issues/3064): We'd rather not poll.
 def _poll_connectivity(state, channel, initial_try_to_connect):
-  try_to_connect = initial_try_to_connect
-  connectivity = channel.check_connectivity_state(try_to_connect)
-  with state.lock:
-    state.connectivity = (
-        _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
-            connectivity])
-    callbacks = tuple(
-        callback for callback, unused_but_known_to_be_none_connectivity
-        in state.callbacks_and_connectivities)
-    for callback_and_connectivity in state.callbacks_and_connectivities:
-      callback_and_connectivity[1] = state.connectivity
-    if callbacks:
-      _spawn_delivery(state, callbacks)
-  completion_queue = cygrpc.CompletionQueue()
-  while True:
-    channel.watch_connectivity_state(
-        connectivity, cygrpc.Timespec(time.time() + 0.2),
-        completion_queue, None)
-    event = completion_queue.poll()
+    try_to_connect = initial_try_to_connect
+    connectivity = channel.check_connectivity_state(try_to_connect)
     with state.lock:
-      if not state.callbacks_and_connectivities and not state.try_to_connect:
-        state.polling = False
-        state.connectivity = None
-        break
-      try_to_connect = state.try_to_connect
-      state.try_to_connect = False
-    if event.success or try_to_connect:
-      connectivity = channel.check_connectivity_state(try_to_connect)
-      with state.lock:
         state.connectivity = (
             _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
                 connectivity])
-        if not state.delivering:
-          callbacks = _deliveries(state)
-          if callbacks:
+        callbacks = tuple(callback
+                          for callback, unused_but_known_to_be_none_connectivity
+                          in state.callbacks_and_connectivities)
+        for callback_and_connectivity in state.callbacks_and_connectivities:
+            callback_and_connectivity[1] = state.connectivity
+        if callbacks:
             _spawn_delivery(state, callbacks)
+    completion_queue = cygrpc.CompletionQueue()
+    while True:
+        channel.watch_connectivity_state(connectivity,
+                                         cygrpc.Timespec(time.time() + 0.2),
+                                         completion_queue, None)
+        event = completion_queue.poll()
+        with state.lock:
+            if not state.callbacks_and_connectivities and not state.try_to_connect:
+                state.polling = False
+                state.connectivity = None
+                break
+            try_to_connect = state.try_to_connect
+            state.try_to_connect = False
+        if event.success or try_to_connect:
+            connectivity = channel.check_connectivity_state(try_to_connect)
+            with state.lock:
+                state.connectivity = (
+                    _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+                        connectivity])
+                if not state.delivering:
+                    callbacks = _deliveries(state)
+                    if callbacks:
+                        _spawn_delivery(state, callbacks)
 
 
 def _moot(state):
-  with state.lock:
-    del state.callbacks_and_connectivities[:]
+    with state.lock:
+        del state.callbacks_and_connectivities[:]
 
 
 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, target=_poll_connectivity,
-          args=(state, state.channel, bool(try_to_connect)))
-      polling_thread.start()
-      state.polling = True
-      state.callbacks_and_connectivities.append([callback, None])
-    elif not state.delivering and state.connectivity is not None:
-      _spawn_delivery(state, (callback,))
-      state.try_to_connect |= bool(try_to_connect)
-      state.callbacks_and_connectivities.append(
-          [callback, state.connectivity])
-    else:
-      state.try_to_connect |= bool(try_to_connect)
-      state.callbacks_and_connectivities.append([callback, None])
+    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,
+                target=_poll_connectivity,
+                args=(state, state.channel, bool(try_to_connect)))
+            polling_thread.start()
+            state.polling = True
+            state.callbacks_and_connectivities.append([callback, None])
+        elif not state.delivering and state.connectivity is not None:
+            _spawn_delivery(state, (callback,))
+            state.try_to_connect |= bool(try_to_connect)
+            state.callbacks_and_connectivities.append(
+                [callback, state.connectivity])
+        else:
+            state.try_to_connect |= bool(try_to_connect)
+            state.callbacks_and_connectivities.append([callback, None])
 
 
 def _unsubscribe(state, callback):
-  with state.lock:
-    for index, (subscribed_callback, unused_connectivity) in enumerate(
-        state.callbacks_and_connectivities):
-      if callback == subscribed_callback:
-        state.callbacks_and_connectivities.pop(index)
-        break
+    with state.lock:
+        for index, (subscribed_callback, unused_connectivity
+                   ) in enumerate(state.callbacks_and_connectivities):
+            if callback == subscribed_callback:
+                state.callbacks_and_connectivities.pop(index)
+                break
 
 
 def _options(options):
-  return list(options) + [
-      (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)]
+    return list(options) + [
+        (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)
+    ]
 
 
 class Channel(grpc.Channel):
-  """A cygrpc.Channel-backed implementation of grpc.Channel."""
+    """A cygrpc.Channel-backed implementation of grpc.Channel."""
 
-  def __init__(self, target, options, credentials):
-    """Constructor.
+    def __init__(self, target, options, credentials):
+        """Constructor.
 
     Args:
       target: The target to which to connect.
       options: Configuration options for the channel.
       credentials: A cygrpc.ChannelCredentials or None.
     """
-    self._channel = cygrpc.Channel(
-        _common.encode(target), _common.channel_args(_options(options)),
-        credentials)
-    self._call_state = _ChannelCallState(self._channel)
-    self._connectivity_state = _ChannelConnectivityState(self._channel)
-
-  def subscribe(self, callback, try_to_connect=None):
-    _subscribe(self._connectivity_state, callback, try_to_connect)
-
-  def unsubscribe(self, callback):
-    _unsubscribe(self._connectivity_state, callback)
-
-  def unary_unary(
-      self, method, request_serializer=None, response_deserializer=None):
-    return _UnaryUnaryMultiCallable(
-        self._channel, _channel_managed_call_management(self._call_state),
-        _common.encode(method), request_serializer, response_deserializer)
-
-  def unary_stream(
-      self, method, request_serializer=None, response_deserializer=None):
-    return _UnaryStreamMultiCallable(
-        self._channel, _channel_managed_call_management(self._call_state),
-        _common.encode(method), request_serializer, response_deserializer)
-
-  def stream_unary(
-      self, method, request_serializer=None, response_deserializer=None):
-    return _StreamUnaryMultiCallable(
-        self._channel, _channel_managed_call_management(self._call_state),
-        _common.encode(method), request_serializer, response_deserializer)
-
-  def stream_stream(
-      self, method, request_serializer=None, response_deserializer=None):
-    return _StreamStreamMultiCallable(
-        self._channel, _channel_managed_call_management(self._call_state),
-        _common.encode(method), request_serializer, response_deserializer)
-
-  def __del__(self):
-    _moot(self._connectivity_state)
+        self._channel = cygrpc.Channel(
+            _common.encode(target),
+            _common.channel_args(_options(options)), credentials)
+        self._call_state = _ChannelCallState(self._channel)
+        self._connectivity_state = _ChannelConnectivityState(self._channel)
+
+    def subscribe(self, callback, try_to_connect=None):
+        _subscribe(self._connectivity_state, callback, try_to_connect)
+
+    def unsubscribe(self, callback):
+        _unsubscribe(self._connectivity_state, callback)
+
+    def unary_unary(self,
+                    method,
+                    request_serializer=None,
+                    response_deserializer=None):
+        return _UnaryUnaryMultiCallable(
+            self._channel,
+            _channel_managed_call_management(self._call_state),
+            _common.encode(method), request_serializer, response_deserializer)
+
+    def unary_stream(self,
+                     method,
+                     request_serializer=None,
+                     response_deserializer=None):
+        return _UnaryStreamMultiCallable(
+            self._channel,
+            _channel_managed_call_management(self._call_state),
+            _common.encode(method), request_serializer, response_deserializer)
+
+    def stream_unary(self,
+                     method,
+                     request_serializer=None,
+                     response_deserializer=None):
+        return _StreamUnaryMultiCallable(
+            self._channel,
+            _channel_managed_call_management(self._call_state),
+            _common.encode(method), request_serializer, response_deserializer)
+
+    def stream_stream(self,
+                      method,
+                      request_serializer=None,
+                      response_deserializer=None):
+        return _StreamStreamMultiCallable(
+            self._channel,
+            _channel_managed_call_management(self._call_state),
+            _common.encode(method), request_serializer, response_deserializer)
+
+    def __del__(self):
+        _moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index cc0984c8c6..7ef2571379 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Shared implementation."""
 
 import logging
@@ -45,9 +44,8 @@ CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
     cygrpc.ConnectivityState.connecting: grpc.ChannelConnectivity.CONNECTING,
     cygrpc.ConnectivityState.ready: grpc.ChannelConnectivity.READY,
     cygrpc.ConnectivityState.transient_failure:
-        grpc.ChannelConnectivity.TRANSIENT_FAILURE,
-    cygrpc.ConnectivityState.shutdown:
-        grpc.ChannelConnectivity.SHUTDOWN,
+    grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+    cygrpc.ConnectivityState.shutdown: grpc.ChannelConnectivity.SHUTDOWN,
 }
 
 CYGRPC_STATUS_CODE_TO_STATUS_CODE = {
@@ -77,83 +75,88 @@ STATUS_CODE_TO_CYGRPC_STATUS_CODE = {
 
 
 def encode(s):
-  if isinstance(s, bytes):
-    return s
-  else:
-    return s.encode('ascii')
+    if isinstance(s, bytes):
+        return s
+    else:
+        return s.encode('ascii')
 
 
 def decode(b):
-  if isinstance(b, str):
-    return b
-  else:
-    try:
-      return b.decode('utf8')
-    except UnicodeDecodeError:
-      logging.exception('Invalid encoding on {}'.format(b))
-      return b.decode('latin1')
+    if isinstance(b, str):
+        return b
+    else:
+        try:
+            return b.decode('utf8')
+        except UnicodeDecodeError:
+            logging.exception('Invalid encoding on {}'.format(b))
+            return b.decode('latin1')
 
 
 def channel_args(options):
-  channel_args = []
-  for key, value in options:
-    if isinstance(value, six.string_types):
-      channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
-    else:
-      channel_args.append(cygrpc.ChannelArg(encode(key), value))
-  return cygrpc.ChannelArgs(channel_args)
+    channel_args = []
+    for key, value in options:
+        if isinstance(value, six.string_types):
+            channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
+        else:
+            channel_args.append(cygrpc.ChannelArg(encode(key), value))
+    return cygrpc.ChannelArgs(channel_args)
 
 
 def cygrpc_metadata(application_metadata):
-  return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
-      cygrpc.Metadatum(encode(key), encode(value))
-      for key, value in application_metadata)
+    return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
+        cygrpc.Metadatum(encode(key), encode(value))
+        for key, value in application_metadata)
 
 
 def application_metadata(cygrpc_metadata):
-  if cygrpc_metadata is None:
-    return ()
-  else:
-    return tuple(
-        (decode(key), value if key[-4:] == b'-bin' else decode(value))
-        for key, value in cygrpc_metadata)
+    if cygrpc_metadata is None:
+        return ()
+    else:
+        return tuple((decode(key), value
+                      if key[-4:] == b'-bin' else decode(value))
+                     for key, value in cygrpc_metadata)
 
 
 def _transform(message, transformer, exception_message):
-  if transformer is None:
-    return message
-  else:
-    try:
-      return transformer(message)
-    except Exception:  # pylint: disable=broad-except
-      logging.exception(exception_message)
-      return None
+    if transformer is None:
+        return message
+    else:
+        try:
+            return transformer(message)
+        except Exception:  # pylint: disable=broad-except
+            logging.exception(exception_message)
+            return None
 
 
 def serialize(message, serializer):
-  return _transform(message, serializer, 'Exception serializing message!')
+    return _transform(message, serializer, 'Exception serializing message!')
 
 
 def deserialize(serialized_message, deserializer):
-  return _transform(serialized_message, deserializer,
-                    'Exception deserializing message!')
+    return _transform(serialized_message, deserializer,
+                      'Exception deserializing message!')
 
 
 def fully_qualified_method(group, method):
-  return '/{}/{}'.format(group, method)
+    return '/{}/{}'.format(group, method)
 
 
 class CleanupThread(threading.Thread):
-  """A threading.Thread subclass supporting custom behavior on join().
+    """A threading.Thread subclass supporting custom behavior on join().
 
   On Python Interpreter exit, Python will attempt to join outstanding threads
   prior to garbage collection.  We may need to do additional cleanup, and
   we accomplish this by overriding the join() method.
   """
 
-  def __init__(self, behavior, group=None, target=None, name=None,
-               args=(), kwargs={}):
-    """Constructor.
+    def __init__(self,
+                 behavior,
+                 group=None,
+                 target=None,
+                 name=None,
+                 args=(),
+                 kwargs={}):
+        """Constructor.
 
     Args:
       behavior (function): Function called on join() with a single
@@ -169,15 +172,15 @@ class CleanupThread(threading.Thread):
       kwargs (dict[str,object]): A dictionary of keyword arguments to
            pass to `target`.
     """
-    super(CleanupThread, self).__init__(group=group, target=target,
-                                        name=name, args=args, kwargs=kwargs)
-    self._behavior = behavior
-
-  def join(self, timeout=None):
-    start_time = time.time()
-    self._behavior(timeout)
-    end_time = time.time()
-    if timeout is not None:
-      timeout -= end_time - start_time
-      timeout = max(timeout, 0)
-    super(CleanupThread, self).join(timeout)
+        super(CleanupThread, self).__init__(
+            group=group, target=target, name=name, args=args, kwargs=kwargs)
+        self._behavior = behavior
+
+    def join(self, timeout=None):
+        start_time = time.time()
+        self._behavior(timeout)
+        end_time = time.time()
+        if timeout is not None:
+            timeout -= end_time - start_time
+            timeout = max(timeout, 0)
+        super(CleanupThread, self).join(timeout)
diff --git a/src/python/grpcio/grpc/_credential_composition.py b/src/python/grpcio/grpc/_credential_composition.py
index 9cb5508e27..bdf017baa5 100644
--- a/src/python/grpcio/grpc/_credential_composition.py
+++ b/src/python/grpcio/grpc/_credential_composition.py
@@ -31,18 +31,18 @@ from grpc._cython import cygrpc
 
 
 def _call(call_credentialses):
-  call_credentials_iterator = iter(call_credentialses)
-  composition = next(call_credentials_iterator)
-  for additional_call_credentials in call_credentials_iterator:
-    composition = cygrpc.call_credentials_composite(
-        composition, additional_call_credentials)
-  return composition
+    call_credentials_iterator = iter(call_credentialses)
+    composition = next(call_credentials_iterator)
+    for additional_call_credentials in call_credentials_iterator:
+        composition = cygrpc.call_credentials_composite(
+            composition, additional_call_credentials)
+    return composition
 
 
 def call(call_credentialses):
-  return _call(call_credentialses)
+    return _call(call_credentialses)
 
 
 def channel(channel_credentials, call_credentialses):
-  return cygrpc.channel_credentials_composite(
-      channel_credentials, _call(call_credentialses))
+    return cygrpc.channel_credentials_composite(channel_credentials,
+                                                _call(call_credentialses))
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 7cb5218c22..bb9a42f3ff 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -36,82 +36,82 @@ from grpc._cython import cygrpc
 
 
 class AuthMetadataContext(
-    collections.namedtuple(
-        'AuthMetadataContext', ('service_url', 'method_name',)),
-    grpc.AuthMetadataContext):
-  pass
+        collections.namedtuple('AuthMetadataContext', (
+            'service_url',
+            'method_name',)), grpc.AuthMetadataContext):
+    pass
 
 
 class AuthMetadataPluginCallback(grpc.AuthMetadataContext):
 
-  def __init__(self, callback):
-    self._callback = callback
+    def __init__(self, callback):
+        self._callback = callback
 
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+    def __call__(self, metadata, error):
+        self._callback(metadata, error)
 
 
 class _WrappedCygrpcCallback(object):
 
-  def __init__(self, cygrpc_callback):
-    self.is_called = False
-    self.error = None
-    self.is_called_lock = threading.Lock()
-    self.cygrpc_callback = cygrpc_callback
-
-  def _invoke_failure(self, error):
-    # TODO(atash) translate different Exception superclasses into different
-    # status codes.
-    self.cygrpc_callback(
-        _common.EMPTY_METADATA, cygrpc.StatusCode.internal,
-        _common.encode(str(error)))
-
-  def _invoke_success(self, metadata):
-    try:
-      cygrpc_metadata = _common.cygrpc_metadata(metadata)
-    except Exception as error:
-      self._invoke_failure(error)
-      return
-    self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
-
-  def __call__(self, metadata, error):
-    with self.is_called_lock:
-      if self.is_called:
-        raise RuntimeError('callback should only ever be invoked once')
-      if self.error:
-        self._invoke_failure(self.error)
-        return
-      self.is_called = True
-    if error is None:
-      self._invoke_success(metadata)
-    else:
-      self._invoke_failure(error)
-
-  def notify_failure(self, error):
-    with self.is_called_lock:
-      if not self.is_called:
-        self.error = error
+    def __init__(self, cygrpc_callback):
+        self.is_called = False
+        self.error = None
+        self.is_called_lock = threading.Lock()
+        self.cygrpc_callback = cygrpc_callback
+
+    def _invoke_failure(self, error):
+        # TODO(atash) translate different Exception superclasses into different
+        # status codes.
+        self.cygrpc_callback(_common.EMPTY_METADATA, cygrpc.StatusCode.internal,
+                             _common.encode(str(error)))
+
+    def _invoke_success(self, metadata):
+        try:
+            cygrpc_metadata = _common.cygrpc_metadata(metadata)
+        except Exception as error:
+            self._invoke_failure(error)
+            return
+        self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
+
+    def __call__(self, metadata, error):
+        with self.is_called_lock:
+            if self.is_called:
+                raise RuntimeError('callback should only ever be invoked once')
+            if self.error:
+                self._invoke_failure(self.error)
+                return
+            self.is_called = True
+        if error is None:
+            self._invoke_success(metadata)
+        else:
+            self._invoke_failure(error)
+
+    def notify_failure(self, error):
+        with self.is_called_lock:
+            if not self.is_called:
+                self.error = error
 
 
 class _WrappedPlugin(object):
 
-  def __init__(self, plugin):
-    self.plugin = plugin
+    def __init__(self, plugin):
+        self.plugin = plugin
 
-  def __call__(self, context, cygrpc_callback):
-    wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
-    wrapped_context = AuthMetadataContext(
-        _common.decode(context.service_url), _common.decode(context.method_name))
-    try:
-      self.plugin(
-          wrapped_context, AuthMetadataPluginCallback(wrapped_cygrpc_callback))
-    except Exception as error:
-      wrapped_cygrpc_callback.notify_failure(error)
-      raise
+    def __call__(self, context, cygrpc_callback):
+        wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
+        wrapped_context = AuthMetadataContext(
+            _common.decode(context.service_url),
+            _common.decode(context.method_name))
+        try:
+            self.plugin(wrapped_context,
+                        AuthMetadataPluginCallback(wrapped_cygrpc_callback))
+        except Exception as error:
+            wrapped_cygrpc_callback.notify_failure(error)
+            raise
 
 
 def call_credentials_metadata_plugin(plugin, name):
-  """
+    """
   Args:
     plugin: A callable accepting a grpc.AuthMetadataContext
       object and a callback (itself accepting a list of metadata key/value
@@ -119,5 +119,6 @@ def call_credentials_metadata_plugin(plugin, name):
       called, but need not be called in plugin's invocation.
       plugin's invocation must be non-blocking.
   """
-  return cygrpc.call_credentials_metadata_plugin(
-      cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), _common.encode(name)))
+    return cygrpc.call_credentials_metadata_plugin(
+        cygrpc.CredentialsMetadataPlugin(
+            _WrappedPlugin(plugin), _common.encode(name)))
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 5223712dfa..158cdf8b0e 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Service-side implementation of gRPC Python."""
 
 import collections
@@ -64,692 +63,715 @@ _UNEXPECTED_EXIT_SERVER_GRACE = 1.0
 
 
 def _serialized_request(request_event):
-  return request_event.batch_operations[0].received_message.bytes()
+    return request_event.batch_operations[0].received_message.bytes()
 
 
 def _application_code(code):
-  cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
-  return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
+    cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
+    return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
 
 
 def _completion_code(state):
-  if state.code is None:
-    return cygrpc.StatusCode.ok
-  else:
-    return _application_code(state.code)
+    if state.code is None:
+        return cygrpc.StatusCode.ok
+    else:
+        return _application_code(state.code)
 
 
 def _abortion_code(state, code):
-  if state.code is None:
-    return code
-  else:
-    return _application_code(state.code)
+    if state.code is None:
+        return code
+    else:
+        return _application_code(state.code)
 
 
 def _details(state):
-  return b'' if state.details is None else state.details
+    return b'' if state.details is None else state.details
 
 
 class _HandlerCallDetails(
-    collections.namedtuple(
-        '_HandlerCallDetails', ('method', 'invocation_metadata',)),
-    grpc.HandlerCallDetails):
-  pass
+        collections.namedtuple('_HandlerCallDetails', (
+            'method',
+            'invocation_metadata',)), grpc.HandlerCallDetails):
+    pass
 
 
 class _RPCState(object):
 
-  def __init__(self):
-    self.condition = threading.Condition()
-    self.due = set()
-    self.request = None
-    self.client = _OPEN
-    self.initial_metadata_allowed = True
-    self.disable_next_compression = False
-    self.trailing_metadata = None
-    self.code = None
-    self.details = None
-    self.statused = False
-    self.rpc_errors = []
-    self.callbacks = []
+    def __init__(self):
+        self.condition = threading.Condition()
+        self.due = set()
+        self.request = None
+        self.client = _OPEN
+        self.initial_metadata_allowed = True
+        self.disable_next_compression = False
+        self.trailing_metadata = None
+        self.code = None
+        self.details = None
+        self.statused = False
+        self.rpc_errors = []
+        self.callbacks = []
 
 
 def _raise_rpc_error(state):
-  rpc_error = grpc.RpcError()
-  state.rpc_errors.append(rpc_error)
-  raise rpc_error
+    rpc_error = grpc.RpcError()
+    state.rpc_errors.append(rpc_error)
+    raise rpc_error
 
 
 def _possibly_finish_call(state, token):
-  state.due.remove(token)
-  if (state.client is _CANCELLED or state.statused) and not state.due:
-    callbacks = state.callbacks
-    state.callbacks = None
-    return state, callbacks
-  else:
-    return None, ()
+    state.due.remove(token)
+    if (state.client is _CANCELLED or state.statused) and not state.due:
+        callbacks = state.callbacks
+        state.callbacks = None
+        return state, callbacks
+    else:
+        return None, ()
 
 
 def _send_status_from_server(state, token):
-  def send_status_from_server(unused_send_status_from_server_event):
-    with state.condition:
-      return _possibly_finish_call(state, token)
-  return send_status_from_server
+
+    def send_status_from_server(unused_send_status_from_server_event):
+        with state.condition:
+            return _possibly_finish_call(state, token)
+
+    return send_status_from_server
 
 
 def _abort(state, call, code, details):
-  if state.client is not _CANCELLED:
-    effective_code = _abortion_code(state, code)
-    effective_details = details if state.details is None else state.details
-    if state.initial_metadata_allowed:
-      operations = (
-          cygrpc.operation_send_initial_metadata(
-              _EMPTY_METADATA, _EMPTY_FLAGS),
-          cygrpc.operation_send_status_from_server(
-              _common.cygrpc_metadata(state.trailing_metadata), effective_code,
-              effective_details, _EMPTY_FLAGS),
-      )
-      token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
-    else:
-      operations = (
-          cygrpc.operation_send_status_from_server(
-              _common.cygrpc_metadata(state.trailing_metadata), effective_code,
-              effective_details, _EMPTY_FLAGS),
-      )
-      token = _SEND_STATUS_FROM_SERVER_TOKEN
-    call.start_server_batch(
-        cygrpc.Operations(operations),
-        _send_status_from_server(state, token))
-    state.statused = True
-    state.due.add(token)
+    if state.client is not _CANCELLED:
+        effective_code = _abortion_code(state, code)
+        effective_details = details if state.details is None else state.details
+        if state.initial_metadata_allowed:
+            operations = (
+                cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                       _EMPTY_FLAGS),
+                cygrpc.operation_send_status_from_server(
+                    _common.cygrpc_metadata(state.trailing_metadata),
+                    effective_code, effective_details, _EMPTY_FLAGS),)
+            token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
+        else:
+            operations = (cygrpc.operation_send_status_from_server(
+                _common.cygrpc_metadata(state.trailing_metadata),
+                effective_code, effective_details, _EMPTY_FLAGS),)
+            token = _SEND_STATUS_FROM_SERVER_TOKEN
+        call.start_server_batch(
+            cygrpc.Operations(operations),
+            _send_status_from_server(state, token))
+        state.statused = True
+        state.due.add(token)
 
 
 def _receive_close_on_server(state):
-  def receive_close_on_server(receive_close_on_server_event):
-    with state.condition:
-      if receive_close_on_server_event.batch_operations[0].received_cancelled:
-        state.client = _CANCELLED
-      elif state.client is _OPEN:
-        state.client = _CLOSED
-      state.condition.notify_all()
-      return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
-  return receive_close_on_server
+
+    def receive_close_on_server(receive_close_on_server_event):
+        with state.condition:
+            if receive_close_on_server_event.batch_operations[
+                    0].received_cancelled:
+                state.client = _CANCELLED
+            elif state.client is _OPEN:
+                state.client = _CLOSED
+            state.condition.notify_all()
+            return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
+
+    return receive_close_on_server
 
 
 def _receive_message(state, call, request_deserializer):
-  def receive_message(receive_message_event):
-    serialized_request = _serialized_request(receive_message_event)
-    if serialized_request is None:
-      with state.condition:
-        if state.client is _OPEN:
-          state.client = _CLOSED
-        state.condition.notify_all()
-        return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
-    else:
-      request = _common.deserialize(serialized_request, request_deserializer)
-      with state.condition:
-        if request is None:
-          _abort(
-              state, call, cygrpc.StatusCode.internal,
-              b'Exception deserializing request!')
+
+    def receive_message(receive_message_event):
+        serialized_request = _serialized_request(receive_message_event)
+        if serialized_request is None:
+            with state.condition:
+                if state.client is _OPEN:
+                    state.client = _CLOSED
+                state.condition.notify_all()
+                return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
         else:
-          state.request = request
-        state.condition.notify_all()
-        return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
-  return receive_message
+            request = _common.deserialize(serialized_request,
+                                          request_deserializer)
+            with state.condition:
+                if request is None:
+                    _abort(state, call, cygrpc.StatusCode.internal,
+                           b'Exception deserializing request!')
+                else:
+                    state.request = request
+                state.condition.notify_all()
+                return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
+
+    return receive_message
 
 
 def _send_initial_metadata(state):
-  def send_initial_metadata(unused_send_initial_metadata_event):
-    with state.condition:
-      return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
-  return send_initial_metadata
+
+    def send_initial_metadata(unused_send_initial_metadata_event):
+        with state.condition:
+            return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
+
+    return send_initial_metadata
 
 
 def _send_message(state, token):
-  def send_message(unused_send_message_event):
-    with state.condition:
-      state.condition.notify_all()
-      return _possibly_finish_call(state, token)
-  return send_message
+
+    def send_message(unused_send_message_event):
+        with state.condition:
+            state.condition.notify_all()
+            return _possibly_finish_call(state, token)
+
+    return send_message
 
 
 class _Context(grpc.ServicerContext):
 
-  def __init__(self, rpc_event, state, request_deserializer):
-    self._rpc_event = rpc_event
-    self._state = state
-    self._request_deserializer = request_deserializer
+    def __init__(self, rpc_event, state, request_deserializer):
+        self._rpc_event = rpc_event
+        self._state = state
+        self._request_deserializer = request_deserializer
 
-  def is_active(self):
-    with self._state.condition:
-      return self._state.client is not _CANCELLED and not self._state.statused
+    def is_active(self):
+        with self._state.condition:
+            return self._state.client is not _CANCELLED and not self._state.statused
 
-  def time_remaining(self):
-    return max(self._rpc_event.request_call_details.deadline - time.time(), 0)
+    def time_remaining(self):
+        return max(self._rpc_event.request_call_details.deadline - time.time(),
+                   0)
 
-  def cancel(self):
-    self._rpc_event.operation_call.cancel()
+    def cancel(self):
+        self._rpc_event.operation_call.cancel()
 
-  def add_callback(self, callback):
-    with self._state.condition:
-      if self._state.callbacks is None:
-        return False
-      else:
-        self._state.callbacks.append(callback)
-        return True
+    def add_callback(self, callback):
+        with self._state.condition:
+            if self._state.callbacks is None:
+                return False
+            else:
+                self._state.callbacks.append(callback)
+                return True
 
-  def disable_next_message_compression(self):
-    with self._state.condition:
-      self._state.disable_next_compression = True
-
-  def invocation_metadata(self):
-    return _common.application_metadata(self._rpc_event.request_metadata)
-
-  def peer(self):
-    return _common.decode(self._rpc_event.operation_call.peer())
-
-  def send_initial_metadata(self, initial_metadata):
-    with self._state.condition:
-      if self._state.client is _CANCELLED:
-        _raise_rpc_error(self._state)
-      else:
-        if self._state.initial_metadata_allowed:
-          operation = cygrpc.operation_send_initial_metadata(
-              _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
-          self._rpc_event.operation_call.start_server_batch(
-              cygrpc.Operations((operation,)),
-              _send_initial_metadata(self._state))
-          self._state.initial_metadata_allowed = False
-          self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
-        else:
-          raise ValueError('Initial metadata no longer allowed!')
+    def disable_next_message_compression(self):
+        with self._state.condition:
+            self._state.disable_next_compression = True
 
-  def set_trailing_metadata(self, trailing_metadata):
-    with self._state.condition:
-      self._state.trailing_metadata = _common.cygrpc_metadata(
-          trailing_metadata)
+    def invocation_metadata(self):
+        return _common.application_metadata(self._rpc_event.request_metadata)
 
-  def set_code(self, code):
-    with self._state.condition:
-      self._state.code = code
+    def peer(self):
+        return _common.decode(self._rpc_event.operation_call.peer())
 
-  def set_details(self, details):
-    with self._state.condition:
-      self._state.details = _common.encode(details)
+    def send_initial_metadata(self, initial_metadata):
+        with self._state.condition:
+            if self._state.client is _CANCELLED:
+                _raise_rpc_error(self._state)
+            else:
+                if self._state.initial_metadata_allowed:
+                    operation = cygrpc.operation_send_initial_metadata(
+                        _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
+                    self._rpc_event.operation_call.start_server_batch(
+                        cygrpc.Operations((operation,)),
+                        _send_initial_metadata(self._state))
+                    self._state.initial_metadata_allowed = False
+                    self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
+                else:
+                    raise ValueError('Initial metadata no longer allowed!')
+
+    def set_trailing_metadata(self, trailing_metadata):
+        with self._state.condition:
+            self._state.trailing_metadata = _common.cygrpc_metadata(
+                trailing_metadata)
+
+    def set_code(self, code):
+        with self._state.condition:
+            self._state.code = code
+
+    def set_details(self, details):
+        with self._state.condition:
+            self._state.details = _common.encode(details)
 
 
 class _RequestIterator(object):
 
-  def __init__(self, state, call, request_deserializer):
-    self._state = state
-    self._call = call
-    self._request_deserializer = request_deserializer
+    def __init__(self, state, call, request_deserializer):
+        self._state = state
+        self._call = call
+        self._request_deserializer = request_deserializer
 
-  def _raise_or_start_receive_message(self):
-    if self._state.client is _CANCELLED:
-      _raise_rpc_error(self._state)
-    elif self._state.client is _CLOSED or self._state.statused:
-      raise StopIteration()
-    else:
-      self._call.start_server_batch(
-          cygrpc.Operations((cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
-          _receive_message(self._state, self._call, self._request_deserializer))
-      self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
-
-  def _look_for_request(self):
-    if self._state.client is _CANCELLED:
-      _raise_rpc_error(self._state)
-    elif (self._state.request is None and
-          _RECEIVE_MESSAGE_TOKEN not in self._state.due):
-      raise StopIteration()
-    else:
-      request = self._state.request
-      self._state.request = None
-      return request
+    def _raise_or_start_receive_message(self):
+        if self._state.client is _CANCELLED:
+            _raise_rpc_error(self._state)
+        elif self._state.client is _CLOSED or self._state.statused:
+            raise StopIteration()
+        else:
+            self._call.start_server_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+                _receive_message(self._state, self._call,
+                                 self._request_deserializer))
+            self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
+
+    def _look_for_request(self):
+        if self._state.client is _CANCELLED:
+            _raise_rpc_error(self._state)
+        elif (self._state.request is None and
+              _RECEIVE_MESSAGE_TOKEN not in self._state.due):
+            raise StopIteration()
+        else:
+            request = self._state.request
+            self._state.request = None
+            return request
 
-  def _next(self):
-    with self._state.condition:
-      self._raise_or_start_receive_message()
-      while True:
-        self._state.condition.wait()
-        request = self._look_for_request()
-        if request is not None:
-          return request
+    def _next(self):
+        with self._state.condition:
+            self._raise_or_start_receive_message()
+            while True:
+                self._state.condition.wait()
+                request = self._look_for_request()
+                if request is not None:
+                    return request
 
-  def __iter__(self):
-    return self
+    def __iter__(self):
+        return self
 
-  def __next__(self):
-    return self._next()
+    def __next__(self):
+        return self._next()
 
-  def next(self):
-    return self._next()
+    def next(self):
+        return self._next()
 
 
 def _unary_request(rpc_event, state, request_deserializer):
-  def unary_request():
-    with state.condition:
-      if state.client is _CANCELLED or state.statused:
-        return None
-      else:
-        start_server_batch_result = rpc_event.operation_call.start_server_batch(
-            cygrpc.Operations(
-                (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
-            _receive_message(
-                state, rpc_event.operation_call, request_deserializer))
-        state.due.add(_RECEIVE_MESSAGE_TOKEN)
-        while True:
-          state.condition.wait()
-          if state.request is None:
-            if state.client is _CLOSED:
-              details = '"{}" requires exactly one request message.'.format(
-                  rpc_event.request_call_details.method)
-              _abort(
-                  state, rpc_event.operation_call,
-                  cygrpc.StatusCode.unimplemented, _common.encode(details))
-              return None
-            elif state.client is _CANCELLED:
-              return None
-          else:
-            request = state.request
-            state.request = None
-            return request
-  return unary_request
+
+    def unary_request():
+        with state.condition:
+            if state.client is _CANCELLED or state.statused:
+                return None
+            else:
+                start_server_batch_result = rpc_event.operation_call.start_server_batch(
+                    cygrpc.Operations(
+                        (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+                    _receive_message(state, rpc_event.operation_call,
+                                     request_deserializer))
+                state.due.add(_RECEIVE_MESSAGE_TOKEN)
+                while True:
+                    state.condition.wait()
+                    if state.request is None:
+                        if state.client is _CLOSED:
+                            details = '"{}" requires exactly one request message.'.format(
+                                rpc_event.request_call_details.method)
+                            _abort(state, rpc_event.operation_call,
+                                   cygrpc.StatusCode.unimplemented,
+                                   _common.encode(details))
+                            return None
+                        elif state.client is _CANCELLED:
+                            return None
+                    else:
+                        request = state.request
+                        state.request = None
+                        return request
+
+    return unary_request
 
 
 def _call_behavior(rpc_event, state, behavior, argument, request_deserializer):
-  context = _Context(rpc_event, state, request_deserializer)
-  try:
-    return behavior(argument, context), True
-  except Exception as e:  # pylint: disable=broad-except
-    with state.condition:
-      if e not in state.rpc_errors:
-        details = 'Exception calling application: {}'.format(e)
-        logging.exception(details)
-        _abort(state, rpc_event.operation_call,
-               cygrpc.StatusCode.unknown, _common.encode(details))
-    return None, False
+    context = _Context(rpc_event, state, request_deserializer)
+    try:
+        return behavior(argument, context), True
+    except Exception as e:  # pylint: disable=broad-except
+        with state.condition:
+            if e not in state.rpc_errors:
+                details = 'Exception calling application: {}'.format(e)
+                logging.exception(details)
+                _abort(state, rpc_event.operation_call,
+                       cygrpc.StatusCode.unknown, _common.encode(details))
+        return None, False
 
 
 def _take_response_from_response_iterator(rpc_event, state, response_iterator):
-  try:
-    return next(response_iterator), True
-  except StopIteration:
-    return None, True
-  except Exception as e:  # pylint: disable=broad-except
-    with state.condition:
-      if e not in state.rpc_errors:
-        details = 'Exception iterating responses: {}'.format(e)
-        logging.exception(details)
-        _abort(state, rpc_event.operation_call,
-               cygrpc.StatusCode.unknown, _common.encode(details))
-    return None, False
+    try:
+        return next(response_iterator), True
+    except StopIteration:
+        return None, True
+    except Exception as e:  # pylint: disable=broad-except
+        with state.condition:
+            if e not in state.rpc_errors:
+                details = 'Exception iterating responses: {}'.format(e)
+                logging.exception(details)
+                _abort(state, rpc_event.operation_call,
+                       cygrpc.StatusCode.unknown, _common.encode(details))
+        return None, False
 
 
 def _serialize_response(rpc_event, state, response, response_serializer):
-  serialized_response = _common.serialize(response, response_serializer)
-  if serialized_response is None:
-    with state.condition:
-      _abort(
-          state, rpc_event.operation_call, cygrpc.StatusCode.internal,
-          b'Failed to serialize response!')
-    return None
-  else:
-    return serialized_response
+    serialized_response = _common.serialize(response, response_serializer)
+    if serialized_response is None:
+        with state.condition:
+            _abort(state, rpc_event.operation_call, cygrpc.StatusCode.internal,
+                   b'Failed to serialize response!')
+        return None
+    else:
+        return serialized_response
 
 
 def _send_response(rpc_event, state, serialized_response):
-  with state.condition:
-    if state.client is _CANCELLED or state.statused:
-      return False
-    else:
-      if state.initial_metadata_allowed:
-        operations = (
-            cygrpc.operation_send_initial_metadata(
-                _EMPTY_METADATA, _EMPTY_FLAGS),
-            cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
-        )
-        state.initial_metadata_allowed = False
-        token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
-      else:
-        operations = (
-            cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
-        )
-        token = _SEND_MESSAGE_TOKEN
-      rpc_event.operation_call.start_server_batch(
-          cygrpc.Operations(operations), _send_message(state, token))
-      state.due.add(token)
-      while True:
-        state.condition.wait()
-        if token not in state.due:
-          return state.client is not _CANCELLED and not state.statused
+    with state.condition:
+        if state.client is _CANCELLED or state.statused:
+            return False
+        else:
+            if state.initial_metadata_allowed:
+                operations = (
+                    cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                           _EMPTY_FLAGS),
+                    cygrpc.operation_send_message(serialized_response,
+                                                  _EMPTY_FLAGS),)
+                state.initial_metadata_allowed = False
+                token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
+            else:
+                operations = (cygrpc.operation_send_message(serialized_response,
+                                                            _EMPTY_FLAGS),)
+                token = _SEND_MESSAGE_TOKEN
+            rpc_event.operation_call.start_server_batch(
+                cygrpc.Operations(operations), _send_message(state, token))
+            state.due.add(token)
+            while True:
+                state.condition.wait()
+                if token not in state.due:
+                    return state.client is not _CANCELLED and not state.statused
 
 
 def _status(rpc_event, state, serialized_response):
-  with state.condition:
-    if state.client is not _CANCELLED:
-      trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
-      code = _completion_code(state)
-      details = _details(state)
-      operations = [
-          cygrpc.operation_send_status_from_server(
-              trailing_metadata, code, details, _EMPTY_FLAGS),
-      ]
-      if state.initial_metadata_allowed:
-        operations.append(
-            cygrpc.operation_send_initial_metadata(
-                _EMPTY_METADATA, _EMPTY_FLAGS))
-      if serialized_response is not None:
-        operations.append(cygrpc.operation_send_message(
-            serialized_response, _EMPTY_FLAGS))
-      rpc_event.operation_call.start_server_batch(
-          cygrpc.Operations(operations),
-          _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
-      state.statused = True
-      state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
-
-
-def _unary_response_in_pool(
-    rpc_event, state, behavior, argument_thunk, request_deserializer,
-    response_serializer):
-  argument = argument_thunk()
-  if argument is not None:
-    response, proceed = _call_behavior(
-        rpc_event, state, behavior, argument, request_deserializer)
-    if proceed:
-      serialized_response = _serialize_response(
-          rpc_event, state, response, response_serializer)
-      if serialized_response is not None:
-        _status(rpc_event, state, serialized_response)
-
-
-def _stream_response_in_pool(
-    rpc_event, state, behavior, argument_thunk, request_deserializer,
-    response_serializer):
-  argument = argument_thunk()
-  if argument is not None:
-    response_iterator, proceed = _call_behavior(
-        rpc_event, state, behavior, argument, request_deserializer)
-    if proceed:
-      while True:
-        response, proceed = _take_response_from_response_iterator(
-            rpc_event, state, response_iterator)
+    with state.condition:
+        if state.client is not _CANCELLED:
+            trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
+            code = _completion_code(state)
+            details = _details(state)
+            operations = [
+                cygrpc.operation_send_status_from_server(
+                    trailing_metadata, code, details, _EMPTY_FLAGS),
+            ]
+            if state.initial_metadata_allowed:
+                operations.append(
+                    cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                           _EMPTY_FLAGS))
+            if serialized_response is not None:
+                operations.append(
+                    cygrpc.operation_send_message(serialized_response,
+                                                  _EMPTY_FLAGS))
+            rpc_event.operation_call.start_server_batch(
+                cygrpc.Operations(operations),
+                _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
+            state.statused = True
+            state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
+
+
+def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk,
+                            request_deserializer, response_serializer):
+    argument = argument_thunk()
+    if argument is not None:
+        response, proceed = _call_behavior(rpc_event, state, behavior, argument,
+                                           request_deserializer)
         if proceed:
-          if response is None:
-            _status(rpc_event, state, None)
-            break
-          else:
             serialized_response = _serialize_response(
                 rpc_event, state, response, response_serializer)
             if serialized_response is not None:
-              proceed = _send_response(rpc_event, state, serialized_response)
-              if not proceed:
-                break
-            else:
-              break
-        else:
-          break
+                _status(rpc_event, state, serialized_response)
+
+
+def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
+                             request_deserializer, response_serializer):
+    argument = argument_thunk()
+    if argument is not None:
+        response_iterator, proceed = _call_behavior(
+            rpc_event, state, behavior, argument, request_deserializer)
+        if proceed:
+            while True:
+                response, proceed = _take_response_from_response_iterator(
+                    rpc_event, state, response_iterator)
+                if proceed:
+                    if response is None:
+                        _status(rpc_event, state, None)
+                        break
+                    else:
+                        serialized_response = _serialize_response(
+                            rpc_event, state, response, response_serializer)
+                        if serialized_response is not None:
+                            proceed = _send_response(rpc_event, state,
+                                                     serialized_response)
+                            if not proceed:
+                                break
+                        else:
+                            break
+                else:
+                    break
 
 
 def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
-  unary_request = _unary_request(
-      rpc_event, state, method_handler.request_deserializer)
-  thread_pool.submit(
-      _unary_response_in_pool, rpc_event, state, method_handler.unary_unary,
-      unary_request, method_handler.request_deserializer,
-      method_handler.response_serializer)
+    unary_request = _unary_request(rpc_event, state,
+                                   method_handler.request_deserializer)
+    thread_pool.submit(_unary_response_in_pool, rpc_event, state,
+                       method_handler.unary_unary, unary_request,
+                       method_handler.request_deserializer,
+                       method_handler.response_serializer)
 
 
 def _handle_unary_stream(rpc_event, state, method_handler, thread_pool):
-  unary_request = _unary_request(
-      rpc_event, state, method_handler.request_deserializer)
-  thread_pool.submit(
-      _stream_response_in_pool, rpc_event, state, method_handler.unary_stream,
-      unary_request, method_handler.request_deserializer,
-      method_handler.response_serializer)
+    unary_request = _unary_request(rpc_event, state,
+                                   method_handler.request_deserializer)
+    thread_pool.submit(_stream_response_in_pool, rpc_event, state,
+                       method_handler.unary_stream, unary_request,
+                       method_handler.request_deserializer,
+                       method_handler.response_serializer)
 
 
 def _handle_stream_unary(rpc_event, state, method_handler, thread_pool):
-  request_iterator = _RequestIterator(
-      state, rpc_event.operation_call, method_handler.request_deserializer)
-  thread_pool.submit(
-      _unary_response_in_pool, rpc_event, state, method_handler.stream_unary,
-      lambda: request_iterator, method_handler.request_deserializer,
-      method_handler.response_serializer)
+    request_iterator = _RequestIterator(state, rpc_event.operation_call,
+                                        method_handler.request_deserializer)
+    thread_pool.submit(_unary_response_in_pool, rpc_event, state,
+                       method_handler.stream_unary, lambda: request_iterator,
+                       method_handler.request_deserializer,
+                       method_handler.response_serializer)
 
 
 def _handle_stream_stream(rpc_event, state, method_handler, thread_pool):
-  request_iterator = _RequestIterator(
-      state, rpc_event.operation_call, method_handler.request_deserializer)
-  thread_pool.submit(
-      _stream_response_in_pool, rpc_event, state, method_handler.stream_stream,
-      lambda: request_iterator, method_handler.request_deserializer,
-      method_handler.response_serializer)
+    request_iterator = _RequestIterator(state, rpc_event.operation_call,
+                                        method_handler.request_deserializer)
+    thread_pool.submit(_stream_response_in_pool, rpc_event, state,
+                       method_handler.stream_stream, lambda: request_iterator,
+                       method_handler.request_deserializer,
+                       method_handler.response_serializer)
 
 
 def _find_method_handler(rpc_event, generic_handlers):
-  for generic_handler in generic_handlers:
-    method_handler = generic_handler.service(
-        _HandlerCallDetails(
-            _common.decode(rpc_event.request_call_details.method),
-            rpc_event.request_metadata))
-    if method_handler is not None:
-      return method_handler
-  else:
-    return None
+    for generic_handler in generic_handlers:
+        method_handler = generic_handler.service(
+            _HandlerCallDetails(
+                _common.decode(rpc_event.request_call_details.method),
+                rpc_event.request_metadata))
+        if method_handler is not None:
+            return method_handler
+    else:
+        return None
 
 
 def _handle_unrecognized_method(rpc_event):
-  operations = (
-      cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, _EMPTY_FLAGS),
-      cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
-      cygrpc.operation_send_status_from_server(
-          _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
-          b'Method not found!', _EMPTY_FLAGS),
-  )
-  rpc_state = _RPCState()
-  rpc_event.operation_call.start_server_batch(
-      operations, lambda ignored_event: (rpc_state, (),))
-  return rpc_state
+    operations = (
+        cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, _EMPTY_FLAGS),
+        cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+        cygrpc.operation_send_status_from_server(
+            _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
+            b'Method not found!', _EMPTY_FLAGS),)
+    rpc_state = _RPCState()
+    rpc_event.operation_call.start_server_batch(operations,
+                                                lambda ignored_event: (
+                                                    rpc_state,
+                                                    (),))
+    return rpc_state
 
 
 def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
-  state = _RPCState()
-  with state.condition:
-    rpc_event.operation_call.start_server_batch(
-        cygrpc.Operations(
-            (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
-        _receive_close_on_server(state))
-    state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
-    if method_handler.request_streaming:
-      if method_handler.response_streaming:
-        _handle_stream_stream(rpc_event, state, method_handler, thread_pool)
-      else:
-        _handle_stream_unary(rpc_event, state, method_handler, thread_pool)
-    else:
-      if method_handler.response_streaming:
-        _handle_unary_stream(rpc_event, state, method_handler, thread_pool)
-      else:
-        _handle_unary_unary(rpc_event, state, method_handler, thread_pool)
-    return state
+    state = _RPCState()
+    with state.condition:
+        rpc_event.operation_call.start_server_batch(
+            cygrpc.Operations(
+                (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
+            _receive_close_on_server(state))
+        state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
+        if method_handler.request_streaming:
+            if method_handler.response_streaming:
+                _handle_stream_stream(rpc_event, state, method_handler,
+                                      thread_pool)
+            else:
+                _handle_stream_unary(rpc_event, state, method_handler,
+                                     thread_pool)
+        else:
+            if method_handler.response_streaming:
+                _handle_unary_stream(rpc_event, state, method_handler,
+                                     thread_pool)
+            else:
+                _handle_unary_unary(rpc_event, state, method_handler,
+                                    thread_pool)
+        return state
 
 
 def _handle_call(rpc_event, generic_handlers, thread_pool):
-  if rpc_event.request_call_details.method is not None:
-    method_handler = _find_method_handler(rpc_event, generic_handlers)
-    if method_handler is None:
-      return _handle_unrecognized_method(rpc_event)
+    if rpc_event.request_call_details.method is not None:
+        method_handler = _find_method_handler(rpc_event, generic_handlers)
+        if method_handler is None:
+            return _handle_unrecognized_method(rpc_event)
+        else:
+            return _handle_with_method_handler(rpc_event, method_handler,
+                                               thread_pool)
     else:
-      return _handle_with_method_handler(rpc_event, method_handler, thread_pool)
-  else:
-    return None
+        return None
 
 
 @enum.unique
 class _ServerStage(enum.Enum):
-  STOPPED = 'stopped'
-  STARTED = 'started'
-  GRACE = 'grace'
+    STOPPED = 'stopped'
+    STARTED = 'started'
+    GRACE = 'grace'
 
 
 class _ServerState(object):
 
-  def __init__(self, completion_queue, server, generic_handlers, thread_pool):
-    self.lock = threading.Lock()
-    self.completion_queue = completion_queue
-    self.server = server
-    self.generic_handlers = list(generic_handlers)
-    self.thread_pool = thread_pool
-    self.stage = _ServerStage.STOPPED
-    self.shutdown_events = None
+    def __init__(self, completion_queue, server, generic_handlers, thread_pool):
+        self.lock = threading.Lock()
+        self.completion_queue = completion_queue
+        self.server = server
+        self.generic_handlers = list(generic_handlers)
+        self.thread_pool = thread_pool
+        self.stage = _ServerStage.STOPPED
+        self.shutdown_events = None
 
-    # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
-    self.rpc_states = set()
-    self.due = set()
+        # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
+        self.rpc_states = set()
+        self.due = set()
 
 
 def _add_generic_handlers(state, generic_handlers):
-  with state.lock:
-    state.generic_handlers.extend(generic_handlers)
+    with state.lock:
+        state.generic_handlers.extend(generic_handlers)
 
 
 def _add_insecure_port(state, address):
-  with state.lock:
-    return state.server.add_http2_port(address)
+    with state.lock:
+        return state.server.add_http2_port(address)
 
 
 def _add_secure_port(state, address, server_credentials):
-  with state.lock:
-    return state.server.add_http2_port(address, server_credentials._credentials)
+    with state.lock:
+        return state.server.add_http2_port(address,
+                                           server_credentials._credentials)
 
 
 def _request_call(state):
-  state.server.request_call(
-      state.completion_queue, state.completion_queue, _REQUEST_CALL_TAG)
-  state.due.add(_REQUEST_CALL_TAG)
+    state.server.request_call(state.completion_queue, state.completion_queue,
+                              _REQUEST_CALL_TAG)
+    state.due.add(_REQUEST_CALL_TAG)
 
 
 # TODO(https://github.com/grpc/grpc/issues/6597): delete this function.
 def _stop_serving(state):
-  if not state.rpc_states and not state.due:
-    for shutdown_event in state.shutdown_events:
-      shutdown_event.set()
-    state.stage = _ServerStage.STOPPED
-    return True
-  else:
-    return False
+    if not state.rpc_states and not state.due:
+        for shutdown_event in state.shutdown_events:
+            shutdown_event.set()
+        state.stage = _ServerStage.STOPPED
+        return True
+    else:
+        return False
 
 
 def _serve(state):
-  while True:
-    event = state.completion_queue.poll()
-    if event.tag is _SHUTDOWN_TAG:
-      with state.lock:
-        state.due.remove(_SHUTDOWN_TAG)
-        if _stop_serving(state):
-          return
-    elif event.tag is _REQUEST_CALL_TAG:
-      with state.lock:
-        state.due.remove(_REQUEST_CALL_TAG)
-        rpc_state = _handle_call(
-            event, state.generic_handlers, state.thread_pool)
-        if rpc_state is not None:
-          state.rpc_states.add(rpc_state)
-        if state.stage is _ServerStage.STARTED:
-          _request_call(state)
-        elif _stop_serving(state):
-          return
-    else:
-      rpc_state, callbacks = event.tag(event)
-      for callback in callbacks:
-        callable_util.call_logging_exceptions(
-            callback, 'Exception calling callback!')
-      if rpc_state is not None:
-        with state.lock:
-          state.rpc_states.remove(rpc_state)
-          if _stop_serving(state):
-            return
+    while True:
+        event = state.completion_queue.poll()
+        if event.tag is _SHUTDOWN_TAG:
+            with state.lock:
+                state.due.remove(_SHUTDOWN_TAG)
+                if _stop_serving(state):
+                    return
+        elif event.tag is _REQUEST_CALL_TAG:
+            with state.lock:
+                state.due.remove(_REQUEST_CALL_TAG)
+                rpc_state = _handle_call(event, state.generic_handlers,
+                                         state.thread_pool)
+                if rpc_state is not None:
+                    state.rpc_states.add(rpc_state)
+                if state.stage is _ServerStage.STARTED:
+                    _request_call(state)
+                elif _stop_serving(state):
+                    return
+        else:
+            rpc_state, callbacks = event.tag(event)
+            for callback in callbacks:
+                callable_util.call_logging_exceptions(
+                    callback, 'Exception calling callback!')
+            if rpc_state is not None:
+                with state.lock:
+                    state.rpc_states.remove(rpc_state)
+                    if _stop_serving(state):
+                        return
 
 
 def _stop(state, grace):
-  with state.lock:
-    if state.stage is _ServerStage.STOPPED:
-      shutdown_event = threading.Event()
-      shutdown_event.set()
-      return shutdown_event
-    else:
-      if state.stage is _ServerStage.STARTED:
-        state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
-        state.stage = _ServerStage.GRACE
-        state.shutdown_events = []
-        state.due.add(_SHUTDOWN_TAG)
-      shutdown_event = threading.Event()
-      state.shutdown_events.append(shutdown_event)
-      if grace is None:
-        state.server.cancel_all_calls()
-        # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
-        for rpc_state in state.rpc_states:
-          with rpc_state.condition:
-            rpc_state.client = _CANCELLED
-            rpc_state.condition.notify_all()
-      else:
-        def cancel_all_calls_after_grace():
-          shutdown_event.wait(timeout=grace)
-          with state.lock:
-            state.server.cancel_all_calls()
-            # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
-            for rpc_state in state.rpc_states:
-              with rpc_state.condition:
-                rpc_state.client = _CANCELLED
-                rpc_state.condition.notify_all()
-        thread = threading.Thread(target=cancel_all_calls_after_grace)
-        thread.start()
-        return shutdown_event
-  shutdown_event.wait()
-  return shutdown_event
+    with state.lock:
+        if state.stage is _ServerStage.STOPPED:
+            shutdown_event = threading.Event()
+            shutdown_event.set()
+            return shutdown_event
+        else:
+            if state.stage is _ServerStage.STARTED:
+                state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
+                state.stage = _ServerStage.GRACE
+                state.shutdown_events = []
+                state.due.add(_SHUTDOWN_TAG)
+            shutdown_event = threading.Event()
+            state.shutdown_events.append(shutdown_event)
+            if grace is None:
+                state.server.cancel_all_calls()
+                # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+                for rpc_state in state.rpc_states:
+                    with rpc_state.condition:
+                        rpc_state.client = _CANCELLED
+                        rpc_state.condition.notify_all()
+            else:
+
+                def cancel_all_calls_after_grace():
+                    shutdown_event.wait(timeout=grace)
+                    with state.lock:
+                        state.server.cancel_all_calls()
+                        # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+                        for rpc_state in state.rpc_states:
+                            with rpc_state.condition:
+                                rpc_state.client = _CANCELLED
+                                rpc_state.condition.notify_all()
+
+                thread = threading.Thread(target=cancel_all_calls_after_grace)
+                thread.start()
+                return shutdown_event
+    shutdown_event.wait()
+    return shutdown_event
 
 
 def _start(state):
-  with state.lock:
-    if state.stage is not _ServerStage.STOPPED:
-      raise ValueError('Cannot start already-started server!')
-    state.server.start()
-    state.stage = _ServerStage.STARTED
-    _request_call(state)    
-    def cleanup_server(timeout):
-      if timeout is None:
-        _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
-      else:
-        _stop(state, timeout).wait()
-
-    thread = _common.CleanupThread(
-        cleanup_server, target=_serve, args=(state,))
-    thread.start()
+    with state.lock:
+        if state.stage is not _ServerStage.STOPPED:
+            raise ValueError('Cannot start already-started server!')
+        state.server.start()
+        state.stage = _ServerStage.STARTED
+        _request_call(state)
+
+        def cleanup_server(timeout):
+            if timeout is None:
+                _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
+            else:
+                _stop(state, timeout).wait()
+
+        thread = _common.CleanupThread(
+            cleanup_server, target=_serve, args=(state,))
+        thread.start()
+
 
 class Server(grpc.Server):
 
-  def __init__(self, thread_pool, generic_handlers, options):
-    completion_queue = cygrpc.CompletionQueue()
-    server = cygrpc.Server(_common.channel_args(options))
-    server.register_completion_queue(completion_queue)
-    self._state = _ServerState(
-        completion_queue, server, generic_handlers, thread_pool)
+    def __init__(self, thread_pool, generic_handlers, options):
+        completion_queue = cygrpc.CompletionQueue()
+        server = cygrpc.Server(_common.channel_args(options))
+        server.register_completion_queue(completion_queue)
+        self._state = _ServerState(completion_queue, server, generic_handlers,
+                                   thread_pool)
 
-  def add_generic_rpc_handlers(self, generic_rpc_handlers):
-    _add_generic_handlers(self._state, generic_rpc_handlers)
+    def add_generic_rpc_handlers(self, generic_rpc_handlers):
+        _add_generic_handlers(self._state, generic_rpc_handlers)
 
-  def add_insecure_port(self, address):
-    return _add_insecure_port(self._state, _common.encode(address))
+    def add_insecure_port(self, address):
+        return _add_insecure_port(self._state, _common.encode(address))
 
-  def add_secure_port(self, address, server_credentials):
-    return _add_secure_port(self._state, _common.encode(address), server_credentials)
+    def add_secure_port(self, address, server_credentials):
+        return _add_secure_port(self._state,
+                                _common.encode(address), server_credentials)
 
-  def start(self):
-    _start(self._state)
+    def start(self):
+        _start(self._state)
 
-  def stop(self, grace):
-    return _stop(self._state, grace)
+    def stop(self, grace):
+        return _stop(self._state, grace)
 
-  def __del__(self):
-    _stop(self._state, None)
+    def __del__(self):
+        _stop(self._state, None)
diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py
index a375896e6e..7c602eb37e 100644
--- a/src/python/grpcio/grpc/_utilities.py
+++ b/src/python/grpcio/grpc/_utilities.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Internal utilities for gRPC Python."""
 
 import collections
@@ -44,132 +43,136 @@ _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
 
 
 class RpcMethodHandler(
-    collections.namedtuple(
-        '_RpcMethodHandler',
-        ('request_streaming', 'response_streaming', 'request_deserializer',
-         'response_serializer', 'unary_unary', 'unary_stream', 'stream_unary',
-         'stream_stream',)),
-    grpc.RpcMethodHandler):
-  pass
+        collections.namedtuple('_RpcMethodHandler', (
+            'request_streaming',
+            'response_streaming',
+            'request_deserializer',
+            'response_serializer',
+            'unary_unary',
+            'unary_stream',
+            'stream_unary',
+            'stream_stream',)), grpc.RpcMethodHandler):
+    pass
 
 
 class DictionaryGenericHandler(grpc.ServiceRpcHandler):
 
-  def __init__(self, service, method_handlers):
-    self._name = service
-    self._method_handlers = {
-        _common.fully_qualified_method(service, method): method_handler
-        for method, method_handler in six.iteritems(method_handlers)}
+    def __init__(self, service, method_handlers):
+        self._name = service
+        self._method_handlers = {
+            _common.fully_qualified_method(service, method): method_handler
+            for method, method_handler in six.iteritems(method_handlers)
+        }
 
-  def service_name(self):
-    return self._name
+    def service_name(self):
+        return self._name
 
-  def service(self, handler_call_details):
-    return self._method_handlers.get(handler_call_details.method)
+    def service(self, handler_call_details):
+        return self._method_handlers.get(handler_call_details.method)
 
 
 class _ChannelReadyFuture(grpc.Future):
 
-  def __init__(self, channel):
-    self._condition = threading.Condition()
-    self._channel = channel
-
-    self._matured = False
-    self._cancelled = False
-    self._done_callbacks = []
-
-  def _block(self, timeout):
-    until = None if timeout is None else time.time() + timeout
-    with self._condition:
-      while True:
-        if self._cancelled:
-          raise grpc.FutureCancelledError()
-        elif self._matured:
-          return
-        else:
-          if until is None:
-            self._condition.wait()
-          else:
-            remaining = until - time.time()
-            if remaining < 0:
-              raise grpc.FutureTimeoutError()
+    def __init__(self, channel):
+        self._condition = threading.Condition()
+        self._channel = channel
+
+        self._matured = False
+        self._cancelled = False
+        self._done_callbacks = []
+
+    def _block(self, timeout):
+        until = None if timeout is None else time.time() + timeout
+        with self._condition:
+            while True:
+                if self._cancelled:
+                    raise grpc.FutureCancelledError()
+                elif self._matured:
+                    return
+                else:
+                    if until is None:
+                        self._condition.wait()
+                    else:
+                        remaining = until - time.time()
+                        if remaining < 0:
+                            raise grpc.FutureTimeoutError()
+                        else:
+                            self._condition.wait(timeout=remaining)
+
+    def _update(self, connectivity):
+        with self._condition:
+            if (not self._cancelled and
+                    connectivity is grpc.ChannelConnectivity.READY):
+                self._matured = True
+                self._channel.unsubscribe(self._update)
+                self._condition.notify_all()
+                done_callbacks = tuple(self._done_callbacks)
+                self._done_callbacks = None
+            else:
+                return
+
+        for done_callback in done_callbacks:
+            callable_util.call_logging_exceptions(
+                done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+    def cancel(self):
+        with self._condition:
+            if not self._matured:
+                self._cancelled = True
+                self._channel.unsubscribe(self._update)
+                self._condition.notify_all()
+                done_callbacks = tuple(self._done_callbacks)
+                self._done_callbacks = None
             else:
-              self._condition.wait(timeout=remaining)
-
-  def _update(self, connectivity):
-    with self._condition:
-      if (not self._cancelled and
-          connectivity is grpc.ChannelConnectivity.READY):
-        self._matured = True
-        self._channel.unsubscribe(self._update)
-        self._condition.notify_all()
-        done_callbacks = tuple(self._done_callbacks)
-        self._done_callbacks = None
-      else:
-        return
-
-    for done_callback in done_callbacks:
-      callable_util.call_logging_exceptions(
-          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
-  def cancel(self):
-    with self._condition:
-      if not self._matured:
-        self._cancelled = True
-        self._channel.unsubscribe(self._update)
-        self._condition.notify_all()
-        done_callbacks = tuple(self._done_callbacks)
-        self._done_callbacks = None
-      else:
-        return False
-
-    for done_callback in done_callbacks:
-      callable_util.call_logging_exceptions(
-          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
-  def cancelled(self):
-    with self._condition:
-      return self._cancelled
-
-  def running(self):
-    with self._condition:
-      return not self._cancelled and not self._matured
-
-  def done(self):
-    with self._condition:
-      return self._cancelled or self._matured
-
-  def result(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def exception(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def traceback(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def add_done_callback(self, fn):
-    with self._condition:
-      if not self._cancelled and not self._matured:
-        self._done_callbacks.append(fn)
-        return
-
-    fn(self)
-
-  def start(self):
-    with self._condition:
-      self._channel.subscribe(self._update, try_to_connect=True)
-
-  def __del__(self):
-    with self._condition:
-      if not self._cancelled and not self._matured:
-        self._channel.unsubscribe(self._update)
+                return False
+
+        for done_callback in done_callbacks:
+            callable_util.call_logging_exceptions(
+                done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+    def cancelled(self):
+        with self._condition:
+            return self._cancelled
+
+    def running(self):
+        with self._condition:
+            return not self._cancelled and not self._matured
+
+    def done(self):
+        with self._condition:
+            return self._cancelled or self._matured
+
+    def result(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def exception(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def traceback(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def add_done_callback(self, fn):
+        with self._condition:
+            if not self._cancelled and not self._matured:
+                self._done_callbacks.append(fn)
+                return
+
+        fn(self)
+
+    def start(self):
+        with self._condition:
+            self._channel.subscribe(self._update, try_to_connect=True)
+
+    def __del__(self):
+        with self._condition:
+            if not self._cancelled and not self._matured:
+                self._channel.unsubscribe(self._update)
 
 
 def channel_ready_future(channel):
-  ready_future = _ChannelReadyFuture(channel)
-  ready_future.start()
-  return ready_future
+    ready_future = _ChannelReadyFuture(channel)
+    ready_future.start()
+    return ready_future
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
index e4ee44d7a3..e5b28e9408 100644
--- a/src/python/grpcio/grpc/beta/_client_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Translates gRPC's client-side API into gRPC's client-side Beta API."""
 
 import grpc
@@ -38,531 +37,654 @@ from grpc.framework.foundation import future
 from grpc.framework.interfaces.face import face
 
 _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
-    grpc.StatusCode.CANCELLED: (
-        face.Abortion.Kind.CANCELLED, face.CancellationError),
-    grpc.StatusCode.UNKNOWN: (
-        face.Abortion.Kind.REMOTE_FAILURE, face.RemoteError),
-    grpc.StatusCode.DEADLINE_EXCEEDED: (
-        face.Abortion.Kind.EXPIRED, face.ExpirationError),
-    grpc.StatusCode.UNIMPLEMENTED: (
-        face.Abortion.Kind.LOCAL_FAILURE, face.LocalError),
+    grpc.StatusCode.CANCELLED: (face.Abortion.Kind.CANCELLED,
+                                face.CancellationError),
+    grpc.StatusCode.UNKNOWN: (face.Abortion.Kind.REMOTE_FAILURE,
+                              face.RemoteError),
+    grpc.StatusCode.DEADLINE_EXCEEDED: (face.Abortion.Kind.EXPIRED,
+                                        face.ExpirationError),
+    grpc.StatusCode.UNIMPLEMENTED: (face.Abortion.Kind.LOCAL_FAILURE,
+                                    face.LocalError),
 }
 
 
 def _effective_metadata(metadata, metadata_transformer):
-  non_none_metadata = () if metadata is None else metadata
-  if metadata_transformer is None:
-    return non_none_metadata
-  else:
-    return metadata_transformer(non_none_metadata)
+    non_none_metadata = () if metadata is None else metadata
+    if metadata_transformer is None:
+        return non_none_metadata
+    else:
+        return metadata_transformer(non_none_metadata)
 
 
 def _credentials(grpc_call_options):
-  return None if grpc_call_options is None else grpc_call_options.credentials
+    return None if grpc_call_options is None else grpc_call_options.credentials
 
 
 def _abortion(rpc_error_call):
-  code = rpc_error_call.code()
-  pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
-  error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
-  return face.Abortion(
-      error_kind, rpc_error_call.initial_metadata(),
-      rpc_error_call.trailing_metadata(), code, rpc_error_call.details())
+    code = rpc_error_call.code()
+    pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+    error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
+    return face.Abortion(error_kind,
+                         rpc_error_call.initial_metadata(),
+                         rpc_error_call.trailing_metadata(), code,
+                         rpc_error_call.details())
 
 
 def _abortion_error(rpc_error_call):
-  code = rpc_error_call.code()
-  pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
-  exception_class = face.AbortionError if pair is None else pair[1]
-  return exception_class(
-      rpc_error_call.initial_metadata(), rpc_error_call.trailing_metadata(),
-      code, rpc_error_call.details())
+    code = rpc_error_call.code()
+    pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+    exception_class = face.AbortionError if pair is None else pair[1]
+    return exception_class(rpc_error_call.initial_metadata(),
+                           rpc_error_call.trailing_metadata(), code,
+                           rpc_error_call.details())
 
 
 class _InvocationProtocolContext(interfaces.GRPCInvocationContext):
 
-  def disable_next_request_compression(self):
-    pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+    def disable_next_request_compression(self):
+        pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
 
 
 class _Rendezvous(future.Future, face.Call):
 
-  def __init__(self, response_future, response_iterator, call):
-    self._future = response_future
-    self._iterator = response_iterator
-    self._call = call
+    def __init__(self, response_future, response_iterator, call):
+        self._future = response_future
+        self._iterator = response_iterator
+        self._call = call
 
-  def cancel(self):
-    return self._call.cancel()
+    def cancel(self):
+        return self._call.cancel()
 
-  def cancelled(self):
-    return self._future.cancelled()
+    def cancelled(self):
+        return self._future.cancelled()
 
-  def running(self):
-    return self._future.running()
+    def running(self):
+        return self._future.running()
 
-  def done(self):
-    return self._future.done()
+    def done(self):
+        return self._future.done()
 
-  def result(self, timeout=None):
-    try:
-      return self._future.result(timeout=timeout)
-    except grpc.RpcError as rpc_error_call:
-      raise _abortion_error(rpc_error_call)
-    except grpc.FutureTimeoutError:
-      raise future.TimeoutError()
-    except grpc.FutureCancelledError:
-      raise future.CancelledError()
+    def result(self, timeout=None):
+        try:
+            return self._future.result(timeout=timeout)
+        except grpc.RpcError as rpc_error_call:
+            raise _abortion_error(rpc_error_call)
+        except grpc.FutureTimeoutError:
+            raise future.TimeoutError()
+        except grpc.FutureCancelledError:
+            raise future.CancelledError()
 
-  def exception(self, timeout=None):
-    try:
-      rpc_error_call = self._future.exception(timeout=timeout)
-      if rpc_error_call is None:
-        return None
-      else:
-        return _abortion_error(rpc_error_call)
-    except grpc.FutureTimeoutError:
-      raise future.TimeoutError()
-    except grpc.FutureCancelledError:
-      raise future.CancelledError()
-
-  def traceback(self, timeout=None):
-    try:
-      return self._future.traceback(timeout=timeout)
-    except grpc.FutureTimeoutError:
-      raise future.TimeoutError()
-    except grpc.FutureCancelledError:
-      raise future.CancelledError()
+    def exception(self, timeout=None):
+        try:
+            rpc_error_call = self._future.exception(timeout=timeout)
+            if rpc_error_call is None:
+                return None
+            else:
+                return _abortion_error(rpc_error_call)
+        except grpc.FutureTimeoutError:
+            raise future.TimeoutError()
+        except grpc.FutureCancelledError:
+            raise future.CancelledError()
 
-  def add_done_callback(self, fn):
-    self._future.add_done_callback(lambda ignored_callback: fn(self))
+    def traceback(self, timeout=None):
+        try:
+            return self._future.traceback(timeout=timeout)
+        except grpc.FutureTimeoutError:
+            raise future.TimeoutError()
+        except grpc.FutureCancelledError:
+            raise future.CancelledError()
 
-  def __iter__(self):
-    return self
+    def add_done_callback(self, fn):
+        self._future.add_done_callback(lambda ignored_callback: fn(self))
 
-  def _next(self):
-    try:
-      return next(self._iterator)
-    except grpc.RpcError as rpc_error_call:
-      raise _abortion_error(rpc_error_call)
+    def __iter__(self):
+        return self
+
+    def _next(self):
+        try:
+            return next(self._iterator)
+        except grpc.RpcError as rpc_error_call:
+            raise _abortion_error(rpc_error_call)
+
+    def __next__(self):
+        return self._next()
 
-  def __next__(self):
-    return self._next()
+    def next(self):
+        return self._next()
 
-  def next(self):
-    return self._next()
+    def is_active(self):
+        return self._call.is_active()
 
-  def is_active(self):
-    return self._call.is_active()
+    def time_remaining(self):
+        return self._call.time_remaining()
 
-  def time_remaining(self):
-    return self._call.time_remaining()
+    def add_abortion_callback(self, abortion_callback):
 
-  def add_abortion_callback(self, abortion_callback):
-    def done_callback():
-      if self.code() is not grpc.StatusCode.OK:
-        abortion_callback(_abortion(self._call))
-    registered = self._call.add_callback(done_callback)
-    return None if registered else done_callback()
+        def done_callback():
+            if self.code() is not grpc.StatusCode.OK:
+                abortion_callback(_abortion(self._call))
 
-  def protocol_context(self):
-    return _InvocationProtocolContext()
+        registered = self._call.add_callback(done_callback)
+        return None if registered else done_callback()
 
-  def initial_metadata(self):
-    return self._call.initial_metadata()
+    def protocol_context(self):
+        return _InvocationProtocolContext()
 
-  def terminal_metadata(self):
-    return self._call.terminal_metadata()
+    def initial_metadata(self):
+        return self._call.initial_metadata()
 
-  def code(self):
-    return self._call.code()
+    def terminal_metadata(self):
+        return self._call.terminal_metadata()
 
-  def details(self):
-    return self._call.details()
+    def code(self):
+        return self._call.code()
 
+    def details(self):
+        return self._call.details()
 
-def _blocking_unary_unary(
-    channel, group, method, timeout, with_call, protocol_options, metadata,
-    metadata_transformer, request, request_serializer, response_deserializer):
-  try:
+
+def _blocking_unary_unary(channel, group, method, timeout, with_call,
+                          protocol_options, metadata, metadata_transformer,
+                          request, request_serializer, response_deserializer):
+    try:
+        multi_callable = channel.unary_unary(
+            _common.fully_qualified_method(group, method),
+            request_serializer=request_serializer,
+            response_deserializer=response_deserializer)
+        effective_metadata = _effective_metadata(metadata, metadata_transformer)
+        if with_call:
+            response, call = multi_callable.with_call(
+                request,
+                timeout=timeout,
+                metadata=effective_metadata,
+                credentials=_credentials(protocol_options))
+            return response, _Rendezvous(None, None, call)
+        else:
+            return multi_callable(
+                request,
+                timeout=timeout,
+                metadata=effective_metadata,
+                credentials=_credentials(protocol_options))
+    except grpc.RpcError as rpc_error_call:
+        raise _abortion_error(rpc_error_call)
+
+
+def _future_unary_unary(channel, group, method, timeout, protocol_options,
+                        metadata, metadata_transformer, request,
+                        request_serializer, response_deserializer):
     multi_callable = channel.unary_unary(
         _common.fully_qualified_method(group, method),
         request_serializer=request_serializer,
         response_deserializer=response_deserializer)
     effective_metadata = _effective_metadata(metadata, metadata_transformer)
-    if with_call:
-      response, call = multi_callable.with_call(
-          request, timeout=timeout, metadata=effective_metadata,
-          credentials=_credentials(protocol_options))
-      return response, _Rendezvous(None, None, call)
-    else:
-      return multi_callable(
-          request, timeout=timeout, metadata=effective_metadata,
-          credentials=_credentials(protocol_options))
-  except grpc.RpcError as rpc_error_call:
-    raise _abortion_error(rpc_error_call)
-
-
-def _future_unary_unary(
-    channel, group, method, timeout, protocol_options, metadata,
-    metadata_transformer, request, request_serializer, response_deserializer):
-  multi_callable = channel.unary_unary(
-      _common.fully_qualified_method(group, method),
-      request_serializer=request_serializer,
-      response_deserializer=response_deserializer)
-  effective_metadata = _effective_metadata(metadata, metadata_transformer)
-  response_future = multi_callable.future(
-      request, timeout=timeout, metadata=effective_metadata,
-      credentials=_credentials(protocol_options))
-  return _Rendezvous(response_future, None, response_future)
-
-
-def _unary_stream(
-    channel, group, method, timeout, protocol_options, metadata,
-    metadata_transformer, request, request_serializer, response_deserializer):
-  multi_callable = channel.unary_stream(
-      _common.fully_qualified_method(group, method),
-      request_serializer=request_serializer,
-      response_deserializer=response_deserializer)
-  effective_metadata = _effective_metadata(metadata, metadata_transformer)
-  response_iterator = multi_callable(
-      request, timeout=timeout, metadata=effective_metadata,
-      credentials=_credentials(protocol_options))
-  return _Rendezvous(None, response_iterator, response_iterator)
-
-
-def _blocking_stream_unary(
-    channel, group, method, timeout, with_call, protocol_options, metadata,
-    metadata_transformer, request_iterator, request_serializer,
-    response_deserializer):
-  try:
+    response_future = multi_callable.future(
+        request,
+        timeout=timeout,
+        metadata=effective_metadata,
+        credentials=_credentials(protocol_options))
+    return _Rendezvous(response_future, None, response_future)
+
+
+def _unary_stream(channel, group, method, timeout, protocol_options, metadata,
+                  metadata_transformer, request, request_serializer,
+                  response_deserializer):
+    multi_callable = channel.unary_stream(
+        _common.fully_qualified_method(group, method),
+        request_serializer=request_serializer,
+        response_deserializer=response_deserializer)
+    effective_metadata = _effective_metadata(metadata, metadata_transformer)
+    response_iterator = multi_callable(
+        request,
+        timeout=timeout,
+        metadata=effective_metadata,
+        credentials=_credentials(protocol_options))
+    return _Rendezvous(None, response_iterator, response_iterator)
+
+
+def _blocking_stream_unary(channel, group, method, timeout, with_call,
+                           protocol_options, metadata, metadata_transformer,
+                           request_iterator, request_serializer,
+                           response_deserializer):
+    try:
+        multi_callable = channel.stream_unary(
+            _common.fully_qualified_method(group, method),
+            request_serializer=request_serializer,
+            response_deserializer=response_deserializer)
+        effective_metadata = _effective_metadata(metadata, metadata_transformer)
+        if with_call:
+            response, call = multi_callable.with_call(
+                request_iterator,
+                timeout=timeout,
+                metadata=effective_metadata,
+                credentials=_credentials(protocol_options))
+            return response, _Rendezvous(None, None, call)
+        else:
+            return multi_callable(
+                request_iterator,
+                timeout=timeout,
+                metadata=effective_metadata,
+                credentials=_credentials(protocol_options))
+    except grpc.RpcError as rpc_error_call:
+        raise _abortion_error(rpc_error_call)
+
+
+def _future_stream_unary(channel, group, method, timeout, protocol_options,
+                         metadata, metadata_transformer, request_iterator,
+                         request_serializer, response_deserializer):
     multi_callable = channel.stream_unary(
         _common.fully_qualified_method(group, method),
         request_serializer=request_serializer,
         response_deserializer=response_deserializer)
     effective_metadata = _effective_metadata(metadata, metadata_transformer)
-    if with_call:
-      response, call = multi_callable.with_call(
-          request_iterator, timeout=timeout, metadata=effective_metadata,
-          credentials=_credentials(protocol_options))
-      return response, _Rendezvous(None, None, call)
-    else:
-      return multi_callable(
-          request_iterator, timeout=timeout, metadata=effective_metadata,
-          credentials=_credentials(protocol_options))
-  except grpc.RpcError as rpc_error_call:
-    raise _abortion_error(rpc_error_call)
-
-
-def _future_stream_unary(
-    channel, group, method, timeout, protocol_options, metadata,
-    metadata_transformer, request_iterator, request_serializer,
-    response_deserializer):
-  multi_callable = channel.stream_unary(
-      _common.fully_qualified_method(group, method),
-      request_serializer=request_serializer,
-      response_deserializer=response_deserializer)
-  effective_metadata = _effective_metadata(metadata, metadata_transformer)
-  response_future = multi_callable.future(
-      request_iterator, timeout=timeout, metadata=effective_metadata,
-      credentials=_credentials(protocol_options))
-  return _Rendezvous(response_future, None, response_future)
-
-
-def _stream_stream(
-    channel, group, method, timeout, protocol_options, metadata,
-    metadata_transformer, request_iterator, request_serializer,
-    response_deserializer):
-  multi_callable = channel.stream_stream(
-      _common.fully_qualified_method(group, method),
-      request_serializer=request_serializer,
-      response_deserializer=response_deserializer)
-  effective_metadata = _effective_metadata(metadata, metadata_transformer)
-  response_iterator = multi_callable(
-      request_iterator, timeout=timeout, metadata=effective_metadata,
-      credentials=_credentials(protocol_options))
-  return _Rendezvous(None, response_iterator, response_iterator)
+    response_future = multi_callable.future(
+        request_iterator,
+        timeout=timeout,
+        metadata=effective_metadata,
+        credentials=_credentials(protocol_options))
+    return _Rendezvous(response_future, None, response_future)
+
+
+def _stream_stream(channel, group, method, timeout, protocol_options, metadata,
+                   metadata_transformer, request_iterator, request_serializer,
+                   response_deserializer):
+    multi_callable = channel.stream_stream(
+        _common.fully_qualified_method(group, method),
+        request_serializer=request_serializer,
+        response_deserializer=response_deserializer)
+    effective_metadata = _effective_metadata(metadata, metadata_transformer)
+    response_iterator = multi_callable(
+        request_iterator,
+        timeout=timeout,
+        metadata=effective_metadata,
+        credentials=_credentials(protocol_options))
+    return _Rendezvous(None, response_iterator, response_iterator)
 
 
 class _UnaryUnaryMultiCallable(face.UnaryUnaryMultiCallable):
 
-  def __init__(
-      self, channel, group, method, metadata_transformer, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._group = group
-    self._method = method
-    self._metadata_transformer = metadata_transformer
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(
-      self, request, timeout, metadata=None, with_call=False,
-      protocol_options=None):
-    return _blocking_unary_unary(
-        self._channel, self._group, self._method, timeout, with_call,
-        protocol_options, metadata, self._metadata_transformer, request,
-        self._request_serializer, self._response_deserializer)
-
-  def future(self, request, timeout, metadata=None, protocol_options=None):
-    return _future_unary_unary(
-        self._channel, self._group, self._method, timeout, protocol_options,
-        metadata, self._metadata_transformer, request, self._request_serializer,
-        self._response_deserializer)
-
-  def event(
-      self, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
+    def __init__(self, channel, group, method, metadata_transformer,
+                 request_serializer, response_deserializer):
+        self._channel = channel
+        self._group = group
+        self._method = method
+        self._metadata_transformer = metadata_transformer
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self,
+                 request,
+                 timeout,
+                 metadata=None,
+                 with_call=False,
+                 protocol_options=None):
+        return _blocking_unary_unary(
+            self._channel, self._group, self._method, timeout, with_call,
+            protocol_options, metadata, self._metadata_transformer, request,
+            self._request_serializer, self._response_deserializer)
+
+    def future(self, request, timeout, metadata=None, protocol_options=None):
+        return _future_unary_unary(
+            self._channel, self._group, self._method, timeout, protocol_options,
+            metadata, self._metadata_transformer, request,
+            self._request_serializer, self._response_deserializer)
+
+    def event(self,
+              request,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        raise NotImplementedError()
 
 
 class _UnaryStreamMultiCallable(face.UnaryStreamMultiCallable):
 
-  def __init__(
-      self, channel, group, method, metadata_transformer, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._group = group
-    self._method = method
-    self._metadata_transformer = metadata_transformer
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(self, request, timeout, metadata=None, protocol_options=None):
-    return _unary_stream(
-        self._channel, self._group, self._method, timeout, protocol_options,
-        metadata, self._metadata_transformer, request, self._request_serializer,
-        self._response_deserializer)
-
-  def event(
-      self, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
+    def __init__(self, channel, group, method, metadata_transformer,
+                 request_serializer, response_deserializer):
+        self._channel = channel
+        self._group = group
+        self._method = method
+        self._metadata_transformer = metadata_transformer
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self, request, timeout, metadata=None, protocol_options=None):
+        return _unary_stream(
+            self._channel, self._group, self._method, timeout, protocol_options,
+            metadata, self._metadata_transformer, request,
+            self._request_serializer, self._response_deserializer)
+
+    def event(self,
+              request,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        raise NotImplementedError()
 
 
 class _StreamUnaryMultiCallable(face.StreamUnaryMultiCallable):
 
-  def __init__(
-      self, channel, group, method, metadata_transformer, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._group = group
-    self._method = method
-    self._metadata_transformer = metadata_transformer
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(
-      self, request_iterator, timeout, metadata=None, with_call=False,
-      protocol_options=None):
-    return _blocking_stream_unary(
-        self._channel, self._group, self._method, timeout, with_call,
-        protocol_options, metadata, self._metadata_transformer,
-        request_iterator, self._request_serializer, self._response_deserializer)
-
-  def future(
-      self, request_iterator, timeout, metadata=None, protocol_options=None):
-    return _future_stream_unary(
-        self._channel, self._group, self._method, timeout, protocol_options,
-        metadata, self._metadata_transformer, request_iterator,
-        self._request_serializer, self._response_deserializer)
-
-  def event(
-      self, receiver, abortion_callback, timeout, metadata=None,
-      protocol_options=None):
-    raise NotImplementedError()
+    def __init__(self, channel, group, method, metadata_transformer,
+                 request_serializer, response_deserializer):
+        self._channel = channel
+        self._group = group
+        self._method = method
+        self._metadata_transformer = metadata_transformer
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self,
+                 request_iterator,
+                 timeout,
+                 metadata=None,
+                 with_call=False,
+                 protocol_options=None):
+        return _blocking_stream_unary(
+            self._channel, self._group, self._method, timeout, with_call,
+            protocol_options, metadata, self._metadata_transformer,
+            request_iterator, self._request_serializer,
+            self._response_deserializer)
+
+    def future(self,
+               request_iterator,
+               timeout,
+               metadata=None,
+               protocol_options=None):
+        return _future_stream_unary(
+            self._channel, self._group, self._method, timeout, protocol_options,
+            metadata, self._metadata_transformer, request_iterator,
+            self._request_serializer, self._response_deserializer)
+
+    def event(self,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        raise NotImplementedError()
 
 
 class _StreamStreamMultiCallable(face.StreamStreamMultiCallable):
 
-  def __init__(
-      self, channel, group, method, metadata_transformer, request_serializer,
-      response_deserializer):
-    self._channel = channel
-    self._group = group
-    self._method = method
-    self._metadata_transformer = metadata_transformer
-    self._request_serializer = request_serializer
-    self._response_deserializer = response_deserializer
-
-  def __call__(
-      self, request_iterator, timeout, metadata=None, protocol_options=None):
-    return _stream_stream(
-        self._channel, self._group, self._method, timeout, protocol_options,
-        metadata, self._metadata_transformer, request_iterator,
-        self._request_serializer, self._response_deserializer)
-
-  def event(
-      self, receiver, abortion_callback, timeout, metadata=None,
-      protocol_options=None):
-    raise NotImplementedError()
+    def __init__(self, channel, group, method, metadata_transformer,
+                 request_serializer, response_deserializer):
+        self._channel = channel
+        self._group = group
+        self._method = method
+        self._metadata_transformer = metadata_transformer
+        self._request_serializer = request_serializer
+        self._response_deserializer = response_deserializer
+
+    def __call__(self,
+                 request_iterator,
+                 timeout,
+                 metadata=None,
+                 protocol_options=None):
+        return _stream_stream(
+            self._channel, self._group, self._method, timeout, protocol_options,
+            metadata, self._metadata_transformer, request_iterator,
+            self._request_serializer, self._response_deserializer)
+
+    def event(self,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        raise NotImplementedError()
 
 
 class _GenericStub(face.GenericStub):
 
-  def __init__(
-      self, channel, metadata_transformer, request_serializers,
-      response_deserializers):
-    self._channel = channel
-    self._metadata_transformer = metadata_transformer
-    self._request_serializers = request_serializers or {}
-    self._response_deserializers = response_deserializers or {}
-
-  def blocking_unary_unary(
-      self, group, method, request, timeout, metadata=None,
-      with_call=None, protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _blocking_unary_unary(
-        self._channel, group, method, timeout, with_call, protocol_options,
-        metadata, self._metadata_transformer, request, request_serializer,
-        response_deserializer)
-
-  def future_unary_unary(
-      self, group, method, request, timeout, metadata=None,
-      protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _future_unary_unary(
-        self._channel, group, method, timeout, protocol_options, metadata,
-        self._metadata_transformer, request, request_serializer,
-        response_deserializer)
-
-  def inline_unary_stream(
-      self, group, method, request, timeout, metadata=None,
-      protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _unary_stream(
-        self._channel, group, method, timeout, protocol_options, metadata,
-        self._metadata_transformer, request, request_serializer,
-        response_deserializer)
-
-  def blocking_stream_unary(
-      self, group, method, request_iterator, timeout, metadata=None,
-      with_call=None, protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _blocking_stream_unary(
-        self._channel, group, method, timeout, with_call, protocol_options,
-        metadata, self._metadata_transformer, request_iterator,
-        request_serializer, response_deserializer)
-
-  def future_stream_unary(
-      self, group, method, request_iterator, timeout, metadata=None,
-      protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _future_stream_unary(
-        self._channel, group, method, timeout, protocol_options, metadata,
-        self._metadata_transformer, request_iterator, request_serializer,
-        response_deserializer)
-
-  def inline_stream_stream(
-      self, group, method, request_iterator, timeout, metadata=None,
-      protocol_options=None):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _stream_stream(
-        self._channel, group, method, timeout, protocol_options, metadata,
-        self._metadata_transformer, request_iterator, request_serializer,
-        response_deserializer)
-
-  def event_unary_unary(
-      self, group, method, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
-
-  def event_unary_stream(
-      self, group, method, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
-
-  def event_stream_unary(
-      self, group, method, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
-
-  def event_stream_stream(
-      self, group, method, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    raise NotImplementedError()
-
-  def unary_unary(self, group, method):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _UnaryUnaryMultiCallable(
-        self._channel, group, method, self._metadata_transformer,
-        request_serializer, response_deserializer)
-
-  def unary_stream(self, group, method):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _UnaryStreamMultiCallable(
-        self._channel, group, method, self._metadata_transformer,
-        request_serializer, response_deserializer)
-
-  def stream_unary(self, group, method):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _StreamUnaryMultiCallable(
-        self._channel, group, method, self._metadata_transformer,
-        request_serializer, response_deserializer)
-
-  def stream_stream(self, group, method):
-    request_serializer = self._request_serializers.get((group, method,))
-    response_deserializer = self._response_deserializers.get((group, method,))
-    return _StreamStreamMultiCallable(
-        self._channel, group, method, self._metadata_transformer,
-        request_serializer, response_deserializer)
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, exc_type, exc_val, exc_tb):
-    return False
+    def __init__(self, channel, metadata_transformer, request_serializers,
+                 response_deserializers):
+        self._channel = channel
+        self._metadata_transformer = metadata_transformer
+        self._request_serializers = request_serializers or {}
+        self._response_deserializers = response_deserializers or {}
+
+    def blocking_unary_unary(self,
+                             group,
+                             method,
+                             request,
+                             timeout,
+                             metadata=None,
+                             with_call=None,
+                             protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _blocking_unary_unary(self._channel, group, method, timeout,
+                                     with_call, protocol_options, metadata,
+                                     self._metadata_transformer, request,
+                                     request_serializer, response_deserializer)
+
+    def future_unary_unary(self,
+                           group,
+                           method,
+                           request,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _future_unary_unary(self._channel, group, method, timeout,
+                                   protocol_options, metadata,
+                                   self._metadata_transformer, request,
+                                   request_serializer, response_deserializer)
+
+    def inline_unary_stream(self,
+                            group,
+                            method,
+                            request,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _unary_stream(self._channel, group, method, timeout,
+                             protocol_options, metadata,
+                             self._metadata_transformer, request,
+                             request_serializer, response_deserializer)
+
+    def blocking_stream_unary(self,
+                              group,
+                              method,
+                              request_iterator,
+                              timeout,
+                              metadata=None,
+                              with_call=None,
+                              protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _blocking_stream_unary(
+            self._channel, group, method, timeout, with_call, protocol_options,
+            metadata, self._metadata_transformer, request_iterator,
+            request_serializer, response_deserializer)
+
+    def future_stream_unary(self,
+                            group,
+                            method,
+                            request_iterator,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _future_stream_unary(
+            self._channel, group, method, timeout, protocol_options, metadata,
+            self._metadata_transformer, request_iterator, request_serializer,
+            response_deserializer)
+
+    def inline_stream_stream(self,
+                             group,
+                             method,
+                             request_iterator,
+                             timeout,
+                             metadata=None,
+                             protocol_options=None):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _stream_stream(self._channel, group, method, timeout,
+                              protocol_options, metadata,
+                              self._metadata_transformer, request_iterator,
+                              request_serializer, response_deserializer)
+
+    def event_unary_unary(self,
+                          group,
+                          method,
+                          request,
+                          receiver,
+                          abortion_callback,
+                          timeout,
+                          metadata=None,
+                          protocol_options=None):
+        raise NotImplementedError()
+
+    def event_unary_stream(self,
+                           group,
+                           method,
+                           request,
+                           receiver,
+                           abortion_callback,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        raise NotImplementedError()
+
+    def event_stream_unary(self,
+                           group,
+                           method,
+                           receiver,
+                           abortion_callback,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        raise NotImplementedError()
+
+    def event_stream_stream(self,
+                            group,
+                            method,
+                            receiver,
+                            abortion_callback,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        raise NotImplementedError()
+
+    def unary_unary(self, group, method):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _UnaryUnaryMultiCallable(
+            self._channel, group, method, self._metadata_transformer,
+            request_serializer, response_deserializer)
+
+    def unary_stream(self, group, method):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _UnaryStreamMultiCallable(
+            self._channel, group, method, self._metadata_transformer,
+            request_serializer, response_deserializer)
+
+    def stream_unary(self, group, method):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _StreamUnaryMultiCallable(
+            self._channel, group, method, self._metadata_transformer,
+            request_serializer, response_deserializer)
+
+    def stream_stream(self, group, method):
+        request_serializer = self._request_serializers.get((
+            group,
+            method,))
+        response_deserializer = self._response_deserializers.get((
+            group,
+            method,))
+        return _StreamStreamMultiCallable(
+            self._channel, group, method, self._metadata_transformer,
+            request_serializer, response_deserializer)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        return False
 
 
 class _DynamicStub(face.DynamicStub):
 
-  def __init__(self, generic_stub, group, cardinalities):
-    self._generic_stub = generic_stub
-    self._group = group
-    self._cardinalities = cardinalities
-
-  def __getattr__(self, attr):
-    method_cardinality = self._cardinalities.get(attr)
-    if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
-      return self._generic_stub.unary_unary(self._group, attr)
-    elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
-      return self._generic_stub.unary_stream(self._group, attr)
-    elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
-      return self._generic_stub.stream_unary(self._group, attr)
-    elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
-      return self._generic_stub.stream_stream(self._group, attr)
-    else:
-      raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, exc_type, exc_val, exc_tb):
-    return False
-
-
-def generic_stub(
-    channel, host, metadata_transformer, request_serializers,
-    response_deserializers):
-  return _GenericStub(
-      channel, metadata_transformer, request_serializers,
-      response_deserializers)
-
-
-def dynamic_stub(
-    channel, service, cardinalities, host, metadata_transformer,
-    request_serializers, response_deserializers):
-  return _DynamicStub(
-      _GenericStub(
-          channel, metadata_transformer, request_serializers,
-          response_deserializers),
-      service, cardinalities)
+    def __init__(self, generic_stub, group, cardinalities):
+        self._generic_stub = generic_stub
+        self._group = group
+        self._cardinalities = cardinalities
+
+    def __getattr__(self, attr):
+        method_cardinality = self._cardinalities.get(attr)
+        if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
+            return self._generic_stub.unary_unary(self._group, attr)
+        elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
+            return self._generic_stub.unary_stream(self._group, attr)
+        elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
+            return self._generic_stub.stream_unary(self._group, attr)
+        elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
+            return self._generic_stub.stream_stream(self._group, attr)
+        else:
+            raise AttributeError('_DynamicStub object has no attribute "%s"!' %
+                                 attr)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        return False
+
+
+def generic_stub(channel, host, metadata_transformer, request_serializers,
+                 response_deserializers):
+    return _GenericStub(channel, metadata_transformer, request_serializers,
+                        response_deserializers)
+
+
+def dynamic_stub(channel, service, cardinalities, host, metadata_transformer,
+                 request_serializers, response_deserializers):
+    return _DynamicStub(
+        _GenericStub(channel, metadata_transformer, request_serializers,
+                     response_deserializers), service, cardinalities)
diff --git a/src/python/grpcio/grpc/beta/_connectivity_channel.py b/src/python/grpcio/grpc/beta/_connectivity_channel.py
index 61674a70ad..39020d2b4e 100644
--- a/src/python/grpcio/grpc/beta/_connectivity_channel.py
+++ b/src/python/grpcio/grpc/beta/_connectivity_channel.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Affords a connectivity-state-listenable channel."""
 
 import threading
@@ -41,116 +40,122 @@ _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
     'Exception calling channel subscription callback!')
 
 _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
-    state: connectivity for state, connectivity in zip(
-        _types.ConnectivityState, interfaces.ChannelConnectivity)
+    state: connectivity
+    for state, connectivity in zip(_types.ConnectivityState,
+                                   interfaces.ChannelConnectivity)
 }
 
 
 class ConnectivityChannel(object):
 
-  def __init__(self, low_channel):
-    self._lock = threading.Lock()
-    self._low_channel = low_channel
-
-    self._polling = False
-    self._connectivity = None
-    self._try_to_connect = False
-    self._callbacks_and_connectivities = []
-    self._delivering = False
-
-  def _deliveries(self, connectivity):
-    callbacks_needing_update = []
-    for callback_and_connectivity in self._callbacks_and_connectivities:
-      callback, callback_connectivity = callback_and_connectivity
-      if callback_connectivity is not connectivity:
-        callbacks_needing_update.append(callback)
-        callback_and_connectivity[1] = connectivity
-    return callbacks_needing_update
-
-  def _deliver(self, initial_connectivity, initial_callbacks):
-    connectivity = initial_connectivity
-    callbacks = initial_callbacks
-    while True:
-      for callback in callbacks:
-        callable_util.call_logging_exceptions(
-            callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
-            connectivity)
-      with self._lock:
-        callbacks = self._deliveries(self._connectivity)
-        if callbacks:
-          connectivity = self._connectivity
-        else:
-          self._delivering = False
-          return
-
-  def _spawn_delivery(self, connectivity, callbacks):
-    delivering_thread = threading.Thread(
-        target=self._deliver, args=(connectivity, callbacks,))
-    delivering_thread.start()
-    self._delivering = True
+    def __init__(self, low_channel):
+        self._lock = threading.Lock()
+        self._low_channel = low_channel
 
-  # TODO(issue 3064): Don't poll.
-  def _poll_connectivity(self, low_channel, initial_try_to_connect):
-    try_to_connect = initial_try_to_connect
-    low_connectivity = low_channel.check_connectivity_state(try_to_connect)
-    with self._lock:
-      self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
-          low_connectivity]
-      callbacks = tuple(
-          callback for callback, unused_but_known_to_be_none_connectivity
-          in self._callbacks_and_connectivities)
-      for callback_and_connectivity in self._callbacks_and_connectivities:
-        callback_and_connectivity[1] = self._connectivity
-      if callbacks:
-        self._spawn_delivery(self._connectivity, callbacks)
-    completion_queue = _low.CompletionQueue()
-    while True:
-      low_channel.watch_connectivity_state(
-          low_connectivity, time.time() + 0.2, completion_queue, None)
-      event = completion_queue.next()
-      with self._lock:
-        if not self._callbacks_and_connectivities and not self._try_to_connect:
-          self._polling = False
-          self._connectivity = None
-          completion_queue.shutdown()
-          break
-        try_to_connect = self._try_to_connect
+        self._polling = False
+        self._connectivity = None
         self._try_to_connect = False
-      if event.success or try_to_connect:
+        self._callbacks_and_connectivities = []
+        self._delivering = False
+
+    def _deliveries(self, connectivity):
+        callbacks_needing_update = []
+        for callback_and_connectivity in self._callbacks_and_connectivities:
+            callback, callback_connectivity = callback_and_connectivity
+            if callback_connectivity is not connectivity:
+                callbacks_needing_update.append(callback)
+                callback_and_connectivity[1] = connectivity
+        return callbacks_needing_update
+
+    def _deliver(self, initial_connectivity, initial_callbacks):
+        connectivity = initial_connectivity
+        callbacks = initial_callbacks
+        while True:
+            for callback in callbacks:
+                callable_util.call_logging_exceptions(
+                    callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
+                    connectivity)
+            with self._lock:
+                callbacks = self._deliveries(self._connectivity)
+                if callbacks:
+                    connectivity = self._connectivity
+                else:
+                    self._delivering = False
+                    return
+
+    def _spawn_delivery(self, connectivity, callbacks):
+        delivering_thread = threading.Thread(
+            target=self._deliver, args=(
+                connectivity,
+                callbacks,))
+        delivering_thread.start()
+        self._delivering = True
+
+    # TODO(issue 3064): Don't poll.
+    def _poll_connectivity(self, low_channel, initial_try_to_connect):
+        try_to_connect = initial_try_to_connect
         low_connectivity = low_channel.check_connectivity_state(try_to_connect)
         with self._lock:
-          self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
-              low_connectivity]
-          if not self._delivering:
-            callbacks = self._deliveries(self._connectivity)
+            self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+                low_connectivity]
+            callbacks = tuple(
+                callback
+                for callback, unused_but_known_to_be_none_connectivity in
+                self._callbacks_and_connectivities)
+            for callback_and_connectivity in self._callbacks_and_connectivities:
+                callback_and_connectivity[1] = self._connectivity
             if callbacks:
-              self._spawn_delivery(self._connectivity, callbacks)
-
-  def subscribe(self, callback, try_to_connect):
-    with self._lock:
-      if not self._callbacks_and_connectivities and not self._polling:
-        polling_thread = threading.Thread(
-            target=self._poll_connectivity,
-            args=(self._low_channel, bool(try_to_connect)))
-        polling_thread.start()
-        self._polling = True
-        self._callbacks_and_connectivities.append([callback, None])
-      elif not self._delivering and self._connectivity is not None:
-        self._spawn_delivery(self._connectivity, (callback,))
-        self._try_to_connect |= bool(try_to_connect)
-        self._callbacks_and_connectivities.append(
-            [callback, self._connectivity])
-      else:
-        self._try_to_connect |= bool(try_to_connect)
-        self._callbacks_and_connectivities.append([callback, None])
-
-  def unsubscribe(self, callback):
-    with self._lock:
-      for index, (subscribed_callback, unused_connectivity) in enumerate(
-          self._callbacks_and_connectivities):
-        if callback == subscribed_callback:
-          self._callbacks_and_connectivities.pop(index)
-          break
-
-  def low_channel(self):
-    return self._low_channel
+                self._spawn_delivery(self._connectivity, callbacks)
+        completion_queue = _low.CompletionQueue()
+        while True:
+            low_channel.watch_connectivity_state(low_connectivity,
+                                                 time.time() + 0.2,
+                                                 completion_queue, None)
+            event = completion_queue.next()
+            with self._lock:
+                if not self._callbacks_and_connectivities and not self._try_to_connect:
+                    self._polling = False
+                    self._connectivity = None
+                    completion_queue.shutdown()
+                    break
+                try_to_connect = self._try_to_connect
+                self._try_to_connect = False
+            if event.success or try_to_connect:
+                low_connectivity = low_channel.check_connectivity_state(
+                    try_to_connect)
+                with self._lock:
+                    self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+                        low_connectivity]
+                    if not self._delivering:
+                        callbacks = self._deliveries(self._connectivity)
+                        if callbacks:
+                            self._spawn_delivery(self._connectivity, callbacks)
+
+    def subscribe(self, callback, try_to_connect):
+        with self._lock:
+            if not self._callbacks_and_connectivities and not self._polling:
+                polling_thread = threading.Thread(
+                    target=self._poll_connectivity,
+                    args=(self._low_channel, bool(try_to_connect)))
+                polling_thread.start()
+                self._polling = True
+                self._callbacks_and_connectivities.append([callback, None])
+            elif not self._delivering and self._connectivity is not None:
+                self._spawn_delivery(self._connectivity, (callback,))
+                self._try_to_connect |= bool(try_to_connect)
+                self._callbacks_and_connectivities.append(
+                    [callback, self._connectivity])
+            else:
+                self._try_to_connect |= bool(try_to_connect)
+                self._callbacks_and_connectivities.append([callback, None])
+
+    def unsubscribe(self, callback):
+        with self._lock:
+            for index, (subscribed_callback, unused_connectivity
+                       ) in enumerate(self._callbacks_and_connectivities):
+                if callback == subscribed_callback:
+                    self._callbacks_and_connectivities.pop(index)
+                    break
+
+    def low_channel(self):
+        return self._low_channel
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index cca4a1797a..bb7c0960d5 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Translates gRPC's server-side API into gRPC's server-side Beta API."""
 
 import collections
@@ -47,329 +46,352 @@ _DEFAULT_POOL_SIZE = 8
 
 class _ServerProtocolContext(interfaces.GRPCServicerContext):
 
-  def __init__(self, servicer_context):
-    self._servicer_context = servicer_context
+    def __init__(self, servicer_context):
+        self._servicer_context = servicer_context
 
-  def peer(self):
-    return self._servicer_context.peer()
+    def peer(self):
+        return self._servicer_context.peer()
 
-  def disable_next_response_compression(self):
-    pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+    def disable_next_response_compression(self):
+        pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
 
 
 class _FaceServicerContext(face.ServicerContext):
 
-  def __init__(self, servicer_context):
-    self._servicer_context = servicer_context
+    def __init__(self, servicer_context):
+        self._servicer_context = servicer_context
 
-  def is_active(self):
-    return self._servicer_context.is_active()
+    def is_active(self):
+        return self._servicer_context.is_active()
 
-  def time_remaining(self):
-    return self._servicer_context.time_remaining()
+    def time_remaining(self):
+        return self._servicer_context.time_remaining()
 
-  def add_abortion_callback(self, abortion_callback):
-    raise NotImplementedError(
-        'add_abortion_callback no longer supported server-side!')
+    def add_abortion_callback(self, abortion_callback):
+        raise NotImplementedError(
+            'add_abortion_callback no longer supported server-side!')
 
-  def cancel(self):
-    self._servicer_context.cancel()
+    def cancel(self):
+        self._servicer_context.cancel()
 
-  def protocol_context(self):
-    return _ServerProtocolContext(self._servicer_context)
+    def protocol_context(self):
+        return _ServerProtocolContext(self._servicer_context)
 
-  def invocation_metadata(self):
-    return _common.cygrpc_metadata(
-        self._servicer_context.invocation_metadata())
+    def invocation_metadata(self):
+        return _common.cygrpc_metadata(
+            self._servicer_context.invocation_metadata())
 
-  def initial_metadata(self, initial_metadata):
-    self._servicer_context.send_initial_metadata(initial_metadata)
+    def initial_metadata(self, initial_metadata):
+        self._servicer_context.send_initial_metadata(initial_metadata)
 
-  def terminal_metadata(self, terminal_metadata):
-    self._servicer_context.set_terminal_metadata(terminal_metadata)
+    def terminal_metadata(self, terminal_metadata):
+        self._servicer_context.set_terminal_metadata(terminal_metadata)
 
-  def code(self, code):
-    self._servicer_context.set_code(code)
+    def code(self, code):
+        self._servicer_context.set_code(code)
 
-  def details(self, details):
-    self._servicer_context.set_details(details)
+    def details(self, details):
+        self._servicer_context.set_details(details)
 
 
 def _adapt_unary_request_inline(unary_request_inline):
-  def adaptation(request, servicer_context):
-    return unary_request_inline(request, _FaceServicerContext(servicer_context))
-  return adaptation
+
+    def adaptation(request, servicer_context):
+        return unary_request_inline(request,
+                                    _FaceServicerContext(servicer_context))
+
+    return adaptation
 
 
 def _adapt_stream_request_inline(stream_request_inline):
-  def adaptation(request_iterator, servicer_context):
-    return stream_request_inline(
-        request_iterator, _FaceServicerContext(servicer_context))
-  return adaptation
+
+    def adaptation(request_iterator, servicer_context):
+        return stream_request_inline(request_iterator,
+                                     _FaceServicerContext(servicer_context))
+
+    return adaptation
 
 
 class _Callback(stream.Consumer):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._values = []
-    self._terminated = False
-    self._cancelled = False
-
-  def consume(self, value):
-    with self._condition:
-      self._values.append(value)
-      self._condition.notify_all()
-
-  def terminate(self):
-    with self._condition:
-      self._terminated = True
-      self._condition.notify_all()
-
-  def consume_and_terminate(self, value):
-    with self._condition:
-      self._values.append(value)
-      self._terminated = True
-      self._condition.notify_all()
-
-  def cancel(self):
-    with self._condition:
-      self._cancelled = True
-      self._condition.notify_all()
-
-  def draw_one_value(self):
-    with self._condition:
-      while True:
-        if self._cancelled:
-          raise abandonment.Abandoned()
-        elif self._values:
-          return self._values.pop(0)
-        elif self._terminated:
-          return None
-        else:
-          self._condition.wait()
-
-  def draw_all_values(self):
-    with self._condition:
-      while True:
-        if self._cancelled:
-          raise abandonment.Abandoned()
-        elif self._terminated:
-          all_values = tuple(self._values)
-          self._values = None
-          return all_values
-        else:
-          self._condition.wait()
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._values = []
+        self._terminated = False
+        self._cancelled = False
+
+    def consume(self, value):
+        with self._condition:
+            self._values.append(value)
+            self._condition.notify_all()
+
+    def terminate(self):
+        with self._condition:
+            self._terminated = True
+            self._condition.notify_all()
+
+    def consume_and_terminate(self, value):
+        with self._condition:
+            self._values.append(value)
+            self._terminated = True
+            self._condition.notify_all()
+
+    def cancel(self):
+        with self._condition:
+            self._cancelled = True
+            self._condition.notify_all()
+
+    def draw_one_value(self):
+        with self._condition:
+            while True:
+                if self._cancelled:
+                    raise abandonment.Abandoned()
+                elif self._values:
+                    return self._values.pop(0)
+                elif self._terminated:
+                    return None
+                else:
+                    self._condition.wait()
+
+    def draw_all_values(self):
+        with self._condition:
+            while True:
+                if self._cancelled:
+                    raise abandonment.Abandoned()
+                elif self._terminated:
+                    all_values = tuple(self._values)
+                    self._values = None
+                    return all_values
+                else:
+                    self._condition.wait()
 
 
 def _run_request_pipe_thread(request_iterator, request_consumer,
                              servicer_context):
-  thread_joined = threading.Event()
-  def pipe_requests():
-    for request in request_iterator:
-      if not servicer_context.is_active() or thread_joined.is_set():
-        return
-      request_consumer.consume(request)
-      if not servicer_context.is_active() or thread_joined.is_set():
-        return
-    request_consumer.terminate()
+    thread_joined = threading.Event()
+
+    def pipe_requests():
+        for request in request_iterator:
+            if not servicer_context.is_active() or thread_joined.is_set():
+                return
+            request_consumer.consume(request)
+            if not servicer_context.is_active() or thread_joined.is_set():
+                return
+        request_consumer.terminate()
 
-  def stop_request_pipe(timeout):
-    thread_joined.set()
+    def stop_request_pipe(timeout):
+        thread_joined.set()
 
-  request_pipe_thread = _common.CleanupThread(
-      stop_request_pipe, target=pipe_requests)
-  request_pipe_thread.start()
+    request_pipe_thread = _common.CleanupThread(
+        stop_request_pipe, target=pipe_requests)
+    request_pipe_thread.start()
 
 
 def _adapt_unary_unary_event(unary_unary_event):
-  def adaptation(request, servicer_context):
-    callback = _Callback()
-    if not servicer_context.add_callback(callback.cancel):
-      raise abandonment.Abandoned()
-    unary_unary_event(
-        request, callback.consume_and_terminate,
-        _FaceServicerContext(servicer_context))
-    return callback.draw_all_values()[0]
-  return adaptation
+
+    def adaptation(request, servicer_context):
+        callback = _Callback()
+        if not servicer_context.add_callback(callback.cancel):
+            raise abandonment.Abandoned()
+        unary_unary_event(request, callback.consume_and_terminate,
+                          _FaceServicerContext(servicer_context))
+        return callback.draw_all_values()[0]
+
+    return adaptation
 
 
 def _adapt_unary_stream_event(unary_stream_event):
-  def adaptation(request, servicer_context):
-    callback = _Callback()
-    if not servicer_context.add_callback(callback.cancel):
-      raise abandonment.Abandoned()
-    unary_stream_event(
-        request, callback, _FaceServicerContext(servicer_context))
-    while True:
-      response = callback.draw_one_value()
-      if response is None:
-        return
-      else:
-        yield response
-  return adaptation
+
+    def adaptation(request, servicer_context):
+        callback = _Callback()
+        if not servicer_context.add_callback(callback.cancel):
+            raise abandonment.Abandoned()
+        unary_stream_event(request, callback,
+                           _FaceServicerContext(servicer_context))
+        while True:
+            response = callback.draw_one_value()
+            if response is None:
+                return
+            else:
+                yield response
+
+    return adaptation
 
 
 def _adapt_stream_unary_event(stream_unary_event):
-  def adaptation(request_iterator, servicer_context):
-    callback = _Callback()
-    if not servicer_context.add_callback(callback.cancel):
-      raise abandonment.Abandoned()
-    request_consumer = stream_unary_event(
-        callback.consume_and_terminate, _FaceServicerContext(servicer_context))
-    _run_request_pipe_thread(
-        request_iterator, request_consumer, servicer_context)
-    return callback.draw_all_values()[0]
-  return adaptation
+
+    def adaptation(request_iterator, servicer_context):
+        callback = _Callback()
+        if not servicer_context.add_callback(callback.cancel):
+            raise abandonment.Abandoned()
+        request_consumer = stream_unary_event(
+            callback.consume_and_terminate,
+            _FaceServicerContext(servicer_context))
+        _run_request_pipe_thread(request_iterator, request_consumer,
+                                 servicer_context)
+        return callback.draw_all_values()[0]
+
+    return adaptation
 
 
 def _adapt_stream_stream_event(stream_stream_event):
-  def adaptation(request_iterator, servicer_context):
-    callback = _Callback()
-    if not servicer_context.add_callback(callback.cancel):
-      raise abandonment.Abandoned()
-    request_consumer = stream_stream_event(
-        callback, _FaceServicerContext(servicer_context))
-    _run_request_pipe_thread(
-        request_iterator, request_consumer, servicer_context)
-    while True:
-      response = callback.draw_one_value()
-      if response is None:
-        return
-      else:
-        yield response
-  return adaptation
+
+    def adaptation(request_iterator, servicer_context):
+        callback = _Callback()
+        if not servicer_context.add_callback(callback.cancel):
+            raise abandonment.Abandoned()
+        request_consumer = stream_stream_event(
+            callback, _FaceServicerContext(servicer_context))
+        _run_request_pipe_thread(request_iterator, request_consumer,
+                                 servicer_context)
+        while True:
+            response = callback.draw_one_value()
+            if response is None:
+                return
+            else:
+                yield response
+
+    return adaptation
 
 
 class _SimpleMethodHandler(
-    collections.namedtuple(
-        '_MethodHandler',
-        ('request_streaming', 'response_streaming', 'request_deserializer',
-         'response_serializer', 'unary_unary', 'unary_stream', 'stream_unary',
-         'stream_stream',)),
-    grpc.RpcMethodHandler):
-  pass
-
-
-def _simple_method_handler(
-    implementation, request_deserializer, response_serializer):
-  if implementation.style is style.Service.INLINE:
-    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
-      return _SimpleMethodHandler(
-          False, False, request_deserializer, response_serializer,
-          _adapt_unary_request_inline(implementation.unary_unary_inline), None,
-          None, None)
-    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
-      return _SimpleMethodHandler(
-          False, True, request_deserializer, response_serializer, None,
-          _adapt_unary_request_inline(implementation.unary_stream_inline), None,
-          None)
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
-      return _SimpleMethodHandler(
-          True, False, request_deserializer, response_serializer, None, None,
-          _adapt_stream_request_inline(implementation.stream_unary_inline),
-          None)
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
-      return _SimpleMethodHandler(
-          True, True, request_deserializer, response_serializer, None, None,
-          None,
-          _adapt_stream_request_inline(implementation.stream_stream_inline))
-  elif implementation.style is style.Service.EVENT:
-    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
-      return _SimpleMethodHandler(
-          False, False, request_deserializer, response_serializer,
-          _adapt_unary_unary_event(implementation.unary_unary_event), None,
-          None, None)
-    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
-      return _SimpleMethodHandler(
-          False, True, request_deserializer, response_serializer, None,
-          _adapt_unary_stream_event(implementation.unary_stream_event), None,
-          None)
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
-      return _SimpleMethodHandler(
-          True, False, request_deserializer, response_serializer, None, None,
-          _adapt_stream_unary_event(implementation.stream_unary_event), None)
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
-      return _SimpleMethodHandler(
-          True, True, request_deserializer, response_serializer, None, None,
-          None, _adapt_stream_stream_event(implementation.stream_stream_event))
+        collections.namedtuple('_MethodHandler', (
+            'request_streaming',
+            'response_streaming',
+            'request_deserializer',
+            'response_serializer',
+            'unary_unary',
+            'unary_stream',
+            'stream_unary',
+            'stream_stream',)), grpc.RpcMethodHandler):
+    pass
+
+
+def _simple_method_handler(implementation, request_deserializer,
+                           response_serializer):
+    if implementation.style is style.Service.INLINE:
+        if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+            return _SimpleMethodHandler(
+                False, False, request_deserializer, response_serializer,
+                _adapt_unary_request_inline(implementation.unary_unary_inline),
+                None, None, None)
+        elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+            return _SimpleMethodHandler(
+                False, True, request_deserializer, response_serializer, None,
+                _adapt_unary_request_inline(implementation.unary_stream_inline),
+                None, None)
+        elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+            return _SimpleMethodHandler(True, False, request_deserializer,
+                                        response_serializer, None, None,
+                                        _adapt_stream_request_inline(
+                                            implementation.stream_unary_inline),
+                                        None)
+        elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+            return _SimpleMethodHandler(
+                True, True, request_deserializer, response_serializer, None,
+                None, None,
+                _adapt_stream_request_inline(
+                    implementation.stream_stream_inline))
+    elif implementation.style is style.Service.EVENT:
+        if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+            return _SimpleMethodHandler(
+                False, False, request_deserializer, response_serializer,
+                _adapt_unary_unary_event(implementation.unary_unary_event),
+                None, None, None)
+        elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+            return _SimpleMethodHandler(
+                False, True, request_deserializer, response_serializer, None,
+                _adapt_unary_stream_event(implementation.unary_stream_event),
+                None, None)
+        elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+            return _SimpleMethodHandler(
+                True, False, request_deserializer, response_serializer, None,
+                None,
+                _adapt_stream_unary_event(implementation.stream_unary_event),
+                None)
+        elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+            return _SimpleMethodHandler(
+                True, True, request_deserializer, response_serializer, None,
+                None, None,
+                _adapt_stream_stream_event(implementation.stream_stream_event))
 
 
 def _flatten_method_pair_map(method_pair_map):
-  method_pair_map = method_pair_map or {}
-  flat_map = {}
-  for method_pair in method_pair_map:
-    method = _common.fully_qualified_method(method_pair[0], method_pair[1])
-    flat_map[method] = method_pair_map[method_pair]
-  return flat_map
+    method_pair_map = method_pair_map or {}
+    flat_map = {}
+    for method_pair in method_pair_map:
+        method = _common.fully_qualified_method(method_pair[0], method_pair[1])
+        flat_map[method] = method_pair_map[method_pair]
+    return flat_map
 
 
 class _GenericRpcHandler(grpc.GenericRpcHandler):
 
-  def __init__(
-      self, method_implementations, multi_method_implementation,
-      request_deserializers, response_serializers):
-    self._method_implementations = _flatten_method_pair_map(
-        method_implementations)
-    self._request_deserializers = _flatten_method_pair_map(
-        request_deserializers)
-    self._response_serializers = _flatten_method_pair_map(
-        response_serializers)
-    self._multi_method_implementation = multi_method_implementation
-
-  def service(self, handler_call_details):
-    method_implementation = self._method_implementations.get(
-        handler_call_details.method)
-    if method_implementation is not None:
-      return _simple_method_handler(
-          method_implementation,
-          self._request_deserializers.get(handler_call_details.method),
-          self._response_serializers.get(handler_call_details.method))
-    elif self._multi_method_implementation is None:
-      return None
-    else:
-      try:
-        return None  #TODO(nathaniel): call the multimethod.
-      except face.NoSuchMethodError:
-        return None
+    def __init__(self, method_implementations, multi_method_implementation,
+                 request_deserializers, response_serializers):
+        self._method_implementations = _flatten_method_pair_map(
+            method_implementations)
+        self._request_deserializers = _flatten_method_pair_map(
+            request_deserializers)
+        self._response_serializers = _flatten_method_pair_map(
+            response_serializers)
+        self._multi_method_implementation = multi_method_implementation
+
+    def service(self, handler_call_details):
+        method_implementation = self._method_implementations.get(
+            handler_call_details.method)
+        if method_implementation is not None:
+            return _simple_method_handler(
+                method_implementation,
+                self._request_deserializers.get(handler_call_details.method),
+                self._response_serializers.get(handler_call_details.method))
+        elif self._multi_method_implementation is None:
+            return None
+        else:
+            try:
+                return None  #TODO(nathaniel): call the multimethod.
+            except face.NoSuchMethodError:
+                return None
 
 
 class _Server(interfaces.Server):
 
-  def __init__(self, server):
-    self._server = server
+    def __init__(self, server):
+        self._server = server
 
-  def add_insecure_port(self, address):
-    return self._server.add_insecure_port(address)
+    def add_insecure_port(self, address):
+        return self._server.add_insecure_port(address)
 
-  def add_secure_port(self, address, server_credentials):
-    return self._server.add_secure_port(address, server_credentials)
+    def add_secure_port(self, address, server_credentials):
+        return self._server.add_secure_port(address, server_credentials)
 
-  def start(self):
-    self._server.start()
+    def start(self):
+        self._server.start()
 
-  def stop(self, grace):
-    return self._server.stop(grace)
+    def stop(self, grace):
+        return self._server.stop(grace)
 
-  def __enter__(self):
-    self._server.start()
-    return self
+    def __enter__(self):
+        self._server.start()
+        return self
 
-  def __exit__(self, exc_type, exc_val, exc_tb):
-    self._server.stop(None)
-    return False
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self._server.stop(None)
+        return False
 
 
-def server(
-    service_implementations, multi_method_implementation, request_deserializers,
-    response_serializers, thread_pool, thread_pool_size):
-  generic_rpc_handler = _GenericRpcHandler(
-      service_implementations, multi_method_implementation,
-      request_deserializers, response_serializers)
-  if thread_pool is None:
-    effective_thread_pool = logging_pool.pool(
-        _DEFAULT_POOL_SIZE if thread_pool_size is None else thread_pool_size)
-  else:
-    effective_thread_pool = thread_pool
-  return _Server(
-      grpc.server(effective_thread_pool, handlers=(generic_rpc_handler,)))
+def server(service_implementations, multi_method_implementation,
+           request_deserializers, response_serializers, thread_pool,
+           thread_pool_size):
+    generic_rpc_handler = _GenericRpcHandler(
+        service_implementations, multi_method_implementation,
+        request_deserializers, response_serializers)
+    if thread_pool is None:
+        effective_thread_pool = logging_pool.pool(_DEFAULT_POOL_SIZE
+                                                  if thread_pool_size is None
+                                                  else thread_pool_size)
+    else:
+        effective_thread_pool = thread_pool
+    return _Server(
+        grpc.server(
+            effective_thread_pool, handlers=(generic_rpc_handler,)))
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index ab25fd5eec..7093852278 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Entry points into the Beta API of gRPC Python."""
 
 # threading is referenced from specification in this module.
@@ -43,7 +42,6 @@ from grpc.beta import interfaces
 from grpc.framework.common import cardinality  # pylint: disable=unused-import
 from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 
-
 ChannelCredentials = grpc.ChannelCredentials
 ssl_channel_credentials = grpc.ssl_channel_credentials
 CallCredentials = grpc.CallCredentials
@@ -51,7 +49,7 @@ metadata_call_credentials = grpc.metadata_call_credentials
 
 
 def google_call_credentials(credentials):
-  """Construct CallCredentials from GoogleCredentials.
+    """Construct CallCredentials from GoogleCredentials.
 
   Args:
     credentials: A GoogleCredentials object from the oauth2client library.
@@ -59,7 +57,8 @@ def google_call_credentials(credentials):
   Returns:
     A CallCredentials object for use in a GRPCCallOptions object.
   """
-  return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
+    return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
+
 
 access_token_call_credentials = grpc.access_token_call_credentials
 composite_call_credentials = grpc.composite_call_credentials
@@ -67,18 +66,18 @@ composite_channel_credentials = grpc.composite_channel_credentials
 
 
 class Channel(object):
-  """A channel to a remote host through which RPCs may be conducted.
+    """A channel to a remote host through which RPCs may be conducted.
 
   Only the "subscribe" and "unsubscribe" methods are supported for application
   use. This class' instance constructor and all other attributes are
   unsupported.
   """
 
-  def __init__(self, channel):
-    self._channel = channel
+    def __init__(self, channel):
+        self._channel = channel
 
-  def subscribe(self, callback, try_to_connect=None):
-    """Subscribes to this Channel's connectivity.
+    def subscribe(self, callback, try_to_connect=None):
+        """Subscribes to this Channel's connectivity.
 
     Args:
       callback: A callable to be invoked and passed an
@@ -90,20 +89,20 @@ class Channel(object):
         attempt to connect if it is not already connected and ready to conduct
         RPCs.
     """
-    self._channel.subscribe(callback, try_to_connect=try_to_connect)
+        self._channel.subscribe(callback, try_to_connect=try_to_connect)
 
-  def unsubscribe(self, callback):
-    """Unsubscribes a callback from this Channel's connectivity.
+    def unsubscribe(self, callback):
+        """Unsubscribes a callback from this Channel's connectivity.
 
     Args:
       callback: A callable previously registered with this Channel from having
         been passed to its "subscribe" method.
     """
-    self._channel.unsubscribe(callback)
+        self._channel.unsubscribe(callback)
 
 
 def insecure_channel(host, port):
-  """Creates an insecure Channel to a remote host.
+    """Creates an insecure Channel to a remote host.
 
   Args:
     host: The name of the remote host to which to connect.
@@ -113,13 +112,13 @@ def insecure_channel(host, port):
   Returns:
     A Channel to the remote host through which RPCs may be conducted.
   """
-  channel = grpc.insecure_channel(
-      host if port is None else '%s:%d' % (host, port))
-  return Channel(channel)
+    channel = grpc.insecure_channel(host
+                                    if port is None else '%s:%d' % (host, port))
+    return Channel(channel)
 
 
 def secure_channel(host, port, channel_credentials):
-  """Creates a secure Channel to a remote host.
+    """Creates a secure Channel to a remote host.
 
   Args:
     host: The name of the remote host to which to connect.
@@ -130,37 +129,39 @@ def secure_channel(host, port, channel_credentials):
   Returns:
     A secure Channel to the remote host through which RPCs may be conducted.
   """
-  channel = grpc.secure_channel(
-      host if port is None else '%s:%d' % (host, port), channel_credentials)
-  return Channel(channel)
+    channel = grpc.secure_channel(host if port is None else
+                                  '%s:%d' % (host, port), channel_credentials)
+    return Channel(channel)
 
 
 class StubOptions(object):
-  """A value encapsulating the various options for creation of a Stub.
+    """A value encapsulating the various options for creation of a Stub.
 
   This class and its instances have no supported interface - it exists to define
   the type of its instances and its instances exist to be passed to other
   functions.
   """
 
-  def __init__(
-      self, host, request_serializers, response_deserializers,
-      metadata_transformer, thread_pool, thread_pool_size):
-    self.host = host
-    self.request_serializers = request_serializers
-    self.response_deserializers = response_deserializers
-    self.metadata_transformer = metadata_transformer
-    self.thread_pool = thread_pool
-    self.thread_pool_size = thread_pool_size
+    def __init__(self, host, request_serializers, response_deserializers,
+                 metadata_transformer, thread_pool, thread_pool_size):
+        self.host = host
+        self.request_serializers = request_serializers
+        self.response_deserializers = response_deserializers
+        self.metadata_transformer = metadata_transformer
+        self.thread_pool = thread_pool
+        self.thread_pool_size = thread_pool_size
 
-_EMPTY_STUB_OPTIONS = StubOptions(
-    None, None, None, None, None, None)
 
+_EMPTY_STUB_OPTIONS = StubOptions(None, None, None, None, None, None)
 
-def stub_options(
-    host=None, request_serializers=None, response_deserializers=None,
-    metadata_transformer=None, thread_pool=None, thread_pool_size=None):
-  """Creates a StubOptions value to be passed at stub creation.
+
+def stub_options(host=None,
+                 request_serializers=None,
+                 response_deserializers=None,
+                 metadata_transformer=None,
+                 thread_pool=None,
+                 thread_pool_size=None):
+    """Creates a StubOptions value to be passed at stub creation.
 
   All parameters are optional and should always be passed by keyword.
 
@@ -180,13 +181,12 @@ def stub_options(
   Returns:
     A StubOptions value created from the passed parameters.
   """
-  return StubOptions(
-      host, request_serializers, response_deserializers,
-      metadata_transformer, thread_pool, thread_pool_size)
+    return StubOptions(host, request_serializers, response_deserializers,
+                       metadata_transformer, thread_pool, thread_pool_size)
 
 
 def generic_stub(channel, options=None):
-  """Creates a face.GenericStub on which RPCs can be made.
+    """Creates a face.GenericStub on which RPCs can be made.
 
   Args:
     channel: A Channel for use by the created stub.
@@ -195,16 +195,17 @@ def generic_stub(channel, options=None):
   Returns:
     A face.GenericStub on which RPCs can be made.
   """
-  effective_options = _EMPTY_STUB_OPTIONS if options is None else options
-  return _client_adaptations.generic_stub(
-      channel._channel,  # pylint: disable=protected-access
-      effective_options.host, effective_options.metadata_transformer,
-      effective_options.request_serializers,
-      effective_options.response_deserializers)
+    effective_options = _EMPTY_STUB_OPTIONS if options is None else options
+    return _client_adaptations.generic_stub(
+        channel._channel,  # pylint: disable=protected-access
+        effective_options.host,
+        effective_options.metadata_transformer,
+        effective_options.request_serializers,
+        effective_options.response_deserializers)
 
 
 def dynamic_stub(channel, service, cardinalities, options=None):
-  """Creates a face.DynamicStub with which RPCs can be invoked.
+    """Creates a face.DynamicStub with which RPCs can be invoked.
 
   Args:
     channel: A Channel for the returned face.DynamicStub to use.
@@ -217,13 +218,15 @@ def dynamic_stub(channel, service, cardinalities, options=None):
   Returns:
     A face.DynamicStub with which RPCs can be invoked.
   """
-  effective_options = StubOptions() if options is None else options
-  return _client_adaptations.dynamic_stub(
-      channel._channel,  # pylint: disable=protected-access
-      service, cardinalities, effective_options.host,
-      effective_options.metadata_transformer,
-      effective_options.request_serializers,
-      effective_options.response_deserializers)
+    effective_options = StubOptions() if options is None else options
+    return _client_adaptations.dynamic_stub(
+        channel._channel,  # pylint: disable=protected-access
+        service,
+        cardinalities,
+        effective_options.host,
+        effective_options.metadata_transformer,
+        effective_options.request_serializers,
+        effective_options.response_deserializers)
 
 
 ServerCredentials = grpc.ServerCredentials
@@ -231,34 +234,36 @@ ssl_server_credentials = grpc.ssl_server_credentials
 
 
 class ServerOptions(object):
-  """A value encapsulating the various options for creation of a Server.
+    """A value encapsulating the various options for creation of a Server.
 
   This class and its instances have no supported interface - it exists to define
   the type of its instances and its instances exist to be passed to other
   functions.
   """
 
-  def __init__(
-      self, multi_method_implementation, request_deserializers,
-      response_serializers, thread_pool, thread_pool_size, default_timeout,
-      maximum_timeout):
-    self.multi_method_implementation = multi_method_implementation
-    self.request_deserializers = request_deserializers
-    self.response_serializers = response_serializers
-    self.thread_pool = thread_pool
-    self.thread_pool_size = thread_pool_size
-    self.default_timeout = default_timeout
-    self.maximum_timeout = maximum_timeout
+    def __init__(self, multi_method_implementation, request_deserializers,
+                 response_serializers, thread_pool, thread_pool_size,
+                 default_timeout, maximum_timeout):
+        self.multi_method_implementation = multi_method_implementation
+        self.request_deserializers = request_deserializers
+        self.response_serializers = response_serializers
+        self.thread_pool = thread_pool
+        self.thread_pool_size = thread_pool_size
+        self.default_timeout = default_timeout
+        self.maximum_timeout = maximum_timeout
+
 
-_EMPTY_SERVER_OPTIONS = ServerOptions(
-    None, None, None, None, None, None, None)
+_EMPTY_SERVER_OPTIONS = ServerOptions(None, None, None, None, None, None, None)
 
 
-def server_options(
-    multi_method_implementation=None, request_deserializers=None,
-    response_serializers=None, thread_pool=None, thread_pool_size=None,
-    default_timeout=None, maximum_timeout=None):
-  """Creates a ServerOptions value to be passed at server creation.
+def server_options(multi_method_implementation=None,
+                   request_deserializers=None,
+                   response_serializers=None,
+                   thread_pool=None,
+                   thread_pool_size=None,
+                   default_timeout=None,
+                   maximum_timeout=None):
+    """Creates a ServerOptions value to be passed at server creation.
 
   All parameters are optional and should always be passed by keyword.
 
@@ -282,13 +287,13 @@ def server_options(
   Returns:
     A StubOptions value created from the passed parameters.
   """
-  return ServerOptions(
-      multi_method_implementation, request_deserializers, response_serializers,
-      thread_pool, thread_pool_size, default_timeout, maximum_timeout)
+    return ServerOptions(multi_method_implementation, request_deserializers,
+                         response_serializers, thread_pool, thread_pool_size,
+                         default_timeout, maximum_timeout)
 
 
 def server(service_implementations, options=None):
-  """Creates an interfaces.Server with which RPCs can be serviced.
+    """Creates an interfaces.Server with which RPCs can be serviced.
 
   Args:
     service_implementations: A dictionary from service name-method name pair to
@@ -299,9 +304,9 @@ def server(service_implementations, options=None):
   Returns:
     An interfaces.Server with which RPCs can be serviced.
   """
-  effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
-  return _server_adaptations.server(
-      service_implementations, effective_options.multi_method_implementation,
-      effective_options.request_deserializers,
-      effective_options.response_serializers, effective_options.thread_pool,
-      effective_options.thread_pool_size)
+    effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
+    return _server_adaptations.server(
+        service_implementations, effective_options.multi_method_implementation,
+        effective_options.request_deserializers,
+        effective_options.response_serializers, effective_options.thread_pool,
+        effective_options.thread_pool_size)
diff --git a/src/python/grpcio/grpc/beta/interfaces.py b/src/python/grpcio/grpc/beta/interfaces.py
index 90f6bbbfcc..361d1bcffe 100644
--- a/src/python/grpcio/grpc/beta/interfaces.py
+++ b/src/python/grpcio/grpc/beta/interfaces.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Constants and interfaces of the Beta API of gRPC Python."""
 
 import abc
@@ -43,21 +42,21 @@ StatusCode = grpc.StatusCode
 
 
 class GRPCCallOptions(object):
-  """A value encapsulating gRPC-specific options passed on RPC invocation.
+    """A value encapsulating gRPC-specific options passed on RPC invocation.
 
   This class and its instances have no supported interface - it exists to
   define the type of its instances and its instances exist to be passed to
   other functions.
   """
 
-  def __init__(self, disable_compression, subcall_of, credentials):
-    self.disable_compression = disable_compression
-    self.subcall_of = subcall_of
-    self.credentials = credentials
+    def __init__(self, disable_compression, subcall_of, credentials):
+        self.disable_compression = disable_compression
+        self.subcall_of = subcall_of
+        self.credentials = credentials
 
 
 def grpc_call_options(disable_compression=False, credentials=None):
-  """Creates a GRPCCallOptions value to be passed at RPC invocation.
+    """Creates a GRPCCallOptions value to be passed at RPC invocation.
 
   All parameters are optional and should always be passed by keyword.
 
@@ -67,7 +66,8 @@ def grpc_call_options(disable_compression=False, credentials=None):
       request-unary RPCs.
     credentials: A CallCredentials object to use for the invoked RPC.
   """
-  return GRPCCallOptions(disable_compression, None, credentials)
+    return GRPCCallOptions(disable_compression, None, credentials)
+
 
 GRPCAuthMetadataContext = grpc.AuthMetadataContext
 GRPCAuthMetadataPluginCallback = grpc.AuthMetadataPluginCallback
@@ -75,38 +75,38 @@ GRPCAuthMetadataPlugin = grpc.AuthMetadataPlugin
 
 
 class GRPCServicerContext(six.with_metaclass(abc.ABCMeta)):
-  """Exposes gRPC-specific options and behaviors to code servicing RPCs."""
+    """Exposes gRPC-specific options and behaviors to code servicing RPCs."""
 
-  @abc.abstractmethod
-  def peer(self):
-    """Identifies the peer that invoked the RPC being serviced.
+    @abc.abstractmethod
+    def peer(self):
+        """Identifies the peer that invoked the RPC being serviced.
 
     Returns:
       A string identifying the peer that invoked the RPC being serviced.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def disable_next_response_compression(self):
-    """Disables compression of the next response passed by the application."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def disable_next_response_compression(self):
+        """Disables compression of the next response passed by the application."""
+        raise NotImplementedError()
 
 
 class GRPCInvocationContext(six.with_metaclass(abc.ABCMeta)):
-  """Exposes gRPC-specific options and behaviors to code invoking RPCs."""
+    """Exposes gRPC-specific options and behaviors to code invoking RPCs."""
 
-  @abc.abstractmethod
-  def disable_next_request_compression(self):
-    """Disables compression of the next request passed by the application."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def disable_next_request_compression(self):
+        """Disables compression of the next request passed by the application."""
+        raise NotImplementedError()
 
 
 class Server(six.with_metaclass(abc.ABCMeta)):
-  """Services RPCs."""
+    """Services RPCs."""
 
-  @abc.abstractmethod
-  def add_insecure_port(self, address):
-    """Reserves a port for insecure RPC service once this Server becomes active.
+    @abc.abstractmethod
+    def add_insecure_port(self, address):
+        """Reserves a port for insecure RPC service once this Server becomes active.
 
     This method may only be called before calling this Server's start method is
     called.
@@ -120,11 +120,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
         in the passed address, but will likely be different if the port number
         contained in the passed address was zero.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_secure_port(self, address, server_credentials):
-    """Reserves a port for secure RPC service after this Server becomes active.
+    @abc.abstractmethod
+    def add_secure_port(self, address, server_credentials):
+        """Reserves a port for secure RPC service after this Server becomes active.
 
     This method may only be called before calling this Server's start method is
     called.
@@ -139,20 +139,20 @@ class Server(six.with_metaclass(abc.ABCMeta)):
         in the passed address, but will likely be different if the port number
         contained in the passed address was zero.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def start(self):
-    """Starts this Server's service of RPCs.
+    @abc.abstractmethod
+    def start(self):
+        """Starts this Server's service of RPCs.
 
     This method may only be called while the server is not serving RPCs (i.e. it
     is not idempotent).
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stop(self, grace):
-    """Stops this Server's service of RPCs.
+    @abc.abstractmethod
+    def stop(self, grace):
+        """Stops this Server's service of RPCs.
 
     All calls to this method immediately stop service of new RPCs. When existing
     RPCs are aborted is controlled by the grace period parameter passed to this
@@ -177,4 +177,4 @@ class Server(six.with_metaclass(abc.ABCMeta)):
       at the time it was stopped or if all RPCs that it had underway completed
       very early in the grace period).
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/beta/utilities.py b/src/python/grpcio/grpc/beta/utilities.py
index fb07a76579..60525350a7 100644
--- a/src/python/grpcio/grpc/beta/utilities.py
+++ b/src/python/grpcio/grpc/beta/utilities.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Utilities for the gRPC Python Beta API."""
 
 import threading
@@ -44,107 +43,107 @@ _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
 
 class _ChannelReadyFuture(future.Future):
 
-  def __init__(self, channel):
-    self._condition = threading.Condition()
-    self._channel = channel
-
-    self._matured = False
-    self._cancelled = False
-    self._done_callbacks = []
-
-  def _block(self, timeout):
-    until = None if timeout is None else time.time() + timeout
-    with self._condition:
-      while True:
-        if self._cancelled:
-          raise future.CancelledError()
-        elif self._matured:
-          return
-        else:
-          if until is None:
-            self._condition.wait()
-          else:
-            remaining = until - time.time()
-            if remaining < 0:
-              raise future.TimeoutError()
+    def __init__(self, channel):
+        self._condition = threading.Condition()
+        self._channel = channel
+
+        self._matured = False
+        self._cancelled = False
+        self._done_callbacks = []
+
+    def _block(self, timeout):
+        until = None if timeout is None else time.time() + timeout
+        with self._condition:
+            while True:
+                if self._cancelled:
+                    raise future.CancelledError()
+                elif self._matured:
+                    return
+                else:
+                    if until is None:
+                        self._condition.wait()
+                    else:
+                        remaining = until - time.time()
+                        if remaining < 0:
+                            raise future.TimeoutError()
+                        else:
+                            self._condition.wait(timeout=remaining)
+
+    def _update(self, connectivity):
+        with self._condition:
+            if (not self._cancelled and
+                    connectivity is interfaces.ChannelConnectivity.READY):
+                self._matured = True
+                self._channel.unsubscribe(self._update)
+                self._condition.notify_all()
+                done_callbacks = tuple(self._done_callbacks)
+                self._done_callbacks = None
+            else:
+                return
+
+        for done_callback in done_callbacks:
+            callable_util.call_logging_exceptions(
+                done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+    def cancel(self):
+        with self._condition:
+            if not self._matured:
+                self._cancelled = True
+                self._channel.unsubscribe(self._update)
+                self._condition.notify_all()
+                done_callbacks = tuple(self._done_callbacks)
+                self._done_callbacks = None
             else:
-              self._condition.wait(timeout=remaining)
-
-  def _update(self, connectivity):
-    with self._condition:
-      if (not self._cancelled and
-          connectivity is interfaces.ChannelConnectivity.READY):
-        self._matured = True
-        self._channel.unsubscribe(self._update)
-        self._condition.notify_all()
-        done_callbacks = tuple(self._done_callbacks)
-        self._done_callbacks = None
-      else:
-        return
-
-    for done_callback in done_callbacks:
-      callable_util.call_logging_exceptions(
-          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
-  def cancel(self):
-    with self._condition:
-      if not self._matured:
-        self._cancelled = True
-        self._channel.unsubscribe(self._update)
-        self._condition.notify_all()
-        done_callbacks = tuple(self._done_callbacks)
-        self._done_callbacks = None
-      else:
-        return False
-
-    for done_callback in done_callbacks:
-      callable_util.call_logging_exceptions(
-          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
-  def cancelled(self):
-    with self._condition:
-      return self._cancelled
-
-  def running(self):
-    with self._condition:
-      return not self._cancelled and not self._matured
-
-  def done(self):
-    with self._condition:
-      return self._cancelled or self._matured
-
-  def result(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def exception(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def traceback(self, timeout=None):
-    self._block(timeout)
-    return None
-
-  def add_done_callback(self, fn):
-    with self._condition:
-      if not self._cancelled and not self._matured:
-        self._done_callbacks.append(fn)
-        return
-
-    fn(self)
-
-  def start(self):
-    with self._condition:
-      self._channel.subscribe(self._update, try_to_connect=True)
-
-  def __del__(self):
-    with self._condition:
-      if not self._cancelled and not self._matured:
-        self._channel.unsubscribe(self._update)
+                return False
+
+        for done_callback in done_callbacks:
+            callable_util.call_logging_exceptions(
+                done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+    def cancelled(self):
+        with self._condition:
+            return self._cancelled
+
+    def running(self):
+        with self._condition:
+            return not self._cancelled and not self._matured
+
+    def done(self):
+        with self._condition:
+            return self._cancelled or self._matured
+
+    def result(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def exception(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def traceback(self, timeout=None):
+        self._block(timeout)
+        return None
+
+    def add_done_callback(self, fn):
+        with self._condition:
+            if not self._cancelled and not self._matured:
+                self._done_callbacks.append(fn)
+                return
+
+        fn(self)
+
+    def start(self):
+        with self._condition:
+            self._channel.subscribe(self._update, try_to_connect=True)
+
+    def __del__(self):
+        with self._condition:
+            if not self._cancelled and not self._matured:
+                self._channel.unsubscribe(self._update)
 
 
 def channel_ready_future(channel):
-  """Creates a future.Future tracking when an implementations.Channel is ready.
+    """Creates a future.Future tracking when an implementations.Channel is ready.
 
   Cancelling the returned future.Future does not tell the given
   implementations.Channel to abandon attempts it may have been making to
@@ -158,7 +157,6 @@ def channel_ready_future(channel):
     A future.Future that matures when the given Channel has connectivity
       interfaces.ChannelConnectivity.READY.
   """
-  ready_future = _ChannelReadyFuture(channel)
-  ready_future.start()
-  return ready_future
-
+    ready_future = _ChannelReadyFuture(channel)
+    ready_future.start()
+    return ready_future
diff --git a/src/python/grpcio/grpc/framework/__init__.py b/src/python/grpcio/grpc/framework/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/__init__.py
+++ b/src/python/grpcio/grpc/framework/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/common/__init__.py b/src/python/grpcio/grpc/framework/common/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/common/__init__.py
+++ b/src/python/grpcio/grpc/framework/common/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/common/cardinality.py b/src/python/grpcio/grpc/framework/common/cardinality.py
index 610425e803..d8927cf9b0 100644
--- a/src/python/grpcio/grpc/framework/common/cardinality.py
+++ b/src/python/grpcio/grpc/framework/common/cardinality.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Defines an enum for classifying RPC methods by streaming semantics."""
 
 import enum
@@ -34,9 +33,9 @@ import enum
 
 @enum.unique
 class Cardinality(enum.Enum):
-  """Describes the streaming semantics of an RPC method."""
+    """Describes the streaming semantics of an RPC method."""
 
-  UNARY_UNARY = 'request-unary/response-unary'
-  UNARY_STREAM = 'request-unary/response-streaming'
-  STREAM_UNARY = 'request-streaming/response-unary'
-  STREAM_STREAM = 'request-streaming/response-streaming'
+    UNARY_UNARY = 'request-unary/response-unary'
+    UNARY_STREAM = 'request-unary/response-streaming'
+    STREAM_UNARY = 'request-streaming/response-unary'
+    STREAM_STREAM = 'request-streaming/response-streaming'
diff --git a/src/python/grpcio/grpc/framework/common/style.py b/src/python/grpcio/grpc/framework/common/style.py
index 6ae694bdcb..43f4211145 100644
--- a/src/python/grpcio/grpc/framework/common/style.py
+++ b/src/python/grpcio/grpc/framework/common/style.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Defines an enum for classifying RPC methods by control flow semantics."""
 
 import enum
@@ -34,7 +33,7 @@ import enum
 
 @enum.unique
 class Service(enum.Enum):
-  """Describes the control flow style of RPC method implementation."""
+    """Describes the control flow style of RPC method implementation."""
 
-  INLINE = 'inline'
-  EVENT = 'event'
+    INLINE = 'inline'
+    EVENT = 'event'
diff --git a/src/python/grpcio/grpc/framework/foundation/__init__.py b/src/python/grpcio/grpc/framework/foundation/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/foundation/__init__.py
+++ b/src/python/grpcio/grpc/framework/foundation/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/foundation/abandonment.py b/src/python/grpcio/grpc/framework/foundation/abandonment.py
index 960b4d06b4..32385b9657 100644
--- a/src/python/grpcio/grpc/framework/foundation/abandonment.py
+++ b/src/python/grpcio/grpc/framework/foundation/abandonment.py
@@ -26,12 +26,11 @@
 # 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.
-
 """Utilities for indicating abandonment of computation."""
 
 
 class Abandoned(Exception):
-  """Indicates that some computation is being abandoned.
+    """Indicates that some computation is being abandoned.
 
   Abandoning a computation is different than returning a value or raising
   an exception indicating some operational or programming defect.
diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py
index 4f029f97bb..3b8351c19b 100644
--- a/src/python/grpcio/grpc/framework/foundation/callable_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Utilities for working with callables."""
 
 import abc
@@ -39,7 +38,7 @@ import six
 
 
 class Outcome(six.with_metaclass(abc.ABCMeta)):
-  """A sum type describing the outcome of some call.
+    """A sum type describing the outcome of some call.
 
   Attributes:
     kind: One of Kind.RETURNED or Kind.RAISED respectively indicating that the
@@ -50,31 +49,31 @@ class Outcome(six.with_metaclass(abc.ABCMeta)):
       Kind.RAISED.
   """
 
-  @enum.unique
-  class Kind(enum.Enum):
-    """Identifies the general kind of the outcome of some call."""
+    @enum.unique
+    class Kind(enum.Enum):
+        """Identifies the general kind of the outcome of some call."""
 
-    RETURNED = object()
-    RAISED = object()
+        RETURNED = object()
+        RAISED = object()
 
 
 class _EasyOutcome(
-    collections.namedtuple(
-        '_EasyOutcome', ['kind', 'return_value', 'exception']),
-    Outcome):
-  """A trivial implementation of Outcome."""
+        collections.namedtuple('_EasyOutcome',
+                               ['kind', 'return_value', 'exception']), Outcome):
+    """A trivial implementation of Outcome."""
 
 
 def _call_logging_exceptions(behavior, message, *args, **kwargs):
-  try:
-    return _EasyOutcome(Outcome.Kind.RETURNED, behavior(*args, **kwargs), None)
-  except Exception as e:  # pylint: disable=broad-except
-    logging.exception(message)
-    return _EasyOutcome(Outcome.Kind.RAISED, None, e)
+    try:
+        return _EasyOutcome(Outcome.Kind.RETURNED,
+                            behavior(*args, **kwargs), None)
+    except Exception as e:  # pylint: disable=broad-except
+        logging.exception(message)
+        return _EasyOutcome(Outcome.Kind.RAISED, None, e)
 
 
 def with_exceptions_logged(behavior, message):
-  """Wraps a callable in a try-except that logs any exceptions it raises.
+    """Wraps a callable in a try-except that logs any exceptions it raises.
 
   Args:
     behavior: Any callable.
@@ -86,14 +85,16 @@ def with_exceptions_logged(behavior, message):
       future.Outcome describing whether the given behavior returned a value or
       raised an exception.
   """
-  @functools.wraps(behavior)
-  def wrapped_behavior(*args, **kwargs):
-    return _call_logging_exceptions(behavior, message, *args, **kwargs)
-  return wrapped_behavior
+
+    @functools.wraps(behavior)
+    def wrapped_behavior(*args, **kwargs):
+        return _call_logging_exceptions(behavior, message, *args, **kwargs)
+
+    return wrapped_behavior
 
 
 def call_logging_exceptions(behavior, message, *args, **kwargs):
-  """Calls a behavior in a try-except that logs any exceptions it raises.
+    """Calls a behavior in a try-except that logs any exceptions it raises.
 
   Args:
     behavior: Any callable.
@@ -105,4 +106,4 @@ def call_logging_exceptions(behavior, message, *args, **kwargs):
     An Outcome describing whether the given behavior returned a value or raised
       an exception.
   """
-  return _call_logging_exceptions(behavior, message, *args, **kwargs)
+    return _call_logging_exceptions(behavior, message, *args, **kwargs)
diff --git a/src/python/grpcio/grpc/framework/foundation/future.py b/src/python/grpcio/grpc/framework/foundation/future.py
index 6fb58eadb6..e2ecf62921 100644
--- a/src/python/grpcio/grpc/framework/foundation/future.py
+++ b/src/python/grpcio/grpc/framework/foundation/future.py
@@ -26,7 +26,6 @@
 # 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.
-
 """A Future interface.
 
 Python doesn't have a Future interface in its standard library. In the absence
@@ -53,33 +52,33 @@ import six
 
 
 class TimeoutError(Exception):
-  """Indicates that a particular call timed out."""
+    """Indicates that a particular call timed out."""
 
 
 class CancelledError(Exception):
-  """Indicates that the computation underlying a Future was cancelled."""
+    """Indicates that the computation underlying a Future was cancelled."""
 
 
 class Future(six.with_metaclass(abc.ABCMeta)):
-  """A representation of a computation in another control flow.
+    """A representation of a computation in another control flow.
 
   Computations represented by a Future may be yet to be begun, may be ongoing,
   or may have already completed.
   """
 
-  # NOTE(nathaniel): This isn't the return type that I would want to have if it
-  # were up to me. Were this interface being written from scratch, the return
-  # type of this method would probably be a sum type like:
-  #
-  # NOT_COMMENCED
-  # COMMENCED_AND_NOT_COMPLETED
-  # PARTIAL_RESULT<Partial_Result_Type>
-  # COMPLETED<Result_Type>
-  # UNCANCELLABLE
-  # NOT_IMMEDIATELY_DETERMINABLE
-  @abc.abstractmethod
-  def cancel(self):
-    """Attempts to cancel the computation.
+    # NOTE(nathaniel): This isn't the return type that I would want to have if it
+    # were up to me. Were this interface being written from scratch, the return
+    # type of this method would probably be a sum type like:
+    #
+    # NOT_COMMENCED
+    # COMMENCED_AND_NOT_COMPLETED
+    # PARTIAL_RESULT<Partial_Result_Type>
+    # COMPLETED<Result_Type>
+    # UNCANCELLABLE
+    # NOT_IMMEDIATELY_DETERMINABLE
+    @abc.abstractmethod
+    def cancel(self):
+        """Attempts to cancel the computation.
 
     This method does not block.
 
@@ -92,25 +91,25 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         remote system for which a determination of whether or not it commenced
         before being cancelled cannot be made without blocking.
     """
-    raise NotImplementedError()
-
-  # NOTE(nathaniel): Here too this isn't the return type that I'd want this
-  # method to have if it were up to me. I think I'd go with another sum type
-  # like:
-  #
-  # NOT_CANCELLED (this object's cancel method hasn't been called)
-  # NOT_COMMENCED
-  # COMMENCED_AND_NOT_COMPLETED
-  # PARTIAL_RESULT<Partial_Result_Type>
-  # COMPLETED<Result_Type>
-  # UNCANCELLABLE
-  # NOT_IMMEDIATELY_DETERMINABLE
-  #
-  # Notice how giving the cancel method the right semantics obviates most
-  # reasons for this method to exist.
-  @abc.abstractmethod
-  def cancelled(self):
-    """Describes whether the computation was cancelled.
+        raise NotImplementedError()
+
+    # NOTE(nathaniel): Here too this isn't the return type that I'd want this
+    # method to have if it were up to me. I think I'd go with another sum type
+    # like:
+    #
+    # NOT_CANCELLED (this object's cancel method hasn't been called)
+    # NOT_COMMENCED
+    # COMMENCED_AND_NOT_COMPLETED
+    # PARTIAL_RESULT<Partial_Result_Type>
+    # COMPLETED<Result_Type>
+    # UNCANCELLABLE
+    # NOT_IMMEDIATELY_DETERMINABLE
+    #
+    # Notice how giving the cancel method the right semantics obviates most
+    # reasons for this method to exist.
+    @abc.abstractmethod
+    def cancelled(self):
+        """Describes whether the computation was cancelled.
 
     This method does not block.
 
@@ -120,11 +119,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         not limited to this object's cancel method not having been called and
         the computation's result having become immediately available.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def running(self):
-    """Describes whether the computation is taking place.
+    @abc.abstractmethod
+    def running(self):
+        """Describes whether the computation is taking place.
 
     This method does not block.
 
@@ -133,15 +132,15 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         taking place now, or False if the computation took place in the past or
         was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  # NOTE(nathaniel): These aren't quite the semantics I'd like here either. I
-  # would rather this only returned True in cases in which the underlying
-  # computation completed successfully. A computation's having been cancelled
-  # conflicts with considering that computation "done".
-  @abc.abstractmethod
-  def done(self):
-    """Describes whether the computation has taken place.
+    # NOTE(nathaniel): These aren't quite the semantics I'd like here either. I
+    # would rather this only returned True in cases in which the underlying
+    # computation completed successfully. A computation's having been cancelled
+    # conflicts with considering that computation "done".
+    @abc.abstractmethod
+    def done(self):
+        """Describes whether the computation has taken place.
 
     This method does not block.
 
@@ -150,11 +149,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         unscheduled or interrupted. False if the computation may possibly be
         executing or scheduled to execute later.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def result(self, timeout=None):
-    """Accesses the outcome of the computation or raises its exception.
+    @abc.abstractmethod
+    def result(self, timeout=None):
+        """Accesses the outcome of the computation or raises its exception.
 
     This method may return immediately or may block.
 
@@ -173,11 +172,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
       Exception: If the computation raised an exception, this call will raise
         the same exception.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def exception(self, timeout=None):
-    """Return the exception raised by the computation.
+    @abc.abstractmethod
+    def exception(self, timeout=None):
+        """Return the exception raised by the computation.
 
     This method may return immediately or may block.
 
@@ -196,11 +195,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         terminate within the allotted time.
       CancelledError: If the computation was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def traceback(self, timeout=None):
-    """Access the traceback of the exception raised by the computation.
+    @abc.abstractmethod
+    def traceback(self, timeout=None):
+        """Access the traceback of the exception raised by the computation.
 
     This method may return immediately or may block.
 
@@ -219,11 +218,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
         terminate within the allotted time.
       CancelledError: If the computation was cancelled.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_done_callback(self, fn):
-    """Adds a function to be called at completion of the computation.
+    @abc.abstractmethod
+    def add_done_callback(self, fn):
+        """Adds a function to be called at completion of the computation.
 
     The callback will be passed this Future object describing the outcome of
     the computation.
@@ -234,4 +233,4 @@ class Future(six.with_metaclass(abc.ABCMeta)):
     Args:
       fn: A callable taking this Future object as its single parameter.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index 9b469a1452..9164173d34 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -26,7 +26,6 @@
 # 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.
-
 """A thread pool that logs exceptions raised by tasks executed within it."""
 
 import logging
@@ -35,42 +34,46 @@ from concurrent import futures
 
 
 def _wrap(behavior):
-  """Wraps an arbitrary callable behavior in exception-logging."""
-  def _wrapping(*args, **kwargs):
-    try:
-      return behavior(*args, **kwargs)
-    except Exception as e:
-      logging.exception(
-          'Unexpected exception from %s executed in logging pool!', behavior)
-      raise
-  return _wrapping
+    """Wraps an arbitrary callable behavior in exception-logging."""
+
+    def _wrapping(*args, **kwargs):
+        try:
+            return behavior(*args, **kwargs)
+        except Exception as e:
+            logging.exception(
+                'Unexpected exception from %s executed in logging pool!',
+                behavior)
+            raise
+
+    return _wrapping
 
 
 class _LoggingPool(object):
-  """An exception-logging futures.ThreadPoolExecutor-compatible thread pool."""
+    """An exception-logging futures.ThreadPoolExecutor-compatible thread pool."""
 
-  def __init__(self, backing_pool):
-    self._backing_pool = backing_pool
+    def __init__(self, backing_pool):
+        self._backing_pool = backing_pool
 
-  def __enter__(self):
-    return self
+    def __enter__(self):
+        return self
 
-  def __exit__(self, exc_type, exc_val, exc_tb):
-    self._backing_pool.shutdown(wait=True)
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self._backing_pool.shutdown(wait=True)
 
-  def submit(self, fn, *args, **kwargs):
-    return self._backing_pool.submit(_wrap(fn), *args, **kwargs)
+    def submit(self, fn, *args, **kwargs):
+        return self._backing_pool.submit(_wrap(fn), *args, **kwargs)
 
-  def map(self, func, *iterables, **kwargs):
-    return self._backing_pool.map(
-        _wrap(func), *iterables, timeout=kwargs.get('timeout', None))
+    def map(self, func, *iterables, **kwargs):
+        return self._backing_pool.map(_wrap(func),
+                                      *iterables,
+                                      timeout=kwargs.get('timeout', None))
 
-  def shutdown(self, wait=True):
-    self._backing_pool.shutdown(wait=wait)
+    def shutdown(self, wait=True):
+        self._backing_pool.shutdown(wait=wait)
 
 
 def pool(max_workers):
-  """Creates a thread pool that logs exceptions raised by the tasks within it.
+    """Creates a thread pool that logs exceptions raised by the tasks within it.
 
   Args:
     max_workers: The maximum number of worker threads to allow the pool.
@@ -79,4 +82,4 @@ def pool(max_workers):
     A futures.ThreadPoolExecutor-compatible thread pool that logs exceptions
       raised by the tasks executed within it.
   """
-  return _LoggingPool(futures.ThreadPoolExecutor(max_workers))
+    return _LoggingPool(futures.ThreadPoolExecutor(max_workers))
diff --git a/src/python/grpcio/grpc/framework/foundation/stream.py b/src/python/grpcio/grpc/framework/foundation/stream.py
index ddd6cc496a..2529a6944b 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream.py
@@ -26,35 +26,35 @@
 # 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.
-
 """Interfaces related to streams of values or objects."""
 
 import abc
 
 import six
 
+
 class Consumer(six.with_metaclass(abc.ABCMeta)):
-  """Interface for consumers of finite streams of values or objects."""
+    """Interface for consumers of finite streams of values or objects."""
 
-  @abc.abstractmethod
-  def consume(self, value):
-    """Accepts a value.
+    @abc.abstractmethod
+    def consume(self, value):
+        """Accepts a value.
 
     Args:
       value: Any value accepted by this Consumer.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def terminate(self):
-    """Indicates to this Consumer that no more values will be supplied."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def terminate(self):
+        """Indicates to this Consumer that no more values will be supplied."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def consume_and_terminate(self, value):
-    """Supplies a value and signals that no more values will be supplied.
+    @abc.abstractmethod
+    def consume_and_terminate(self, value):
+        """Supplies a value and signals that no more values will be supplied.
 
     Args:
       value: Any value accepted by this Consumer.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py
index a6f234f1fe..6b356f176f 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Helpful utilities related to the stream module."""
 
 import logging
@@ -38,126 +37,126 @@ _NO_VALUE = object()
 
 
 class TransformingConsumer(stream.Consumer):
-  """A stream.Consumer that passes a transformation of its input to another."""
+    """A stream.Consumer that passes a transformation of its input to another."""
 
-  def __init__(self, transformation, downstream):
-    self._transformation = transformation
-    self._downstream = downstream
+    def __init__(self, transformation, downstream):
+        self._transformation = transformation
+        self._downstream = downstream
 
-  def consume(self, value):
-    self._downstream.consume(self._transformation(value))
+    def consume(self, value):
+        self._downstream.consume(self._transformation(value))
 
-  def terminate(self):
-    self._downstream.terminate()
+    def terminate(self):
+        self._downstream.terminate()
 
-  def consume_and_terminate(self, value):
-    self._downstream.consume_and_terminate(self._transformation(value))
+    def consume_and_terminate(self, value):
+        self._downstream.consume_and_terminate(self._transformation(value))
 
 
 class IterableConsumer(stream.Consumer):
-  """A Consumer that when iterated over emits the values it has consumed."""
-
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._values = []
-    self._active = True
-
-  def consume(self, stock_reply):
-    with self._condition:
-      if self._active:
-        self._values.append(stock_reply)
-        self._condition.notify()
-
-  def terminate(self):
-    with self._condition:
-      self._active = False
-      self._condition.notify()
-
-  def consume_and_terminate(self, stock_reply):
-    with self._condition:
-      if self._active:
-        self._values.append(stock_reply)
-        self._active = False
-        self._condition.notify()
-
-  def __iter__(self):
-    return self
-
-  def __next__(self):
-    return self.next()
-
-  def next(self):
-    with self._condition:
-      while self._active and not self._values:
-        self._condition.wait()
-      if self._values:
-        return self._values.pop(0)
-      else:
-        raise StopIteration()
+    """A Consumer that when iterated over emits the values it has consumed."""
+
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._values = []
+        self._active = True
+
+    def consume(self, stock_reply):
+        with self._condition:
+            if self._active:
+                self._values.append(stock_reply)
+                self._condition.notify()
+
+    def terminate(self):
+        with self._condition:
+            self._active = False
+            self._condition.notify()
+
+    def consume_and_terminate(self, stock_reply):
+        with self._condition:
+            if self._active:
+                self._values.append(stock_reply)
+                self._active = False
+                self._condition.notify()
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        return self.next()
+
+    def next(self):
+        with self._condition:
+            while self._active and not self._values:
+                self._condition.wait()
+            if self._values:
+                return self._values.pop(0)
+            else:
+                raise StopIteration()
 
 
 class ThreadSwitchingConsumer(stream.Consumer):
-  """A Consumer decorator that affords serialization and asynchrony."""
-
-  def __init__(self, sink, pool):
-    self._lock = threading.Lock()
-    self._sink = sink
-    self._pool = pool
-    # True if self._spin has been submitted to the pool to be called once and
-    # that call has not yet returned, False otherwise.
-    self._spinning = False
-    self._values = []
-    self._active = True
-
-  def _spin(self, sink, value, terminate):
-    while True:
-      try:
-        if value is _NO_VALUE:
-          sink.terminate()
-        elif terminate:
-          sink.consume_and_terminate(value)
-        else:
-          sink.consume(value)
-      except Exception as e:  # pylint:disable=broad-except
-        logging.exception(e)
-
-      with self._lock:
-        if terminate:
-          self._spinning = False
-          return
-        elif self._values:
-          value = self._values.pop(0)
-          terminate = not self._values and not self._active
-        elif not self._active:
-          value = _NO_VALUE
-          terminate = True
-        else:
-          self._spinning = False
-          return
-
-  def consume(self, value):
-    with self._lock:
-      if self._active:
-        if self._spinning:
-          self._values.append(value)
-        else:
-          self._pool.submit(self._spin, self._sink, value, False)
-          self._spinning = True
-
-  def terminate(self):
-    with self._lock:
-      if self._active:
-        self._active = False
-        if not self._spinning:
-          self._pool.submit(self._spin, self._sink, _NO_VALUE, True)
-          self._spinning = True
-
-  def consume_and_terminate(self, value):
-    with self._lock:
-      if self._active:
-        self._active = False
-        if self._spinning:
-          self._values.append(value)
-        else:
-          self._pool.submit(self._spin, self._sink, value, True)
-          self._spinning = True
+    """A Consumer decorator that affords serialization and asynchrony."""
+
+    def __init__(self, sink, pool):
+        self._lock = threading.Lock()
+        self._sink = sink
+        self._pool = pool
+        # True if self._spin has been submitted to the pool to be called once and
+        # that call has not yet returned, False otherwise.
+        self._spinning = False
+        self._values = []
+        self._active = True
+
+    def _spin(self, sink, value, terminate):
+        while True:
+            try:
+                if value is _NO_VALUE:
+                    sink.terminate()
+                elif terminate:
+                    sink.consume_and_terminate(value)
+                else:
+                    sink.consume(value)
+            except Exception as e:  # pylint:disable=broad-except
+                logging.exception(e)
+
+            with self._lock:
+                if terminate:
+                    self._spinning = False
+                    return
+                elif self._values:
+                    value = self._values.pop(0)
+                    terminate = not self._values and not self._active
+                elif not self._active:
+                    value = _NO_VALUE
+                    terminate = True
+                else:
+                    self._spinning = False
+                    return
+
+    def consume(self, value):
+        with self._lock:
+            if self._active:
+                if self._spinning:
+                    self._values.append(value)
+                else:
+                    self._pool.submit(self._spin, self._sink, value, False)
+                    self._spinning = True
+
+    def terminate(self):
+        with self._lock:
+            if self._active:
+                self._active = False
+                if not self._spinning:
+                    self._pool.submit(self._spin, self._sink, _NO_VALUE, True)
+                    self._spinning = True
+
+    def consume_and_terminate(self, value):
+        with self._lock:
+            if self._active:
+                self._active = False
+                if self._spinning:
+                    self._values.append(value)
+                else:
+                    self._pool.submit(self._spin, self._sink, value, True)
+                    self._spinning = True
diff --git a/src/python/grpcio/grpc/framework/interfaces/__init__.py b/src/python/grpcio/grpc/framework/interfaces/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/__init__.py b/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py
index a2ddd9c474..cb3328296c 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/base.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py
@@ -26,7 +26,6 @@
 # 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.
-
 """The base interface of RPC Framework.
 
 Implementations of this interface support the conduct of "operations":
@@ -49,7 +48,7 @@ from grpc.framework.foundation import abandonment  # pylint: disable=unused-impo
 
 
 class NoSuchMethodError(Exception):
-  """Indicates that an unrecognized operation has been called.
+    """Indicates that an unrecognized operation has been called.
 
   Attributes:
     code: A code value to communicate to the other side of the operation along
@@ -58,8 +57,8 @@ class NoSuchMethodError(Exception):
       along with indication of operation termination. May be None.
   """
 
-  def __init__(self, code, details):
-    """Constructor.
+    def __init__(self, code, details):
+        """Constructor.
 
     Args:
       code: A code value to communicate to the other side of the operation
@@ -67,12 +66,12 @@ class NoSuchMethodError(Exception):
       details: A details value to communicate to the other side of the
         operation along with indication of operation termination. May be None.
     """
-    self.code = code
-    self.details = details
+        self.code = code
+        self.details = details
 
 
 class Outcome(object):
-  """The outcome of an operation.
+    """The outcome of an operation.
 
   Attributes:
     kind: A Kind value coarsely identifying how the operation terminated.
@@ -82,23 +81,23 @@ class Outcome(object):
       provided.
   """
 
-  @enum.unique
-  class Kind(enum.Enum):
-    """Ways in which an operation can terminate."""
+    @enum.unique
+    class Kind(enum.Enum):
+        """Ways in which an operation can terminate."""
 
-    COMPLETED = 'completed'
-    CANCELLED = 'cancelled'
-    EXPIRED = 'expired'
-    LOCAL_SHUTDOWN = 'local shutdown'
-    REMOTE_SHUTDOWN = 'remote shutdown'
-    RECEPTION_FAILURE = 'reception failure'
-    TRANSMISSION_FAILURE = 'transmission failure'
-    LOCAL_FAILURE = 'local failure'
-    REMOTE_FAILURE = 'remote failure'
+        COMPLETED = 'completed'
+        CANCELLED = 'cancelled'
+        EXPIRED = 'expired'
+        LOCAL_SHUTDOWN = 'local shutdown'
+        REMOTE_SHUTDOWN = 'remote shutdown'
+        RECEPTION_FAILURE = 'reception failure'
+        TRANSMISSION_FAILURE = 'transmission failure'
+        LOCAL_FAILURE = 'local failure'
+        REMOTE_FAILURE = 'remote failure'
 
 
 class Completion(six.with_metaclass(abc.ABCMeta)):
-  """An aggregate of the values exchanged upon operation completion.
+    """An aggregate of the values exchanged upon operation completion.
 
   Attributes:
     terminal_metadata: A terminal metadata value for the operaton.
@@ -108,21 +107,21 @@ class Completion(six.with_metaclass(abc.ABCMeta)):
 
 
 class OperationContext(six.with_metaclass(abc.ABCMeta)):
-  """Provides operation-related information and action."""
+    """Provides operation-related information and action."""
 
-  @abc.abstractmethod
-  def outcome(self):
-    """Indicates the operation's outcome (or that the operation is ongoing).
+    @abc.abstractmethod
+    def outcome(self):
+        """Indicates the operation's outcome (or that the operation is ongoing).
 
     Returns:
       None if the operation is still active or the Outcome value for the
         operation if it has terminated.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_termination_callback(self, callback):
-    """Adds a function to be called upon operation termination.
+    @abc.abstractmethod
+    def add_termination_callback(self, callback):
+        """Adds a function to be called upon operation termination.
 
     Args:
       callback: A callable to be passed an Outcome value on operation
@@ -134,42 +133,44 @@ class OperationContext(six.with_metaclass(abc.ABCMeta)):
         terminated an Outcome value describing the operation termination and the
         passed callback will not be called as a result of this method call.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def time_remaining(self):
-    """Describes the length of allowed time remaining for the operation.
+    @abc.abstractmethod
+    def time_remaining(self):
+        """Describes the length of allowed time remaining for the operation.
 
     Returns:
       A nonnegative float indicating the length of allowed time in seconds
       remaining for the operation to complete before it is considered to have
       timed out. Zero is returned if the operation has terminated.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def cancel(self):
-    """Cancels the operation if the operation has not yet terminated."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def cancel(self):
+        """Cancels the operation if the operation has not yet terminated."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def fail(self, exception):
-    """Indicates that the operation has failed.
+    @abc.abstractmethod
+    def fail(self, exception):
+        """Indicates that the operation has failed.
 
     Args:
       exception: An exception germane to the operation failure. May be None.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class Operator(six.with_metaclass(abc.ABCMeta)):
-  """An interface through which to participate in an operation."""
+    """An interface through which to participate in an operation."""
 
-  @abc.abstractmethod
-  def advance(
-      self, initial_metadata=None, payload=None, completion=None,
-      allowance=None):
-    """Progresses the operation.
+    @abc.abstractmethod
+    def advance(self,
+                initial_metadata=None,
+                payload=None,
+                completion=None,
+                allowance=None):
+        """Progresses the operation.
 
     Args:
       initial_metadata: An initial metadata value. Only one may ever be
@@ -181,23 +182,24 @@ class Operator(six.with_metaclass(abc.ABCMeta)):
       allowance: A positive integer communicating the number of additional
         payloads allowed to be passed by the remote side of the operation.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
+
 
 class ProtocolReceiver(six.with_metaclass(abc.ABCMeta)):
-  """A means of receiving protocol values during an operation."""
+    """A means of receiving protocol values during an operation."""
 
-  @abc.abstractmethod
-  def context(self, protocol_context):
-    """Accepts the protocol context object for the operation.
+    @abc.abstractmethod
+    def context(self, protocol_context):
+        """Accepts the protocol context object for the operation.
 
     Args:
       protocol_context: The protocol context object for the operation.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class Subscription(six.with_metaclass(abc.ABCMeta)):
-  """Describes customer code's interest in values from the other side.
+    """Describes customer code's interest in values from the other side.
 
   Attributes:
     kind: A Kind value describing the overall kind of this value.
@@ -215,20 +217,20 @@ class Subscription(six.with_metaclass(abc.ABCMeta)):
       Kind.FULL.
   """
 
-  @enum.unique
-  class Kind(enum.Enum):
+    @enum.unique
+    class Kind(enum.Enum):
 
-    NONE = 'none'
-    TERMINATION_ONLY = 'termination only'
-    FULL = 'full'
+        NONE = 'none'
+        TERMINATION_ONLY = 'termination only'
+        FULL = 'full'
 
 
 class Servicer(six.with_metaclass(abc.ABCMeta)):
-  """Interface for service implementations."""
+    """Interface for service implementations."""
 
-  @abc.abstractmethod
-  def service(self, group, method, context, output_operator):
-    """Services an operation.
+    @abc.abstractmethod
+    def service(self, group, method, context, output_operator):
+        """Services an operation.
 
     Args:
       group: The group identifier of the operation to be serviced.
@@ -248,20 +250,20 @@ class Servicer(six.with_metaclass(abc.ABCMeta)):
       abandonment.Abandoned: If the operation has been aborted and there no
         longer is any reason to service the operation.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class End(six.with_metaclass(abc.ABCMeta)):
-  """Common type for entry-point objects on both sides of an operation."""
+    """Common type for entry-point objects on both sides of an operation."""
 
-  @abc.abstractmethod
-  def start(self):
-    """Starts this object's service of operations."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def start(self):
+        """Starts this object's service of operations."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stop(self, grace):
-    """Stops this object's service of operations.
+    @abc.abstractmethod
+    def stop(self, grace):
+        """Stops this object's service of operations.
 
     This object will refuse service of new operations as soon as this method is
     called but operations under way at the time of the call may be given a
@@ -281,13 +283,19 @@ class End(six.with_metaclass(abc.ABCMeta)):
         much sooner (if for example this End had no operations in progress at
         the time its stop method was called).
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def operate(
-      self, group, method, subscription, timeout, initial_metadata=None,
-      payload=None, completion=None, protocol_options=None):
-    """Commences an operation.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def operate(self,
+                group,
+                method,
+                subscription,
+                timeout,
+                initial_metadata=None,
+                payload=None,
+                completion=None,
+                protocol_options=None):
+        """Commences an operation.
 
     Args:
       group: The group identifier of the invoked operation.
@@ -312,23 +320,23 @@ class End(six.with_metaclass(abc.ABCMeta)):
         returned pair is an Operator to which operation values not passed in
         this call should later be passed.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def operation_stats(self):
-    """Reports the number of terminated operations broken down by outcome.
+    @abc.abstractmethod
+    def operation_stats(self):
+        """Reports the number of terminated operations broken down by outcome.
 
     Returns:
       A dictionary from Outcome.Kind value to an integer identifying the number
         of operations that terminated with that outcome kind.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_idle_action(self, action):
-    """Adds an action to be called when this End has no ongoing operations.
+    @abc.abstractmethod
+    def add_idle_action(self, action):
+        """Adds an action to be called when this End has no ongoing operations.
 
     Args:
       action: A callable that accepts no arguments.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/utilities.py b/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
index 87a85018f5..461706ff9f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Utilities for use with the base interface of RPC Framework."""
 
 import collections
@@ -34,27 +33,30 @@ import collections
 from grpc.framework.interfaces.base import base
 
 
-class _Completion(
-    base.Completion,
-    collections.namedtuple(
-        '_Completion', ('terminal_metadata', 'code', 'message',))):
-  """A trivial implementation of base.Completion."""
+class _Completion(base.Completion,
+                  collections.namedtuple('_Completion', (
+                      'terminal_metadata',
+                      'code',
+                      'message',))):
+    """A trivial implementation of base.Completion."""
+
 
+class _Subscription(base.Subscription,
+                    collections.namedtuple('_Subscription', (
+                        'kind',
+                        'termination_callback',
+                        'allowance',
+                        'operator',
+                        'protocol_receiver',))):
+    """A trivial implementation of base.Subscription."""
 
-class _Subscription(
-    base.Subscription,
-    collections.namedtuple(
-        '_Subscription',
-        ('kind', 'termination_callback', 'allowance', 'operator',
-         'protocol_receiver',))):
-  """A trivial implementation of base.Subscription."""
 
-_NONE_SUBSCRIPTION = _Subscription(
-    base.Subscription.Kind.NONE, None, None, None, None)
+_NONE_SUBSCRIPTION = _Subscription(base.Subscription.Kind.NONE, None, None,
+                                   None, None)
 
 
 def completion(terminal_metadata, code, message):
-  """Creates a base.Completion aggregating the given operation values.
+    """Creates a base.Completion aggregating the given operation values.
 
   Args:
     terminal_metadata: A terminal metadata value for an operaton.
@@ -64,11 +66,11 @@ def completion(terminal_metadata, code, message):
   Returns:
     A base.Completion aggregating the given operation values.
   """
-  return _Completion(terminal_metadata, code, message)
+    return _Completion(terminal_metadata, code, message)
 
 
 def full_subscription(operator, protocol_receiver):
-  """Creates a "full" base.Subscription for the given base.Operator.
+    """Creates a "full" base.Subscription for the given base.Operator.
 
   Args:
     operator: A base.Operator to be used in an operation.
@@ -78,5 +80,5 @@ def full_subscription(operator, protocol_receiver):
     A base.Subscription of kind base.Subscription.Kind.FULL wrapping the given
       base.Operator and base.ProtocolReceiver.
   """
-  return _Subscription(
-      base.Subscription.Kind.FULL, None, None, operator, protocol_receiver)
+    return _Subscription(base.Subscription.Kind.FULL, None, None, operator,
+                         protocol_receiver)
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/__init__.py b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
index 4826e7fff6..36ddca18c1 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/face.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Interfaces defining the Face layer of RPC Framework."""
 
 import abc
@@ -45,33 +44,38 @@ from grpc.framework.foundation import stream  # pylint: disable=unused-import
 
 
 class NoSuchMethodError(Exception):
-  """Raised by customer code to indicate an unrecognized method.
+    """Raised by customer code to indicate an unrecognized method.
 
   Attributes:
     group: The group of the unrecognized method.
     name: The name of the unrecognized method.
   """
 
-  def __init__(self, group, method):
-    """Constructor.
+    def __init__(self, group, method):
+        """Constructor.
 
     Args:
       group: The group identifier of the unrecognized RPC name.
       method: The method identifier of the unrecognized RPC name.
     """
-    super(NoSuchMethodError, self).__init__()
-    self.group = group
-    self.method = method
+        super(NoSuchMethodError, self).__init__()
+        self.group = group
+        self.method = method
 
-  def __repr__(self):
-    return 'face.NoSuchMethodError(%s, %s)' % (self.group, self.method,)
+    def __repr__(self):
+        return 'face.NoSuchMethodError(%s, %s)' % (
+            self.group,
+            self.method,)
 
 
 class Abortion(
-    collections.namedtuple(
-        'Abortion',
-        ('kind', 'initial_metadata', 'terminal_metadata', 'code', 'details',))):
-  """A value describing RPC abortion.
+        collections.namedtuple('Abortion', (
+            'kind',
+            'initial_metadata',
+            'terminal_metadata',
+            'code',
+            'details',))):
+    """A value describing RPC abortion.
 
   Attributes:
     kind: A Kind value identifying how the RPC failed.
@@ -85,21 +89,21 @@ class Abortion(
       details value was received.
   """
 
-  @enum.unique
-  class Kind(enum.Enum):
-    """Types of RPC abortion."""
+    @enum.unique
+    class Kind(enum.Enum):
+        """Types of RPC abortion."""
 
-    CANCELLED = 'cancelled'
-    EXPIRED = 'expired'
-    LOCAL_SHUTDOWN = 'local shutdown'
-    REMOTE_SHUTDOWN = 'remote shutdown'
-    NETWORK_FAILURE = 'network failure'
-    LOCAL_FAILURE = 'local failure'
-    REMOTE_FAILURE = 'remote failure'
+        CANCELLED = 'cancelled'
+        EXPIRED = 'expired'
+        LOCAL_SHUTDOWN = 'local shutdown'
+        REMOTE_SHUTDOWN = 'remote shutdown'
+        NETWORK_FAILURE = 'network failure'
+        LOCAL_FAILURE = 'local failure'
+        REMOTE_FAILURE = 'remote failure'
 
 
 class AbortionError(six.with_metaclass(abc.ABCMeta, Exception)):
-  """Common super type for exceptions indicating RPC abortion.
+    """Common super type for exceptions indicating RPC abortion.
 
     initial_metadata: The initial metadata from the other side of the RPC or
       None if no initial metadata value was received.
@@ -111,100 +115,100 @@ class AbortionError(six.with_metaclass(abc.ABCMeta, Exception)):
       details value was received.
   """
 
-  def __init__(self, initial_metadata, terminal_metadata, code, details):
-    super(AbortionError, self).__init__()
-    self.initial_metadata = initial_metadata
-    self.terminal_metadata = terminal_metadata
-    self.code = code
-    self.details = details
+    def __init__(self, initial_metadata, terminal_metadata, code, details):
+        super(AbortionError, self).__init__()
+        self.initial_metadata = initial_metadata
+        self.terminal_metadata = terminal_metadata
+        self.code = code
+        self.details = details
 
-  def __str__(self):
-    return '%s(code=%s, details="%s")' % (
-        self.__class__.__name__, self.code, self.details)
+    def __str__(self):
+        return '%s(code=%s, details="%s")' % (self.__class__.__name__,
+                                              self.code, self.details)
 
 
 class CancellationError(AbortionError):
-  """Indicates that an RPC has been cancelled."""
+    """Indicates that an RPC has been cancelled."""
 
 
 class ExpirationError(AbortionError):
-  """Indicates that an RPC has expired ("timed out")."""
+    """Indicates that an RPC has expired ("timed out")."""
 
 
 class LocalShutdownError(AbortionError):
-  """Indicates that an RPC has terminated due to local shutdown of RPCs."""
+    """Indicates that an RPC has terminated due to local shutdown of RPCs."""
 
 
 class RemoteShutdownError(AbortionError):
-  """Indicates that an RPC has terminated due to remote shutdown of RPCs."""
+    """Indicates that an RPC has terminated due to remote shutdown of RPCs."""
 
 
 class NetworkError(AbortionError):
-  """Indicates that some error occurred on the network."""
+    """Indicates that some error occurred on the network."""
 
 
 class LocalError(AbortionError):
-  """Indicates that an RPC has terminated due to a local defect."""
+    """Indicates that an RPC has terminated due to a local defect."""
 
 
 class RemoteError(AbortionError):
-  """Indicates that an RPC has terminated due to a remote defect."""
+    """Indicates that an RPC has terminated due to a remote defect."""
 
 
 class RpcContext(six.with_metaclass(abc.ABCMeta)):
-  """Provides RPC-related information and action."""
+    """Provides RPC-related information and action."""
 
-  @abc.abstractmethod
-  def is_active(self):
-    """Describes whether the RPC is active or has terminated."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def is_active(self):
+        """Describes whether the RPC is active or has terminated."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def time_remaining(self):
-    """Describes the length of allowed time remaining for the RPC.
+    @abc.abstractmethod
+    def time_remaining(self):
+        """Describes the length of allowed time remaining for the RPC.
 
     Returns:
       A nonnegative float indicating the length of allowed time in seconds
       remaining for the RPC to complete before it is considered to have timed
       out.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def add_abortion_callback(self, abortion_callback):
-    """Registers a callback to be called if the RPC is aborted.
+    @abc.abstractmethod
+    def add_abortion_callback(self, abortion_callback):
+        """Registers a callback to be called if the RPC is aborted.
 
     Args:
       abortion_callback: A callable to be called and passed an Abortion value
         in the event of RPC abortion.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def cancel(self):
-    """Cancels the RPC.
+    @abc.abstractmethod
+    def cancel(self):
+        """Cancels the RPC.
 
     Idempotent and has no effect if the RPC has already terminated.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def protocol_context(self):
-    """Accesses a custom object specified by an implementation provider.
+    @abc.abstractmethod
+    def protocol_context(self):
+        """Accesses a custom object specified by an implementation provider.
 
     Returns:
       A value specified by the provider of a Face interface implementation
         affording custom state and behavior.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
-  """Invocation-side utility object for an RPC."""
+    """Invocation-side utility object for an RPC."""
 
-  @abc.abstractmethod
-  def initial_metadata(self):
-    """Accesses the initial metadata from the service-side of the RPC.
+    @abc.abstractmethod
+    def initial_metadata(self):
+        """Accesses the initial metadata from the service-side of the RPC.
 
     This method blocks until the value is available or is known not to have been
     emitted from the service-side of the RPC.
@@ -213,11 +217,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
       The initial metadata object emitted by the service-side of the RPC, or
         None if there was no such value.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def terminal_metadata(self):
-    """Accesses the terminal metadata from the service-side of the RPC.
+    @abc.abstractmethod
+    def terminal_metadata(self):
+        """Accesses the terminal metadata from the service-side of the RPC.
 
     This method blocks until the value is available or is known not to have been
     emitted from the service-side of the RPC.
@@ -226,11 +230,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
       The terminal metadata object emitted by the service-side of the RPC, or
         None if there was no such value.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def code(self):
-    """Accesses the code emitted by the service-side of the RPC.
+    @abc.abstractmethod
+    def code(self):
+        """Accesses the code emitted by the service-side of the RPC.
 
     This method blocks until the value is available or is known not to have been
     emitted from the service-side of the RPC.
@@ -239,11 +243,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
       The code object emitted by the service-side of the RPC, or None if there
         was no such value.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def details(self):
-    """Accesses the details value emitted by the service-side of the RPC.
+    @abc.abstractmethod
+    def details(self):
+        """Accesses the details value emitted by the service-side of the RPC.
 
     This method blocks until the value is available or is known not to have been
     emitted from the service-side of the RPC.
@@ -252,15 +256,15 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
       The details value emitted by the service-side of the RPC, or None if there
         was no such value.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
-  """A context object passed to method implementations."""
+    """A context object passed to method implementations."""
 
-  @abc.abstractmethod
-  def invocation_metadata(self):
-    """Accesses the metadata from the invocation-side of the RPC.
+    @abc.abstractmethod
+    def invocation_metadata(self):
+        """Accesses the metadata from the invocation-side of the RPC.
 
     This method blocks until the value is available or is known not to have been
     emitted from the invocation-side of the RPC.
@@ -269,11 +273,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       The metadata object emitted by the invocation-side of the RPC, or None if
         there was no such value.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def initial_metadata(self, initial_metadata):
-    """Accepts the service-side initial metadata value of the RPC.
+    @abc.abstractmethod
+    def initial_metadata(self, initial_metadata):
+        """Accepts the service-side initial metadata value of the RPC.
 
     This method need not be called by method implementations if they have no
     service-side initial metadata to transmit.
@@ -282,11 +286,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       initial_metadata: The service-side initial metadata value of the RPC to
         be transmitted to the invocation side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def terminal_metadata(self, terminal_metadata):
-    """Accepts the service-side terminal metadata value of the RPC.
+    @abc.abstractmethod
+    def terminal_metadata(self, terminal_metadata):
+        """Accepts the service-side terminal metadata value of the RPC.
 
     This method need not be called by method implementations if they have no
     service-side terminal metadata to transmit.
@@ -295,11 +299,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       terminal_metadata: The service-side terminal metadata value of the RPC to
         be transmitted to the invocation side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def code(self, code):
-    """Accepts the service-side code of the RPC.
+    @abc.abstractmethod
+    def code(self, code):
+        """Accepts the service-side code of the RPC.
 
     This method need not be called by method implementations if they have no
     code to transmit.
@@ -308,11 +312,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       code: The code of the RPC to be transmitted to the invocation side of the
         RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def details(self, details):
-    """Accepts the service-side details of the RPC.
+    @abc.abstractmethod
+    def details(self, details):
+        """Accepts the service-side details of the RPC.
 
     This method need not be called by method implementations if they have no
     service-side details to transmit.
@@ -321,34 +325,34 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
       details: The service-side details value of the RPC to be transmitted to
         the invocation side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class ResponseReceiver(six.with_metaclass(abc.ABCMeta)):
-  """Invocation-side object used to accept the output of an RPC."""
+    """Invocation-side object used to accept the output of an RPC."""
 
-  @abc.abstractmethod
-  def initial_metadata(self, initial_metadata):
-    """Receives the initial metadata from the service-side of the RPC.
+    @abc.abstractmethod
+    def initial_metadata(self, initial_metadata):
+        """Receives the initial metadata from the service-side of the RPC.
 
     Args:
       initial_metadata: The initial metadata object emitted from the
         service-side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def response(self, response):
-    """Receives a response from the service-side of the RPC.
+    @abc.abstractmethod
+    def response(self, response):
+        """Receives a response from the service-side of the RPC.
 
     Args:
       response: A response object emitted from the service-side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def complete(self, terminal_metadata, code, details):
-    """Receives the completion values emitted from the service-side of the RPC.
+    @abc.abstractmethod
+    def complete(self, terminal_metadata, code, details):
+        """Receives the completion values emitted from the service-side of the RPC.
 
     Args:
       terminal_metadata: The terminal metadata object emitted from the
@@ -356,17 +360,20 @@ class ResponseReceiver(six.with_metaclass(abc.ABCMeta)):
       code: The code object emitted from the service-side of the RPC.
       details: The details object emitted from the service-side of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a unary-unary RPC in any call style."""
+    """Affords invoking a unary-unary RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(
-      self, request, timeout, metadata=None, with_call=False,
-      protocol_options=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self,
+                 request,
+                 timeout,
+                 metadata=None,
+                 with_call=False,
+                 protocol_options=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -385,11 +392,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
     Raises:
       AbortionError: Indicating that the RPC was aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def future(self, request, timeout, metadata=None, protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def future(self, request, timeout, metadata=None, protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -405,13 +412,17 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         response value of the RPC. In the event of RPC abortion, the returned
         Future's exception value will be an AbortionError.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event(
-      self, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event(self,
+              request,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -427,15 +438,15 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A Call for the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a unary-stream RPC in any call style."""
+    """Affords invoking a unary-stream RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(self, request, timeout, metadata=None, protocol_options=None):
-    """Invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self, request, timeout, metadata=None, protocol_options=None):
+        """Invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -450,13 +461,17 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         AbortionError indicating abortion of the RPC.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event(
-      self, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event(self,
+              request,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request: The request value for the RPC.
@@ -472,17 +487,20 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A Call object for the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a stream-unary RPC in any call style."""
+    """Affords invoking a stream-unary RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(
-      self, request_iterator, timeout, metadata=None,
-      with_call=False, protocol_options=None):
-    """Synchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self,
+                 request_iterator,
+                 timeout,
+                 metadata=None,
+                 with_call=False,
+                 protocol_options=None):
+        """Synchronously invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -501,12 +519,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
     Raises:
       AbortionError: Indicating that the RPC was aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def future(
-      self, request_iterator, timeout, metadata=None, protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def future(self,
+               request_iterator,
+               timeout,
+               metadata=None,
+               protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -522,13 +543,16 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
         response value of the RPC. In the event of RPC abortion, the returned
         Future's exception value will be an AbortionError.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def event(
-      self, receiver, abortion_callback, timeout, metadata=None,
-      protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def event(self,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       receiver: A ResponseReceiver to be passed the response data of the RPC.
@@ -544,16 +568,19 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
       A single object that is both a Call object for the RPC and a
         stream.Consumer to which the request values of the RPC should be passed.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
-  """Affords invoking a stream-stream RPC in any call style."""
+    """Affords invoking a stream-stream RPC in any call style."""
 
-  @abc.abstractmethod
-  def __call__(
-      self, request_iterator, timeout, metadata=None, protocol_options=None):
-    """Invokes the underlying RPC.
+    @abc.abstractmethod
+    def __call__(self,
+                 request_iterator,
+                 timeout,
+                 metadata=None,
+                 protocol_options=None):
+        """Invokes the underlying RPC.
 
     Args:
       request_iterator: An iterator that yields request values for the RPC.
@@ -568,13 +595,16 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         AbortionError indicating abortion of the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def event(
-      self, receiver, abortion_callback, timeout, metadata=None,
-      protocol_options=None):
-    """Asynchronously invokes the underlying RPC.
+    @abc.abstractmethod
+    def event(self,
+              receiver,
+              abortion_callback,
+              timeout,
+              metadata=None,
+              protocol_options=None):
+        """Asynchronously invokes the underlying RPC.
 
     Args:
       receiver: A ResponseReceiver to be passed the response data of the RPC.
@@ -590,11 +620,11 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
       A single object that is both a Call object for the RPC and a
         stream.Consumer to which the request values of the RPC should be passed.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class MethodImplementation(six.with_metaclass(abc.ABCMeta)):
-  """A sum type that describes a method implementation.
+    """A sum type that describes a method implementation.
 
   Attributes:
     cardinality: A cardinality.Cardinality value.
@@ -639,11 +669,11 @@ class MethodImplementation(six.with_metaclass(abc.ABCMeta)):
 
 
 class MultiMethodImplementation(six.with_metaclass(abc.ABCMeta)):
-  """A general type able to service many methods."""
+    """A general type able to service many methods."""
 
-  @abc.abstractmethod
-  def service(self, group, method, response_consumer, context):
-    """Services an RPC.
+    @abc.abstractmethod
+    def service(self, group, method, response_consumer, context):
+        """Services an RPC.
 
     Args:
       group: The group identifier of the RPC.
@@ -666,17 +696,22 @@ class MultiMethodImplementation(six.with_metaclass(abc.ABCMeta)):
       NoSuchMethodError: If this MultiMethod does not recognize the given group
         and name for the RPC and is not able to service the RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class GenericStub(six.with_metaclass(abc.ABCMeta)):
-  """Affords RPC invocation via generic methods."""
-
-  @abc.abstractmethod
-  def blocking_unary_unary(
-      self, group, method, request, timeout, metadata=None,
-      with_call=False, protocol_options=None):
-    """Invokes a unary-request-unary-response method.
+    """Affords RPC invocation via generic methods."""
+
+    @abc.abstractmethod
+    def blocking_unary_unary(self,
+                             group,
+                             method,
+                             request,
+                             timeout,
+                             metadata=None,
+                             with_call=False,
+                             protocol_options=None):
+        """Invokes a unary-request-unary-response method.
 
     This method blocks until either returning the response value of the RPC
     (in the event of RPC completion) or raising an exception (in the event of
@@ -700,13 +735,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Raises:
       AbortionError: Indicating that the RPC was aborted.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def future_unary_unary(
-      self, group, method, request, timeout, metadata=None,
-      protocol_options=None):
-    """Invokes a unary-request-unary-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def future_unary_unary(self,
+                           group,
+                           method,
+                           request,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        """Invokes a unary-request-unary-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -723,13 +762,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
         response value of the RPC. In the event of RPC abortion, the returned
         Future's exception value will be an AbortionError.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def inline_unary_stream(
-      self, group, method, request, timeout, metadata=None,
-      protocol_options=None):
-    """Invokes a unary-request-stream-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def inline_unary_stream(self,
+                            group,
+                            method,
+                            request,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        """Invokes a unary-request-stream-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -745,13 +788,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         AbortionError indicating abortion of the RPC.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def blocking_stream_unary(
-      self, group, method, request_iterator, timeout, metadata=None,
-      with_call=False, protocol_options=None):
-    """Invokes a stream-request-unary-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def blocking_stream_unary(self,
+                              group,
+                              method,
+                              request_iterator,
+                              timeout,
+                              metadata=None,
+                              with_call=False,
+                              protocol_options=None):
+        """Invokes a stream-request-unary-response method.
 
     This method blocks until either returning the response value of the RPC
     (in the event of RPC completion) or raising an exception (in the event of
@@ -775,13 +823,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Raises:
       AbortionError: Indicating that the RPC was aborted.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def future_stream_unary(
-      self, group, method, request_iterator, timeout, metadata=None,
-      protocol_options=None):
-    """Invokes a stream-request-unary-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def future_stream_unary(self,
+                            group,
+                            method,
+                            request_iterator,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        """Invokes a stream-request-unary-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -798,13 +850,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
         response value of the RPC. In the event of RPC abortion, the returned
         Future's exception value will be an AbortionError.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def inline_stream_stream(
-      self, group, method, request_iterator, timeout, metadata=None,
-      protocol_options=None):
-    """Invokes a stream-request-stream-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def inline_stream_stream(self,
+                             group,
+                             method,
+                             request_iterator,
+                             timeout,
+                             metadata=None,
+                             protocol_options=None):
+        """Invokes a stream-request-stream-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -820,13 +876,19 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
         values. Drawing response values from the returned iterator may raise
         AbortionError indicating abortion of the RPC.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event_unary_unary(
-      self, group, method, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Event-driven invocation of a unary-request-unary-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event_unary_unary(self,
+                          group,
+                          method,
+                          request,
+                          receiver,
+                          abortion_callback,
+                          timeout,
+                          metadata=None,
+                          protocol_options=None):
+        """Event-driven invocation of a unary-request-unary-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -843,13 +905,19 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A Call for the RPC.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event_unary_stream(
-      self, group, method, request, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Event-driven invocation of a unary-request-stream-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event_unary_stream(self,
+                           group,
+                           method,
+                           request,
+                           receiver,
+                           abortion_callback,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        """Event-driven invocation of a unary-request-stream-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -866,13 +934,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A Call for the RPC.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event_stream_unary(
-      self, group, method, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Event-driven invocation of a unary-request-unary-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event_stream_unary(self,
+                           group,
+                           method,
+                           receiver,
+                           abortion_callback,
+                           timeout,
+                           metadata=None,
+                           protocol_options=None):
+        """Event-driven invocation of a unary-request-unary-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -889,13 +962,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
       A pair of a Call object for the RPC and a stream.Consumer to which the
         request values of the RPC should be passed.
     """
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def event_stream_stream(
-      self, group, method, receiver, abortion_callback, timeout,
-      metadata=None, protocol_options=None):
-    """Event-driven invocation of a unary-request-stream-response method.
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def event_stream_stream(self,
+                            group,
+                            method,
+                            receiver,
+                            abortion_callback,
+                            timeout,
+                            metadata=None,
+                            protocol_options=None):
+        """Event-driven invocation of a unary-request-stream-response method.
 
     Args:
       group: The group identifier of the RPC.
@@ -912,11 +990,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
       A pair of a Call object for the RPC and a stream.Consumer to which the
         request values of the RPC should be passed.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unary_unary(self, group, method):
-    """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+    @abc.abstractmethod
+    def unary_unary(self, group, method):
+        """Creates a UnaryUnaryMultiCallable for a unary-unary method.
 
     Args:
       group: The group identifier of the RPC.
@@ -925,11 +1003,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A UnaryUnaryMultiCallable value for the named unary-unary method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unary_stream(self, group, method):
-    """Creates a UnaryStreamMultiCallable for a unary-stream method.
+    @abc.abstractmethod
+    def unary_stream(self, group, method):
+        """Creates a UnaryStreamMultiCallable for a unary-stream method.
 
     Args:
       group: The group identifier of the RPC.
@@ -938,11 +1016,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A UnaryStreamMultiCallable value for the name unary-stream method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_unary(self, group, method):
-    """Creates a StreamUnaryMultiCallable for a stream-unary method.
+    @abc.abstractmethod
+    def stream_unary(self, group, method):
+        """Creates a StreamUnaryMultiCallable for a stream-unary method.
 
     Args:
       group: The group identifier of the RPC.
@@ -951,11 +1029,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A StreamUnaryMultiCallable value for the named stream-unary method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_stream(self, group, method):
-    """Creates a StreamStreamMultiCallable for a stream-stream method.
+    @abc.abstractmethod
+    def stream_stream(self, group, method):
+        """Creates a StreamStreamMultiCallable for a stream-stream method.
 
     Args:
       group: The group identifier of the RPC.
@@ -964,11 +1042,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A StreamStreamMultiCallable value for the named stream-stream method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class DynamicStub(six.with_metaclass(abc.ABCMeta)):
-  """Affords RPC invocation via attributes corresponding to afforded methods.
+    """Affords RPC invocation via attributes corresponding to afforded methods.
 
   Instances of this type may be scoped to a single group so that attribute
   access is unambiguous.
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/utilities.py b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
index db2ec6ed87..39a642f0ae 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Utilities for RPC Framework's Face interface."""
 
 import collections
@@ -38,18 +37,24 @@ from grpc.framework.foundation import stream  # pylint: disable=unused-import
 from grpc.framework.interfaces.face import face
 
 
-class _MethodImplementation(
-    face.MethodImplementation,
-    collections.namedtuple(
-        '_MethodImplementation',
-        ['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
-         'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
-         'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
-  pass
+class _MethodImplementation(face.MethodImplementation,
+                            collections.namedtuple('_MethodImplementation', [
+                                'cardinality',
+                                'style',
+                                'unary_unary_inline',
+                                'unary_stream_inline',
+                                'stream_unary_inline',
+                                'stream_stream_inline',
+                                'unary_unary_event',
+                                'unary_stream_event',
+                                'stream_unary_event',
+                                'stream_stream_event',
+                            ])):
+    pass
 
 
 def unary_unary_inline(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-unary RPC method as a callable value
@@ -59,13 +64,13 @@ def unary_unary_inline(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
-      None, None, None, None, None, None, None)
+    return _MethodImplementation(cardinality.Cardinality.UNARY_UNARY,
+                                 style.Service.INLINE, behavior, None, None,
+                                 None, None, None, None, None)
 
 
 def unary_stream_inline(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-stream RPC method as a callable
@@ -75,13 +80,13 @@ def unary_stream_inline(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
-      behavior, None, None, None, None, None, None)
+    return _MethodImplementation(cardinality.Cardinality.UNARY_STREAM,
+                                 style.Service.INLINE, None, behavior, None,
+                                 None, None, None, None, None)
 
 
 def stream_unary_inline(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-unary RPC method as a callable
@@ -91,13 +96,13 @@ def stream_unary_inline(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
-      behavior, None, None, None, None, None)
+    return _MethodImplementation(cardinality.Cardinality.STREAM_UNARY,
+                                 style.Service.INLINE, None, None, behavior,
+                                 None, None, None, None, None)
 
 
 def stream_stream_inline(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-stream RPC method as a callable
@@ -107,13 +112,13 @@ def stream_stream_inline(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
-      None, behavior, None, None, None, None)
+    return _MethodImplementation(cardinality.Cardinality.STREAM_STREAM,
+                                 style.Service.INLINE, None, None, None,
+                                 behavior, None, None, None, None)
 
 
 def unary_unary_event(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-unary RPC method as a callable
@@ -123,13 +128,13 @@ def unary_unary_event(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
-      None, None, behavior, None, None, None)
+    return _MethodImplementation(cardinality.Cardinality.UNARY_UNARY,
+                                 style.Service.EVENT, None, None, None, None,
+                                 behavior, None, None, None)
 
 
 def unary_stream_event(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-stream RPC method as a callable
@@ -139,13 +144,13 @@ def unary_stream_event(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
-      None, None, None, behavior, None, None)
+    return _MethodImplementation(cardinality.Cardinality.UNARY_STREAM,
+                                 style.Service.EVENT, None, None, None, None,
+                                 None, behavior, None, None)
 
 
 def stream_unary_event(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-unary RPC method as a callable
@@ -156,13 +161,13 @@ def stream_unary_event(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
-      None, None, None, None, behavior, None)
+    return _MethodImplementation(cardinality.Cardinality.STREAM_UNARY,
+                                 style.Service.EVENT, None, None, None, None,
+                                 None, None, behavior, None)
 
 
 def stream_stream_event(behavior):
-  """Creates an face.MethodImplementation for the given behavior.
+    """Creates an face.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-stream RPC method as a callable
@@ -173,6 +178,6 @@ def stream_stream_event(behavior):
   Returns:
     An face.MethodImplementation derived from the given behavior.
   """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
-      None, None, None, None, None, behavior)
+    return _MethodImplementation(cardinality.Cardinality.STREAM_STREAM,
+                                 style.Service.EVENT, None, None, None, None,
+                                 None, None, None, behavior)
diff --git a/src/python/grpcio/support.py b/src/python/grpcio/support.py
index b226e690fd..a228ba4a48 100644
--- a/src/python/grpcio/support.py
+++ b/src/python/grpcio/support.py
@@ -27,7 +27,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 import os
 import os.path
 import shutil
@@ -38,7 +37,6 @@ from distutils import errors
 
 import commands
 
-
 C_PYTHON_DEV = """
 #include <Python.h>
 int main(int argc, char **argv) { return 0; }
@@ -55,69 +53,70 @@ Could not find <Python.h>. This could mean the following:
     (check your environment variables or try re-installing?)
 """
 
-C_CHECKS = {
-  C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE,
-}
+C_CHECKS = {C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE,}
+
 
 def _compile(compiler, source_string):
-  tempdir = tempfile.mkdtemp()
-  cpath = os.path.join(tempdir, 'a.c')
-  with open(cpath, 'w') as cfile:
-    cfile.write(source_string)
-  try:
-    compiler.compile([cpath])
-  except errors.CompileError as error:
-    return error
-  finally:
-    shutil.rmtree(tempdir)
+    tempdir = tempfile.mkdtemp()
+    cpath = os.path.join(tempdir, 'a.c')
+    with open(cpath, 'w') as cfile:
+        cfile.write(source_string)
+    try:
+        compiler.compile([cpath])
+    except errors.CompileError as error:
+        return error
+    finally:
+        shutil.rmtree(tempdir)
+
 
 def _expect_compile(compiler, source_string, error_message):
-  if _compile(compiler, source_string) is not None:
-    sys.stderr.write(error_message)
-    raise commands.CommandError(
-        "Diagnostics found a compilation environment issue:\n{}"
+    if _compile(compiler, source_string) is not None:
+        sys.stderr.write(error_message)
+        raise commands.CommandError(
+            "Diagnostics found a compilation environment issue:\n{}"
             .format(error_message))
 
+
 def diagnose_compile_error(build_ext, error):
-  """Attempt to diagnose an error during compilation."""
-  for c_check, message in C_CHECKS.items():
-    _expect_compile(build_ext.compiler, c_check, message)
-  python_sources = [
-      source for source in build_ext.get_source_files()
-      if source.startswith('./src/python') and source.endswith('c')
-  ]
-  for source in python_sources:
-    if not os.path.isfile(source):
-      raise commands.CommandError(
-          ("Diagnostics found a missing Python extension source file:\n{}\n\n"
-           "This is usually because the Cython sources haven't been transpiled "
-           "into C yet and you're building from source.\n"
-           "Try setting the environment variable "
-           "`GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking `setup.py` or "
-           "when using `pip`, e.g.:\n\n"
-           "pip install -rrequirements.txt\n"
-           "GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .")
-            .format(source)
-          )
+    """Attempt to diagnose an error during compilation."""
+    for c_check, message in C_CHECKS.items():
+        _expect_compile(build_ext.compiler, c_check, message)
+    python_sources = [
+        source for source in build_ext.get_source_files()
+        if source.startswith('./src/python') and source.endswith('c')
+    ]
+    for source in python_sources:
+        if not os.path.isfile(source):
+            raise commands.CommandError((
+                "Diagnostics found a missing Python extension source file:\n{}\n\n"
+                "This is usually because the Cython sources haven't been transpiled "
+                "into C yet and you're building from source.\n"
+                "Try setting the environment variable "
+                "`GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking `setup.py` or "
+                "when using `pip`, e.g.:\n\n"
+                "pip install -rrequirements.txt\n"
+                "GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .").format(source))
+
 
 def diagnose_attribute_error(build_ext, error):
-  if any('_needs_stub' in arg for arg in error.args):
-    raise commands.CommandError(
-        "We expect a missing `_needs_stub` attribute from older versions of "
-        "setuptools. Consider upgrading setuptools.")
+    if any('_needs_stub' in arg for arg in error.args):
+        raise commands.CommandError(
+            "We expect a missing `_needs_stub` attribute from older versions of "
+            "setuptools. Consider upgrading setuptools.")
+
 
 _ERROR_DIAGNOSES = {
     errors.CompileError: diagnose_compile_error,
     AttributeError: diagnose_attribute_error
 }
 
-def diagnose_build_ext_error(build_ext, error, formatted):
-  diagnostic = _ERROR_DIAGNOSES.get(type(error))
-  if diagnostic is None:
-    raise commands.CommandError(
-        "\n\nWe could not diagnose your build failure. Please file an issue at "
-        "http://www.github.com/grpc/grpc with `[Python install]` in the title."
-        "\n\n{}".format(formatted))
-  else:
-    diagnostic(build_ext, error)
 
+def diagnose_build_ext_error(build_ext, error, formatted):
+    diagnostic = _ERROR_DIAGNOSES.get(type(error))
+    if diagnostic is None:
+        raise commands.CommandError(
+            "\n\nWe could not diagnose your build failure. Please file an issue at "
+            "http://www.github.com/grpc/grpc with `[Python install]` in the title."
+            "\n\n{}".format(formatted))
+    else:
+        diagnostic(build_ext, error)
diff --git a/src/python/grpcio_health_checking/grpc_health/__init__.py b/src/python/grpcio_health_checking/grpc_health/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_health_checking/grpc_health/__init__.py
+++ b/src/python/grpcio_health_checking/grpc_health/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_health_checking/grpc_health/v1/__init__.py b/src/python/grpcio_health_checking/grpc_health/v1/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_health_checking/grpc_health/v1/__init__.py
+++ b/src/python/grpcio_health_checking/grpc_health/v1/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py
index 0df679b0e2..f0f11cf84b 100644
--- a/src/python/grpcio_health_checking/grpc_health/v1/health.py
+++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Reference implementation for health checking in gRPC Python."""
 
 import threading
@@ -37,23 +36,23 @@ from grpc_health.v1 import health_pb2
 
 
 class HealthServicer(health_pb2.HealthServicer):
-  """Servicer handling RPCs for service statuses."""
+    """Servicer handling RPCs for service statuses."""
 
-  def __init__(self):
-    self._server_status_lock = threading.Lock()
-    self._server_status = {}
+    def __init__(self):
+        self._server_status_lock = threading.Lock()
+        self._server_status = {}
 
-  def Check(self, request, context):
-    with self._server_status_lock:
-      status = self._server_status.get(request.service)
-      if status is None:
-        context.set_code(grpc.StatusCode.NOT_FOUND)
-        return health_pb2.HealthCheckResponse()
-      else:
-        return health_pb2.HealthCheckResponse(status=status)
+    def Check(self, request, context):
+        with self._server_status_lock:
+            status = self._server_status.get(request.service)
+            if status is None:
+                context.set_code(grpc.StatusCode.NOT_FOUND)
+                return health_pb2.HealthCheckResponse()
+            else:
+                return health_pb2.HealthCheckResponse(status=status)
 
-  def set(self, service, status):
-    """Sets the status of a service.
+    def set(self, service, status):
+        """Sets the status of a service.
 
     Args:
         service: string, the name of the service.
@@ -61,5 +60,5 @@ class HealthServicer(health_pb2.HealthServicer):
         status: HealthCheckResponse.status enum value indicating
             the status of the service
     """
-    with self._server_status_lock:
-      self._server_status[service] = status
+        with self._server_status_lock:
+            self._server_status[service] = status
diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py
index 0c420a655f..14375a74c0 100644
--- a/src/python/grpcio_health_checking/health_commands.py
+++ b/src/python/grpcio_health_checking/health_commands.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Provides distutils command classes for the GRPC Python setup process."""
 
 import os
@@ -39,40 +38,40 @@ HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto')
 
 
 class CopyProtoModules(setuptools.Command):
-  """Command to copy proto modules from grpc/src/proto."""
+    """Command to copy proto modules from grpc/src/proto."""
 
-  description = ''
-  user_options = []
+    description = ''
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    if os.path.isfile(HEALTH_PROTO):
-      shutil.copyfile(
-          HEALTH_PROTO,
-          os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto'))
+    def run(self):
+        if os.path.isfile(HEALTH_PROTO):
+            shutil.copyfile(
+                HEALTH_PROTO,
+                os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto'))
 
 
 class BuildPackageProtos(setuptools.Command):
-  """Command to generate project *_pb2.py modules from proto files."""
+    """Command to generate project *_pb2.py modules from proto files."""
 
-  description = 'build grpc protobuf modules'
-  user_options = []
+    description = 'build grpc protobuf modules'
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    # due to limitations of the proto generator, we require that only *one*
-    # directory is provided as an 'include' directory. We assume it's the '' key
-    # to `self.distribution.package_dir` (and get a key error if it's not
-    # there).
-    from grpc_tools import command
-    command.build_package_protos(self.distribution.package_dir[''])
+    def run(self):
+        # due to limitations of the proto generator, we require that only *one*
+        # directory is provided as an 'include' directory. We assume it's the '' key
+        # to `self.distribution.package_dir` (and get a key error if it's not
+        # there).
+        from grpc_tools import command
+        command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index e88f389ba8..4c3991dcc4 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Setup module for the GRPC Python package's optional health checking."""
 
 import os
@@ -41,18 +40,14 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
 import health_commands
 import grpc_version
 
-PACKAGE_DIRECTORIES = {
-    '': '.',
-}
+PACKAGE_DIRECTORIES = {'': '.',}
 
 SETUP_REQUIRES = (
-    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
-)
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),)
 
 INSTALL_REQUIRES = (
     'protobuf>=3.0.0',
-    'grpcio>={version}'.format(version=grpc_version.VERSION),
-)
+    'grpcio>={version}'.format(version=grpc_version.VERSION),)
 
 COMMAND_CLASS = {
     # Run preprocess from the repository *before* doing any packaging!
@@ -68,5 +63,4 @@ setuptools.setup(
     packages=setuptools.find_packages('.'),
     install_requires=INSTALL_REQUIRES,
     setup_requires=SETUP_REQUIRES,
-    cmdclass=COMMAND_CLASS
-)
+    cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_reflection/grpc_reflection/__init__.py b/src/python/grpcio_reflection/grpc_reflection/__init__.py
index d5ad73a74a..100a624dc9 100644
--- a/src/python/grpcio_reflection/grpc_reflection/__init__.py
+++ b/src/python/grpcio_reflection/grpc_reflection/__init__.py
@@ -26,4 +26,3 @@
 # 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.
-
diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/__init__.py b/src/python/grpcio_reflection/grpc_reflection/v1alpha/__init__.py
index d5ad73a74a..100a624dc9 100644
--- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/__init__.py
+++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/__init__.py
@@ -26,4 +26,3 @@
 # 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.
-
diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
index bfcbce8e04..87f28396ce 100644
--- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
+++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Reference implementation for reflection in gRPC Python."""
 
 import threading
@@ -39,105 +38,96 @@ from grpc_reflection.v1alpha import reflection_pb2
 
 _POOL = descriptor_pool.Default()
 
+
 def _not_found_error():
-  return reflection_pb2.ServerReflectionResponse(
-      error_response=reflection_pb2.ErrorResponse(
-          error_code=grpc.StatusCode.NOT_FOUND.value[0],
-          error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
-      )
-  )
+    return reflection_pb2.ServerReflectionResponse(
+        error_response=reflection_pb2.ErrorResponse(
+            error_code=grpc.StatusCode.NOT_FOUND.value[0],
+            error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),))
+
 
 def _file_descriptor_response(descriptor):
-  proto = descriptor_pb2.FileDescriptorProto()
-  descriptor.CopyToProto(proto)
-  serialized_proto = proto.SerializeToString()
-  return reflection_pb2.ServerReflectionResponse(
-      file_descriptor_response=reflection_pb2.FileDescriptorResponse(
-        file_descriptor_proto=(serialized_proto,)
-      ),
-  )
+    proto = descriptor_pb2.FileDescriptorProto()
+    descriptor.CopyToProto(proto)
+    serialized_proto = proto.SerializeToString()
+    return reflection_pb2.ServerReflectionResponse(
+        file_descriptor_response=reflection_pb2.FileDescriptorResponse(
+            file_descriptor_proto=(serialized_proto,)),)
 
 
 class ReflectionServicer(reflection_pb2.ServerReflectionServicer):
-  """Servicer handling RPCs for service statuses."""
+    """Servicer handling RPCs for service statuses."""
 
-  def __init__(self, service_names, pool=None):
-    """Constructor.
+    def __init__(self, service_names, pool=None):
+        """Constructor.
 
     Args:
       service_names: Iterable of fully-qualified service names available.
     """
-    self._service_names = list(service_names)
-    self._pool = _POOL if pool is None else pool
-
-  def _file_by_filename(self, filename):
-    try:
-      descriptor = self._pool.FindFileByName(filename)
-    except KeyError:
-      return _not_found_error()
-    else:
-      return _file_descriptor_response(descriptor)
-
-  def _file_containing_symbol(self, fully_qualified_name):
-    try:
-      descriptor = self._pool.FindFileContainingSymbol(fully_qualified_name)
-    except KeyError:
-      return _not_found_error()
-    else:
-      return _file_descriptor_response(descriptor)
-
-  def _file_containing_extension(containing_type, extension_number):
-    # TODO(atash) Python protobuf currently doesn't support querying extensions.
-    # https://github.com/google/protobuf/issues/2248
-    return reflection_pb2.ServerReflectionResponse(
-        error_response=reflection_pb2.ErrorResponse(
-            error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
-            error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),
-        )
-    )
-
-  def _extension_numbers_of_type(fully_qualified_name):
-    # TODO(atash) We're allowed to leave this unsupported according to the
-    # protocol, but we should still eventually implement it. Hits the same issue
-    # as `_file_containing_extension`, however.
-    # https://github.com/google/protobuf/issues/2248
-    return reflection_pb2.ServerReflectionResponse(
-        error_response=reflection_pb2.ErrorResponse(
-            error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
-            error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),
-        )
-    )
+        self._service_names = list(service_names)
+        self._pool = _POOL if pool is None else pool
+
+    def _file_by_filename(self, filename):
+        try:
+            descriptor = self._pool.FindFileByName(filename)
+        except KeyError:
+            return _not_found_error()
+        else:
+            return _file_descriptor_response(descriptor)
+
+    def _file_containing_symbol(self, fully_qualified_name):
+        try:
+            descriptor = self._pool.FindFileContainingSymbol(
+                fully_qualified_name)
+        except KeyError:
+            return _not_found_error()
+        else:
+            return _file_descriptor_response(descriptor)
+
+    def _file_containing_extension(containing_type, extension_number):
+        # TODO(atash) Python protobuf currently doesn't support querying extensions.
+        # https://github.com/google/protobuf/issues/2248
+        return reflection_pb2.ServerReflectionResponse(
+            error_response=reflection_pb2.ErrorResponse(
+                error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
+                error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),))
+
+    def _extension_numbers_of_type(fully_qualified_name):
+        # TODO(atash) We're allowed to leave this unsupported according to the
+        # protocol, but we should still eventually implement it. Hits the same issue
+        # as `_file_containing_extension`, however.
+        # https://github.com/google/protobuf/issues/2248
+        return reflection_pb2.ServerReflectionResponse(
+            error_response=reflection_pb2.ErrorResponse(
+                error_code=grpc.StatusCode.UNIMPLEMENTED.value[0],
+                error_message=grpc.StatusCode.UNIMPLMENTED.value[1].encode(),))
 
-  def _list_services(self):
-    return reflection_pb2.ServerReflectionResponse(
-        list_services_response=reflection_pb2.ListServiceResponse(
-            service=[
+    def _list_services(self):
+        return reflection_pb2.ServerReflectionResponse(
+            list_services_response=reflection_pb2.ListServiceResponse(service=[
                 reflection_pb2.ServiceResponse(name=service_name)
                 for service_name in self._service_names
-            ]
-        )
-    )
-
-  def ServerReflectionInfo(self, request_iterator, context):
-    for request in request_iterator:
-      if request.HasField('file_by_filename'):
-        yield self._file_by_filename(request.file_by_filename)
-      elif request.HasField('file_containing_symbol'):
-        yield self._file_containing_symbol(request.file_containing_symbol)
-      elif request.HasField('file_containing_extension'):
-        yield self._file_containing_extension(
-            request.file_containing_extension.containing_type,
-            request.file_containing_extension.extension_number)
-      elif request.HasField('all_extension_numbers_of_type'):
-        yield _all_extension_numbers_of_type(
-            request.all_extension_numbers_of_type)
-      elif request.HasField('list_services'):
-        yield self._list_services()
-      else:
-        yield reflection_pb2.ServerReflectionResponse(
-            error_response=reflection_pb2.ErrorResponse(
-                error_code=grpc.StatusCode.INVALID_ARGUMENT.value[0],
-                error_message=grpc.StatusCode.INVALID_ARGUMENT.value[1].encode(),
-            )
-        )
-
+            ]))
+
+    def ServerReflectionInfo(self, request_iterator, context):
+        for request in request_iterator:
+            if request.HasField('file_by_filename'):
+                yield self._file_by_filename(request.file_by_filename)
+            elif request.HasField('file_containing_symbol'):
+                yield self._file_containing_symbol(
+                    request.file_containing_symbol)
+            elif request.HasField('file_containing_extension'):
+                yield self._file_containing_extension(
+                    request.file_containing_extension.containing_type,
+                    request.file_containing_extension.extension_number)
+            elif request.HasField('all_extension_numbers_of_type'):
+                yield _all_extension_numbers_of_type(
+                    request.all_extension_numbers_of_type)
+            elif request.HasField('list_services'):
+                yield self._list_services()
+            else:
+                yield reflection_pb2.ServerReflectionResponse(
+                    error_response=reflection_pb2.ErrorResponse(
+                        error_code=grpc.StatusCode.INVALID_ARGUMENT.value[0],
+                        error_message=grpc.StatusCode.INVALID_ARGUMENT.value[1]
+                        .encode(),))
diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py
index dee5491e0a..62237e0971 100644
--- a/src/python/grpcio_reflection/reflection_commands.py
+++ b/src/python/grpcio_reflection/reflection_commands.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Provides distutils command classes for the GRPC Python setup process."""
 
 import os
@@ -35,44 +34,46 @@ import shutil
 import setuptools
 
 ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
-HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto')
+HEALTH_PROTO = os.path.join(
+    ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto')
 
 
 class CopyProtoModules(setuptools.Command):
-  """Command to copy proto modules from grpc/src/proto."""
+    """Command to copy proto modules from grpc/src/proto."""
 
-  description = ''
-  user_options = []
+    description = ''
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    if os.path.isfile(HEALTH_PROTO):
-      shutil.copyfile(
-          HEALTH_PROTO,
-          os.path.join(ROOT_DIR, 'grpc_reflection/v1alpha/reflection.proto'))
+    def run(self):
+        if os.path.isfile(HEALTH_PROTO):
+            shutil.copyfile(
+                HEALTH_PROTO,
+                os.path.join(ROOT_DIR,
+                             'grpc_reflection/v1alpha/reflection.proto'))
 
 
 class BuildPackageProtos(setuptools.Command):
-  """Command to generate project *_pb2.py modules from proto files."""
+    """Command to generate project *_pb2.py modules from proto files."""
 
-  description = 'build grpc protobuf modules'
-  user_options = []
+    description = 'build grpc protobuf modules'
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    # due to limitations of the proto generator, we require that only *one*
-    # directory is provided as an 'include' directory. We assume it's the '' key
-    # to `self.distribution.package_dir` (and get a key error if it's not
-    # there).
-    from grpc_tools import command
-    command.build_package_protos(self.distribution.package_dir[''])
+    def run(self):
+        # due to limitations of the proto generator, we require that only *one*
+        # directory is provided as an 'include' directory. We assume it's the '' key
+        # to `self.distribution.package_dir` (and get a key error if it's not
+        # there).
+        from grpc_tools import command
+        command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index cfc41f4fe7..2926923029 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Setup module for the GRPC Python package's optional reflection."""
 
 import os
@@ -41,18 +40,14 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
 import reflection_commands
 import grpc_version
 
-PACKAGE_DIRECTORIES = {
-    '': '.',
-}
+PACKAGE_DIRECTORIES = {'': '.',}
 
 SETUP_REQUIRES = (
-    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
-)
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),)
 
 INSTALL_REQUIRES = (
     'protobuf>=3.0.0',
-    'grpcio>={version}'.format(version=grpc_version.VERSION),
-)
+    'grpcio>={version}'.format(version=grpc_version.VERSION),)
 
 COMMAND_CLASS = {
     # Run preprocess from the repository *before* doing any packaging!
@@ -68,5 +63,4 @@ setuptools.setup(
     packages=setuptools.find_packages('.'),
     install_requires=INSTALL_REQUIRES,
     setup_requires=SETUP_REQUIRES,
-    cmdclass=COMMAND_CLASS
-)
+    cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index e822971fe0..845b7f598c 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Provides distutils command classes for the gRPC Python setup process."""
 
 import distutils
@@ -55,163 +54,162 @@ PYTHON_PROTO_TOP_LEVEL = os.path.join(PYTHON_STEM, 'src')
 
 
 class CommandError(object):
-  pass
+    pass
 
 
 class GatherProto(setuptools.Command):
 
-  description = 'gather proto dependencies'
-  user_options = []
+    description = 'gather proto dependencies'
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    pass
+    def finalize_options(self):
+        pass
 
-  def run(self):
-    # TODO(atash) ensure that we're running from the repository directory when
-    # this command is used
-    try:
-      shutil.rmtree(PROTO_STEM)
-    except Exception as error:
-      # We don't care if this command fails
-      pass
-    shutil.copytree(GRPC_PROTO_STEM, PROTO_STEM)
-    for root, _, _ in os.walk(PYTHON_PROTO_TOP_LEVEL):
-      path = os.path.join(root, '__init__.py')
-      open(path, 'a').close()
+    def run(self):
+        # TODO(atash) ensure that we're running from the repository directory when
+        # this command is used
+        try:
+            shutil.rmtree(PROTO_STEM)
+        except Exception as error:
+            # We don't care if this command fails
+            pass
+        shutil.copytree(GRPC_PROTO_STEM, PROTO_STEM)
+        for root, _, _ in os.walk(PYTHON_PROTO_TOP_LEVEL):
+            path = os.path.join(root, '__init__.py')
+            open(path, 'a').close()
 
 
 class BuildProtoModules(setuptools.Command):
-  """Command to generate project *_pb2.py modules from proto files."""
-
-  description = 'build protobuf modules'
-  user_options = [
-    ('include=', None, 'path patterns to include in protobuf generation'),
-    ('exclude=', None, 'path patterns to exclude from protobuf generation')
-  ]
-
-  def initialize_options(self):
-    self.exclude = None
-    self.include = r'.*\.proto$'
-
-  def finalize_options(self):
-    pass
-
-  def run(self):
-    import grpc_tools.protoc as protoc
-
-    include_regex = re.compile(self.include)
-    exclude_regex = re.compile(self.exclude) if self.exclude else None
-    paths = []
-    for walk_root, directories, filenames in os.walk(PROTO_STEM):
-      for filename in filenames:
-        path = os.path.join(walk_root, filename)
-        if include_regex.match(path) and not (
-            exclude_regex and exclude_regex.match(path)):
-          paths.append(path)
-
-    # TODO(kpayson): It would be nice to do this in a batch command,
-    # but we currently have name conflicts in src/proto
-    for path in paths:
-      command = [
-          'grpc_tools.protoc',
-          '-I {}'.format(PROTO_STEM),
-          '--python_out={}'.format(PROTO_STEM),
-          '--grpc_python_out={}'.format(PROTO_STEM),
-      ] + [path]
-      if protoc.main(command) != 0:
-        sys.stderr.write(
-            'warning: Command:\n{}\nFailed'.format(
-                command))
-
-    # Generated proto directories dont include __init__.py, but
-    # these are needed for python package resolution
-    for walk_root, _, _ in os.walk(PROTO_STEM):
-      path = os.path.join(walk_root, '__init__.py')
-      open(path, 'a').close()
+    """Command to generate project *_pb2.py modules from proto files."""
+
+    description = 'build protobuf modules'
+    user_options = [
+        ('include=', None, 'path patterns to include in protobuf generation'),
+        ('exclude=', None, 'path patterns to exclude from protobuf generation')
+    ]
+
+    def initialize_options(self):
+        self.exclude = None
+        self.include = r'.*\.proto$'
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        import grpc_tools.protoc as protoc
+
+        include_regex = re.compile(self.include)
+        exclude_regex = re.compile(self.exclude) if self.exclude else None
+        paths = []
+        for walk_root, directories, filenames in os.walk(PROTO_STEM):
+            for filename in filenames:
+                path = os.path.join(walk_root, filename)
+                if include_regex.match(path) and not (
+                        exclude_regex and exclude_regex.match(path)):
+                    paths.append(path)
+
+        # TODO(kpayson): It would be nice to do this in a batch command,
+        # but we currently have name conflicts in src/proto
+        for path in paths:
+            command = [
+                'grpc_tools.protoc',
+                '-I {}'.format(PROTO_STEM),
+                '--python_out={}'.format(PROTO_STEM),
+                '--grpc_python_out={}'.format(PROTO_STEM),
+            ] + [path]
+            if protoc.main(command) != 0:
+                sys.stderr.write('warning: Command:\n{}\nFailed'.format(
+                    command))
+
+        # Generated proto directories dont include __init__.py, but
+        # these are needed for python package resolution
+        for walk_root, _, _ in os.walk(PROTO_STEM):
+            path = os.path.join(walk_root, '__init__.py')
+            open(path, 'a').close()
 
 
 class BuildPy(build_py.build_py):
-  """Custom project build command."""
+    """Custom project build command."""
 
-  def run(self):
-    try:
-      self.run_command('build_package_protos')
-    except CommandError as error:
-      sys.stderr.write('warning: %s\n' % error.message)
-    build_py.build_py.run(self)
+    def run(self):
+        try:
+            self.run_command('build_package_protos')
+        except CommandError as error:
+            sys.stderr.write('warning: %s\n' % error.message)
+        build_py.build_py.run(self)
 
 
 class TestLite(setuptools.Command):
-  """Command to run tests without fetching or building anything."""
+    """Command to run tests without fetching or building anything."""
 
-  description = 'run tests without fetching or building anything.'
-  user_options = []
+    description = 'run tests without fetching or building anything.'
+    user_options = []
 
-  def initialize_options(self):
-    pass
+    def initialize_options(self):
+        pass
 
-  def finalize_options(self):
-    # distutils requires this override.
-    pass
+    def finalize_options(self):
+        # distutils requires this override.
+        pass
 
-  def run(self):
-    self._add_eggs_to_path()
+    def run(self):
+        self._add_eggs_to_path()
 
-    import tests
-    loader = tests.Loader()
-    loader.loadTestsFromNames(['tests'])
-    runner = tests.Runner()
-    result = runner.run(loader.suite)
-    if not result.wasSuccessful():
-      sys.exit('Test failure')
+        import tests
+        loader = tests.Loader()
+        loader.loadTestsFromNames(['tests'])
+        runner = tests.Runner()
+        result = runner.run(loader.suite)
+        if not result.wasSuccessful():
+            sys.exit('Test failure')
 
-  def _add_eggs_to_path(self):
-    """Fetch install and test requirements"""
-    self.distribution.fetch_build_eggs(self.distribution.install_requires)
-    self.distribution.fetch_build_eggs(self.distribution.tests_require)
+    def _add_eggs_to_path(self):
+        """Fetch install and test requirements"""
+        self.distribution.fetch_build_eggs(self.distribution.install_requires)
+        self.distribution.fetch_build_eggs(self.distribution.tests_require)
 
 
 class RunInterop(test.test):
 
-  description = 'run interop test client/server'
-  user_options = [
-    ('args=', 'a', 'pass-thru arguments for the client/server'),
-    ('client', 'c', 'flag indicating to run the client'),
-    ('server', 's', 'flag indicating to run the server')
-  ]
-
-  def initialize_options(self):
-    self.args = ''
-    self.client = False
-    self.server = False
-
-  def finalize_options(self):
-    if self.client and self.server:
-      raise DistutilsOptionError('you may only specify one of client or server')
-
-  def run(self):
-    if self.distribution.install_requires:
-      self.distribution.fetch_build_eggs(self.distribution.install_requires)
-    if self.distribution.tests_require:
-      self.distribution.fetch_build_eggs(self.distribution.tests_require)
-    if self.client:
-      self.run_client()
-    elif self.server:
-      self.run_server()
-
-  def run_server(self):
-    # We import here to ensure that our setuptools parent has had a chance to
-    # edit the Python system path.
-    from tests.interop import server
-    sys.argv[1:] = self.args.split()
-    server.serve()
-
-  def run_client(self):
-    # We import here to ensure that our setuptools parent has had a chance to
-    # edit the Python system path.
-    from tests.interop import client
-    sys.argv[1:] = self.args.split()
-    client.test_interoperability()
+    description = 'run interop test client/server'
+    user_options = [('args=', 'a', 'pass-thru arguments for the client/server'),
+                    ('client', 'c', 'flag indicating to run the client'),
+                    ('server', 's', 'flag indicating to run the server')]
+
+    def initialize_options(self):
+        self.args = ''
+        self.client = False
+        self.server = False
+
+    def finalize_options(self):
+        if self.client and self.server:
+            raise DistutilsOptionError(
+                'you may only specify one of client or server')
+
+    def run(self):
+        if self.distribution.install_requires:
+            self.distribution.fetch_build_eggs(
+                self.distribution.install_requires)
+        if self.distribution.tests_require:
+            self.distribution.fetch_build_eggs(self.distribution.tests_require)
+        if self.client:
+            self.run_client()
+        elif self.server:
+            self.run_server()
+
+    def run_server(self):
+        # We import here to ensure that our setuptools parent has had a chance to
+        # edit the Python system path.
+        from tests.interop import server
+        sys.argv[1:] = self.args.split()
+        server.serve()
+
+    def run_client(self):
+        # We import here to ensure that our setuptools parent has had a chance to
+        # edit the Python system path.
+        from tests.interop import client
+        sys.argv[1:] = self.args.split()
+        client.test_interoperability()
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 375fbd6c77..f0407d1a55 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -26,7 +26,6 @@
 # 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.
-
 """A setup module for the gRPC Python package."""
 
 import os
@@ -48,9 +47,7 @@ import grpc_version
 
 LICENSE = '3-clause BSD'
 
-PACKAGE_DIRECTORIES = {
-    '': '.',
-}
+PACKAGE_DIRECTORIES = {'': '.',}
 
 INSTALL_REQUIRES = (
     'coverage>=4.0',
@@ -61,13 +58,11 @@ INSTALL_REQUIRES = (
     'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
     'oauth2client>=1.4.7',
     'protobuf>=3.0.0',
-    'six>=1.10',
-)
+    'six>=1.10',)
 
 COMMAND_CLASS = {
     # Run `preprocess` *before* doing any packaging!
     'preprocess': commands.GatherProto,
-
     'build_package_protos': grpc_tools.command.BuildPackageProtos,
     'build_py': commands.BuildPy,
     'run_interop': commands.RunInterop,
@@ -80,9 +75,7 @@ PACKAGE_DATA = {
         'credentials/server1.key',
         'credentials/server1.pem',
     ],
-    'tests.protoc_plugin.protos.invocation_testing': [
-        'same.proto',
-    ],
+    'tests.protoc_plugin.protos.invocation_testing': ['same.proto',],
     'tests.protoc_plugin.protos.invocation_testing.split_messages': [
         'messages.proto',
     ],
@@ -94,9 +87,7 @@ PACKAGE_DATA = {
         'credentials/server1.key',
         'credentials/server1.pem',
     ],
-    'tests': [
-        'tests.json'
-    ],
+    'tests': ['tests.json'],
 }
 
 TEST_SUITE = 'tests'
@@ -107,16 +98,15 @@ TESTS_REQUIRE = INSTALL_REQUIRES
 PACKAGES = setuptools.find_packages('.')
 
 setuptools.setup(
-  name='grpcio-tests',
-  version=grpc_version.VERSION,
-  license=LICENSE,
-  packages=list(PACKAGES),
-  package_dir=PACKAGE_DIRECTORIES,
-  package_data=PACKAGE_DATA,
-  install_requires=INSTALL_REQUIRES,
-  cmdclass=COMMAND_CLASS,
-  tests_require=TESTS_REQUIRE,
-  test_suite=TEST_SUITE,
-  test_loader=TEST_LOADER,
-  test_runner=TEST_RUNNER,
-)
+    name='grpcio-tests',
+    version=grpc_version.VERSION,
+    license=LICENSE,
+    packages=list(PACKAGES),
+    package_dir=PACKAGE_DIRECTORIES,
+    package_data=PACKAGE_DATA,
+    install_requires=INSTALL_REQUIRES,
+    cmdclass=COMMAND_CLASS,
+    tests_require=TESTS_REQUIRE,
+    test_suite=TEST_SUITE,
+    test_loader=TEST_LOADER,
+    test_runner=TEST_RUNNER,)
diff --git a/src/python/grpcio_tests/tests/_loader.py b/src/python/grpcio_tests/tests/_loader.py
index 621bedc7bb..42cf9ab4ca 100644
--- a/src/python/grpcio_tests/tests/_loader.py
+++ b/src/python/grpcio_tests/tests/_loader.py
@@ -40,7 +40,7 @@ TEST_MODULE_REGEX = r'^.*_test$'
 
 
 class Loader(object):
-  """Test loader for setuptools test suite support.
+    """Test loader for setuptools test suite support.
 
   Attributes:
     suite (unittest.TestSuite): All tests collected by the loader.
@@ -51,57 +51,57 @@ class Loader(object):
       contributes to the test suite.
   """
 
-  def __init__(self):
-    self.suite = unittest.TestSuite()
-    self.loader = unittest.TestLoader()
-    self.module_matcher = re.compile(TEST_MODULE_REGEX)
+    def __init__(self):
+        self.suite = unittest.TestSuite()
+        self.loader = unittest.TestLoader()
+        self.module_matcher = re.compile(TEST_MODULE_REGEX)
 
-  def loadTestsFromNames(self, names, module=None):
-    """Function mirroring TestLoader::loadTestsFromNames, as expected by
+    def loadTestsFromNames(self, names, module=None):
+        """Function mirroring TestLoader::loadTestsFromNames, as expected by
     setuptools.setup argument `test_loader`."""
-    # ensure that we capture decorators and definitions (else our coverage
-    # measure unnecessarily suffers)
-    coverage_context = coverage.Coverage(data_suffix=True)
-    coverage_context.start()
-    modules = [importlib.import_module(name) for name in names]
-    for module in modules:
-      self.visit_module(module)
-    for module in modules:
-      try:
-        package_paths = module.__path__
-      except:
-        continue
-      self.walk_packages(package_paths)
-    coverage_context.stop()
-    coverage_context.save()
-    return self.suite
-
-  def walk_packages(self, package_paths):
-    """Walks over the packages, dispatching `visit_module` calls.
+        # ensure that we capture decorators and definitions (else our coverage
+        # measure unnecessarily suffers)
+        coverage_context = coverage.Coverage(data_suffix=True)
+        coverage_context.start()
+        modules = [importlib.import_module(name) for name in names]
+        for module in modules:
+            self.visit_module(module)
+        for module in modules:
+            try:
+                package_paths = module.__path__
+            except:
+                continue
+            self.walk_packages(package_paths)
+        coverage_context.stop()
+        coverage_context.save()
+        return self.suite
+
+    def walk_packages(self, package_paths):
+        """Walks over the packages, dispatching `visit_module` calls.
 
     Args:
       package_paths (list): A list of paths over which to walk through modules
         along.
     """
-    for importer, module_name, is_package in (
-        pkgutil.walk_packages(package_paths)):
-      module = importer.find_module(module_name).load_module(module_name)
-      self.visit_module(module)
+        for importer, module_name, is_package in (
+                pkgutil.walk_packages(package_paths)):
+            module = importer.find_module(module_name).load_module(module_name)
+            self.visit_module(module)
 
-  def visit_module(self, module):
-    """Visits the module, adding discovered tests to the test suite.
+    def visit_module(self, module):
+        """Visits the module, adding discovered tests to the test suite.
 
     Args:
       module (module): Module to match against self.module_matcher; if matched
         it has its tests loaded via self.loader into self.suite.
     """
-    if self.module_matcher.match(module.__name__):
-      module_suite = self.loader.loadTestsFromModule(module)
-      self.suite.addTest(module_suite)
+        if self.module_matcher.match(module.__name__):
+            module_suite = self.loader.loadTestsFromModule(module)
+            self.suite.addTest(module_suite)
 
 
 def iterate_suite_cases(suite):
-  """Generator over all unittest.TestCases in a unittest.TestSuite.
+    """Generator over all unittest.TestCases in a unittest.TestSuite.
 
   Args:
     suite (unittest.TestSuite): Suite to iterate over in the generator.
@@ -109,11 +109,12 @@ def iterate_suite_cases(suite):
   Returns:
     generator: A generator over all unittest.TestCases in `suite`.
   """
-  for item in suite:
-    if isinstance(item, unittest.TestSuite):
-      for child_item in iterate_suite_cases(item):
-        yield child_item
-    elif isinstance(item, unittest.TestCase):
-      yield item
-    else:
-      raise ValueError('unexpected suite item of type {}'.format(type(item)))
+    for item in suite:
+        if isinstance(item, unittest.TestSuite):
+            for child_item in iterate_suite_cases(item):
+                yield child_item
+        elif isinstance(item, unittest.TestCase):
+            yield item
+        else:
+            raise ValueError('unexpected suite item of type {}'.format(
+                type(item)))
diff --git a/src/python/grpcio_tests/tests/_result.py b/src/python/grpcio_tests/tests/_result.py
index 1acec6a9b5..794b7540f1 100644
--- a/src/python/grpcio_tests/tests/_result.py
+++ b/src/python/grpcio_tests/tests/_result.py
@@ -41,9 +41,11 @@ from six import moves
 from tests import _loader
 
 
-class CaseResult(collections.namedtuple('CaseResult', [
-    'id', 'name', 'kind', 'stdout', 'stderr', 'skip_reason', 'traceback'])):
-  """A serializable result of a single test case.
+class CaseResult(
+        collections.namedtuple('CaseResult', [
+            'id', 'name', 'kind', 'stdout', 'stderr', 'skip_reason', 'traceback'
+        ])):
+    """A serializable result of a single test case.
 
   Attributes:
     id (object): Any serializable object used to denote the identity of this
@@ -59,62 +61,78 @@ class CaseResult(collections.namedtuple('CaseResult', [
       None.
   """
 
-  class Kind:
-    UNTESTED = 'untested'
-    RUNNING = 'running'
-    ERROR = 'error'
-    FAILURE = 'failure'
-    SUCCESS = 'success'
-    SKIP = 'skip'
-    EXPECTED_FAILURE = 'expected failure'
-    UNEXPECTED_SUCCESS = 'unexpected success'
-
-  def __new__(cls, id=None, name=None, kind=None, stdout=None, stderr=None,
-              skip_reason=None, traceback=None):
-    """Helper keyword constructor for the namedtuple.
+    class Kind:
+        UNTESTED = 'untested'
+        RUNNING = 'running'
+        ERROR = 'error'
+        FAILURE = 'failure'
+        SUCCESS = 'success'
+        SKIP = 'skip'
+        EXPECTED_FAILURE = 'expected failure'
+        UNEXPECTED_SUCCESS = 'unexpected success'
+
+    def __new__(cls,
+                id=None,
+                name=None,
+                kind=None,
+                stdout=None,
+                stderr=None,
+                skip_reason=None,
+                traceback=None):
+        """Helper keyword constructor for the namedtuple.
 
     See this class' attributes for information on the arguments."""
-    assert id is not None
-    assert name is None or isinstance(name, str)
-    if kind is CaseResult.Kind.UNTESTED:
-      pass
-    elif kind is CaseResult.Kind.RUNNING:
-      pass
-    elif kind is CaseResult.Kind.ERROR:
-      assert traceback is not None
-    elif kind is CaseResult.Kind.FAILURE:
-      assert traceback is not None
-    elif kind is CaseResult.Kind.SUCCESS:
-      pass
-    elif kind is CaseResult.Kind.SKIP:
-      assert skip_reason is not None
-    elif kind is CaseResult.Kind.EXPECTED_FAILURE:
-      assert traceback is not None
-    elif kind is CaseResult.Kind.UNEXPECTED_SUCCESS:
-      pass
-    else:
-      assert False
-    return super(cls, CaseResult).__new__(
-        cls, id, name, kind, stdout, stderr, skip_reason, traceback)
-
-  def updated(self, name=None, kind=None, stdout=None, stderr=None,
-              skip_reason=None, traceback=None):
-    """Get a new validated CaseResult with the fields updated.
+        assert id is not None
+        assert name is None or isinstance(name, str)
+        if kind is CaseResult.Kind.UNTESTED:
+            pass
+        elif kind is CaseResult.Kind.RUNNING:
+            pass
+        elif kind is CaseResult.Kind.ERROR:
+            assert traceback is not None
+        elif kind is CaseResult.Kind.FAILURE:
+            assert traceback is not None
+        elif kind is CaseResult.Kind.SUCCESS:
+            pass
+        elif kind is CaseResult.Kind.SKIP:
+            assert skip_reason is not None
+        elif kind is CaseResult.Kind.EXPECTED_FAILURE:
+            assert traceback is not None
+        elif kind is CaseResult.Kind.UNEXPECTED_SUCCESS:
+            pass
+        else:
+            assert False
+        return super(cls, CaseResult).__new__(cls, id, name, kind, stdout,
+                                              stderr, skip_reason, traceback)
+
+    def updated(self,
+                name=None,
+                kind=None,
+                stdout=None,
+                stderr=None,
+                skip_reason=None,
+                traceback=None):
+        """Get a new validated CaseResult with the fields updated.
 
     See this class' attributes for information on the arguments."""
-    name = self.name if name is None else name
-    kind = self.kind if kind is None else kind
-    stdout = self.stdout if stdout is None else stdout
-    stderr = self.stderr if stderr is None else stderr
-    skip_reason = self.skip_reason if skip_reason is None else skip_reason
-    traceback = self.traceback if traceback is None else traceback
-    return CaseResult(id=self.id, name=name, kind=kind, stdout=stdout,
-                      stderr=stderr, skip_reason=skip_reason,
-                      traceback=traceback)
+        name = self.name if name is None else name
+        kind = self.kind if kind is None else kind
+        stdout = self.stdout if stdout is None else stdout
+        stderr = self.stderr if stderr is None else stderr
+        skip_reason = self.skip_reason if skip_reason is None else skip_reason
+        traceback = self.traceback if traceback is None else traceback
+        return CaseResult(
+            id=self.id,
+            name=name,
+            kind=kind,
+            stdout=stdout,
+            stderr=stderr,
+            skip_reason=skip_reason,
+            traceback=traceback)
 
 
 class AugmentedResult(unittest.TestResult):
-  """unittest.Result that keeps track of additional information.
+    """unittest.Result that keeps track of additional information.
 
   Uses CaseResult objects to store test-case results, providing additional
   information beyond that of the standard Python unittest library, such as
@@ -127,228 +145,215 @@ class AugmentedResult(unittest.TestResult):
       to CaseResult objects corresponding to those IDs.
   """
 
-  def __init__(self, id_map):
-    """Initialize the object with an identifier mapping.
+    def __init__(self, id_map):
+        """Initialize the object with an identifier mapping.
 
     Arguments:
       id_map (callable): Corresponds to the attribute `id_map`."""
-    super(AugmentedResult, self).__init__()
-    self.id_map = id_map
-    self.cases = None
-
-  def startTestRun(self):
-    """See unittest.TestResult.startTestRun."""
-    super(AugmentedResult, self).startTestRun()
-    self.cases = dict()
-
-  def stopTestRun(self):
-    """See unittest.TestResult.stopTestRun."""
-    super(AugmentedResult, self).stopTestRun()
-
-  def startTest(self, test):
-    """See unittest.TestResult.startTest."""
-    super(AugmentedResult, self).startTest(test)
-    case_id = self.id_map(test)
-    self.cases[case_id] = CaseResult(
-        id=case_id, name=test.id(), kind=CaseResult.Kind.RUNNING)
-
-  def addError(self, test, error):
-    """See unittest.TestResult.addError."""
-    super(AugmentedResult, self).addError(test, error)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.ERROR, traceback=error)
-
-  def addFailure(self, test, error):
-    """See unittest.TestResult.addFailure."""
-    super(AugmentedResult, self).addFailure(test, error)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.FAILURE, traceback=error)
-
-  def addSuccess(self, test):
-    """See unittest.TestResult.addSuccess."""
-    super(AugmentedResult, self).addSuccess(test)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.SUCCESS)
-
-  def addSkip(self, test, reason):
-    """See unittest.TestResult.addSkip."""
-    super(AugmentedResult, self).addSkip(test, reason)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.SKIP, skip_reason=reason)
-
-  def addExpectedFailure(self, test, error):
-    """See unittest.TestResult.addExpectedFailure."""
-    super(AugmentedResult, self).addExpectedFailure(test, error)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.EXPECTED_FAILURE, traceback=error)
-
-  def addUnexpectedSuccess(self, test):
-    """See unittest.TestResult.addUnexpectedSuccess."""
-    super(AugmentedResult, self).addUnexpectedSuccess(test)
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        kind=CaseResult.Kind.UNEXPECTED_SUCCESS)
-
-  def set_output(self, test, stdout, stderr):
-    """Set the output attributes for the CaseResult corresponding to a test.
+        super(AugmentedResult, self).__init__()
+        self.id_map = id_map
+        self.cases = None
+
+    def startTestRun(self):
+        """See unittest.TestResult.startTestRun."""
+        super(AugmentedResult, self).startTestRun()
+        self.cases = dict()
+
+    def stopTestRun(self):
+        """See unittest.TestResult.stopTestRun."""
+        super(AugmentedResult, self).stopTestRun()
+
+    def startTest(self, test):
+        """See unittest.TestResult.startTest."""
+        super(AugmentedResult, self).startTest(test)
+        case_id = self.id_map(test)
+        self.cases[case_id] = CaseResult(
+            id=case_id, name=test.id(), kind=CaseResult.Kind.RUNNING)
+
+    def addError(self, test, error):
+        """See unittest.TestResult.addError."""
+        super(AugmentedResult, self).addError(test, error)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.ERROR, traceback=error)
+
+    def addFailure(self, test, error):
+        """See unittest.TestResult.addFailure."""
+        super(AugmentedResult, self).addFailure(test, error)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.FAILURE, traceback=error)
+
+    def addSuccess(self, test):
+        """See unittest.TestResult.addSuccess."""
+        super(AugmentedResult, self).addSuccess(test)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.SUCCESS)
+
+    def addSkip(self, test, reason):
+        """See unittest.TestResult.addSkip."""
+        super(AugmentedResult, self).addSkip(test, reason)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.SKIP, skip_reason=reason)
+
+    def addExpectedFailure(self, test, error):
+        """See unittest.TestResult.addExpectedFailure."""
+        super(AugmentedResult, self).addExpectedFailure(test, error)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.EXPECTED_FAILURE, traceback=error)
+
+    def addUnexpectedSuccess(self, test):
+        """See unittest.TestResult.addUnexpectedSuccess."""
+        super(AugmentedResult, self).addUnexpectedSuccess(test)
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            kind=CaseResult.Kind.UNEXPECTED_SUCCESS)
+
+    def set_output(self, test, stdout, stderr):
+        """Set the output attributes for the CaseResult corresponding to a test.
 
     Args:
       test (unittest.TestCase): The TestCase to set the outputs of.
       stdout (str): Output from stdout to assign to self.id_map(test).
       stderr (str): Output from stderr to assign to self.id_map(test).
     """
-    case_id = self.id_map(test)
-    self.cases[case_id] = self.cases[case_id].updated(
-        stdout=stdout.decode(), stderr=stderr.decode())
+        case_id = self.id_map(test)
+        self.cases[case_id] = self.cases[case_id].updated(
+            stdout=stdout.decode(), stderr=stderr.decode())
 
-  def augmented_results(self, filter):
-    """Convenience method to retrieve filtered case results.
+    def augmented_results(self, filter):
+        """Convenience method to retrieve filtered case results.
 
     Args:
       filter (callable): A unary predicate to filter over CaseResult objects.
     """
-    return (self.cases[case_id] for case_id in self.cases
-            if filter(self.cases[case_id]))
+        return (self.cases[case_id] for case_id in self.cases
+                if filter(self.cases[case_id]))
 
 
 class CoverageResult(AugmentedResult):
-  """Extension to AugmentedResult adding coverage.py support per test.\
+    """Extension to AugmentedResult adding coverage.py support per test.\
 
   Attributes:
     coverage_context (coverage.Coverage): coverage.py management object.
   """
 
-  def __init__(self, id_map):
-    """See AugmentedResult.__init__."""
-    super(CoverageResult, self).__init__(id_map=id_map)
-    self.coverage_context = None
+    def __init__(self, id_map):
+        """See AugmentedResult.__init__."""
+        super(CoverageResult, self).__init__(id_map=id_map)
+        self.coverage_context = None
 
-  def startTest(self, test):
-    """See unittest.TestResult.startTest.
+    def startTest(self, test):
+        """See unittest.TestResult.startTest.
 
     Additionally initializes and begins code coverage tracking."""
-    super(CoverageResult, self).startTest(test)
-    self.coverage_context = coverage.Coverage(data_suffix=True)
-    self.coverage_context.start()
+        super(CoverageResult, self).startTest(test)
+        self.coverage_context = coverage.Coverage(data_suffix=True)
+        self.coverage_context.start()
 
-  def stopTest(self, test):
-    """See unittest.TestResult.stopTest.
+    def stopTest(self, test):
+        """See unittest.TestResult.stopTest.
 
     Additionally stops and deinitializes code coverage tracking."""
-    super(CoverageResult, self).stopTest(test)
-    self.coverage_context.stop()
-    self.coverage_context.save()
-    self.coverage_context = None
+        super(CoverageResult, self).stopTest(test)
+        self.coverage_context.stop()
+        self.coverage_context.save()
+        self.coverage_context = None
 
-  def stopTestRun(self):
-    """See unittest.TestResult.stopTestRun."""
-    super(CoverageResult, self).stopTestRun()
-    # TODO(atash): Dig deeper into why the following line fails to properly
-    # combine coverage data from the Cython plugin.
-    #coverage.Coverage().combine()
+    def stopTestRun(self):
+        """See unittest.TestResult.stopTestRun."""
+        super(CoverageResult, self).stopTestRun()
+        # TODO(atash): Dig deeper into why the following line fails to properly
+        # combine coverage data from the Cython plugin.
+        #coverage.Coverage().combine()
 
 
 class _Colors:
-  """Namespaced constants for terminal color magic numbers."""
-  HEADER = '\033[95m'
-  INFO = '\033[94m'
-  OK = '\033[92m'
-  WARN = '\033[93m'
-  FAIL = '\033[91m'
-  BOLD = '\033[1m'
-  UNDERLINE = '\033[4m'
-  END = '\033[0m'
+    """Namespaced constants for terminal color magic numbers."""
+    HEADER = '\033[95m'
+    INFO = '\033[94m'
+    OK = '\033[92m'
+    WARN = '\033[93m'
+    FAIL = '\033[91m'
+    BOLD = '\033[1m'
+    UNDERLINE = '\033[4m'
+    END = '\033[0m'
 
 
 class TerminalResult(CoverageResult):
-  """Extension to CoverageResult adding basic terminal reporting."""
+    """Extension to CoverageResult adding basic terminal reporting."""
 
-  def __init__(self, out, id_map):
-    """Initialize the result object.
+    def __init__(self, out, id_map):
+        """Initialize the result object.
 
     Args:
       out (file-like): Output file to which terminal-colored live results will
         be written.
       id_map (callable): See AugmentedResult.__init__.
     """
-    super(TerminalResult, self).__init__(id_map=id_map)
-    self.out = out
-
-  def startTestRun(self):
-    """See unittest.TestResult.startTestRun."""
-    super(TerminalResult, self).startTestRun()
-    self.out.write(
-        _Colors.HEADER +
-        'Testing gRPC Python...\n' +
-        _Colors.END)
-
-  def stopTestRun(self):
-    """See unittest.TestResult.stopTestRun."""
-    super(TerminalResult, self).stopTestRun()
-    self.out.write(summary(self))
-    self.out.flush()
-
-  def addError(self, test, error):
-    """See unittest.TestResult.addError."""
-    super(TerminalResult, self).addError(test, error)
-    self.out.write(
-        _Colors.FAIL +
-        'ERROR         {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
-
-  def addFailure(self, test, error):
-    """See unittest.TestResult.addFailure."""
-    super(TerminalResult, self).addFailure(test, error)
-    self.out.write(
-        _Colors.FAIL +
-        'FAILURE       {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
-
-  def addSuccess(self, test):
-    """See unittest.TestResult.addSuccess."""
-    super(TerminalResult, self).addSuccess(test)
-    self.out.write(
-        _Colors.OK +
-        'SUCCESS       {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
-
-  def addSkip(self, test, reason):
-    """See unittest.TestResult.addSkip."""
-    super(TerminalResult, self).addSkip(test, reason)
-    self.out.write(
-        _Colors.INFO +
-        'SKIP          {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
-
-  def addExpectedFailure(self, test, error):
-    """See unittest.TestResult.addExpectedFailure."""
-    super(TerminalResult, self).addExpectedFailure(test, error)
-    self.out.write(
-        _Colors.INFO +
-        'FAILURE_OK    {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
-
-  def addUnexpectedSuccess(self, test):
-    """See unittest.TestResult.addUnexpectedSuccess."""
-    super(TerminalResult, self).addUnexpectedSuccess(test)
-    self.out.write(
-        _Colors.INFO +
-        'UNEXPECTED_OK {}\n'.format(test.id()) +
-        _Colors.END)
-    self.out.flush()
+        super(TerminalResult, self).__init__(id_map=id_map)
+        self.out = out
+
+    def startTestRun(self):
+        """See unittest.TestResult.startTestRun."""
+        super(TerminalResult, self).startTestRun()
+        self.out.write(_Colors.HEADER + 'Testing gRPC Python...\n' +
+                       _Colors.END)
+
+    def stopTestRun(self):
+        """See unittest.TestResult.stopTestRun."""
+        super(TerminalResult, self).stopTestRun()
+        self.out.write(summary(self))
+        self.out.flush()
+
+    def addError(self, test, error):
+        """See unittest.TestResult.addError."""
+        super(TerminalResult, self).addError(test, error)
+        self.out.write(_Colors.FAIL + 'ERROR         {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
+    def addFailure(self, test, error):
+        """See unittest.TestResult.addFailure."""
+        super(TerminalResult, self).addFailure(test, error)
+        self.out.write(_Colors.FAIL + 'FAILURE       {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
+    def addSuccess(self, test):
+        """See unittest.TestResult.addSuccess."""
+        super(TerminalResult, self).addSuccess(test)
+        self.out.write(_Colors.OK + 'SUCCESS       {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
+    def addSkip(self, test, reason):
+        """See unittest.TestResult.addSkip."""
+        super(TerminalResult, self).addSkip(test, reason)
+        self.out.write(_Colors.INFO + 'SKIP          {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
+    def addExpectedFailure(self, test, error):
+        """See unittest.TestResult.addExpectedFailure."""
+        super(TerminalResult, self).addExpectedFailure(test, error)
+        self.out.write(_Colors.INFO + 'FAILURE_OK    {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
+    def addUnexpectedSuccess(self, test):
+        """See unittest.TestResult.addUnexpectedSuccess."""
+        super(TerminalResult, self).addUnexpectedSuccess(test)
+        self.out.write(_Colors.INFO + 'UNEXPECTED_OK {}\n'.format(test.id()) +
+                       _Colors.END)
+        self.out.flush()
+
 
 def _traceback_string(type, value, trace):
-  """Generate a descriptive string of a Python exception traceback.
+    """Generate a descriptive string of a Python exception traceback.
 
   Args:
     type (class): The type of the exception.
@@ -358,12 +363,13 @@ def _traceback_string(type, value, trace):
   Returns:
     str: Formatted exception descriptive string.
   """
-  buffer = moves.cStringIO()
-  traceback.print_exception(type, value, trace, file=buffer)
-  return buffer.getvalue()
+    buffer = moves.cStringIO()
+    traceback.print_exception(type, value, trace, file=buffer)
+    return buffer.getvalue()
+
 
 def summary(result):
-  """A summary string of a result object.
+    """A summary string of a result object.
 
   Args:
     result (AugmentedResult): The result object to get the summary of.
@@ -371,62 +377,68 @@ def summary(result):
   Returns:
     str: The summary string.
   """
-  assert isinstance(result, AugmentedResult)
-  untested = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.UNTESTED))
-  running = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.RUNNING))
-  failures = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.FAILURE))
-  errors = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.ERROR))
-  successes = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.SUCCESS))
-  skips = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.SKIP))
-  expected_failures = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.EXPECTED_FAILURE))
-  unexpected_successes = list(result.augmented_results(
-      lambda case_result: case_result.kind is CaseResult.Kind.UNEXPECTED_SUCCESS))
-  running_names = [case.name for case in running]
-  finished_count = (len(failures) + len(errors) + len(successes) +
-                    len(expected_failures) + len(unexpected_successes))
-  statistics = (
-      '{finished} tests finished:\n'
-      '\t{successful} successful\n'
-      '\t{unsuccessful} unsuccessful\n'
-      '\t{skipped} skipped\n'
-      '\t{expected_fail} expected failures\n'
-      '\t{unexpected_successful} unexpected successes\n'
-      'Interrupted Tests:\n'
-      '\t{interrupted}\n'
-      .format(finished=finished_count,
-              successful=len(successes),
-              unsuccessful=(len(failures)+len(errors)),
-              skipped=len(skips),
-              expected_fail=len(expected_failures),
-              unexpected_successful=len(unexpected_successes),
-              interrupted=str(running_names)))
-  tracebacks = '\n\n'.join([
-      (_Colors.FAIL + '{test_name}' + _Colors.END + '\n' +
-       _Colors.BOLD + 'traceback:' + _Colors.END + '\n' +
-       '{traceback}\n' +
-       _Colors.BOLD + 'stdout:' + _Colors.END + '\n' +
-       '{stdout}\n' +
-       _Colors.BOLD + 'stderr:' + _Colors.END + '\n' +
-       '{stderr}\n').format(
-           test_name=result.name,
-           traceback=_traceback_string(*result.traceback),
-           stdout=result.stdout, stderr=result.stderr)
-      for result in itertools.chain(failures, errors)
-  ])
-  notes = 'Unexpected successes: {}\n'.format([
-      result.name for result in unexpected_successes])
-  return statistics + '\nErrors/Failures: \n' + tracebacks + '\n' + notes
+    assert isinstance(result, AugmentedResult)
+    untested = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.UNTESTED))
+    running = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.RUNNING))
+    failures = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.FAILURE))
+    errors = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.ERROR))
+    successes = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.SUCCESS))
+    skips = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.SKIP))
+    expected_failures = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.EXPECTED_FAILURE
+        ))
+    unexpected_successes = list(
+        result.augmented_results(
+            lambda case_result: case_result.kind is CaseResult.Kind.UNEXPECTED_SUCCESS
+        ))
+    running_names = [case.name for case in running]
+    finished_count = (len(failures) + len(errors) + len(successes) +
+                      len(expected_failures) + len(unexpected_successes))
+    statistics = ('{finished} tests finished:\n'
+                  '\t{successful} successful\n'
+                  '\t{unsuccessful} unsuccessful\n'
+                  '\t{skipped} skipped\n'
+                  '\t{expected_fail} expected failures\n'
+                  '\t{unexpected_successful} unexpected successes\n'
+                  'Interrupted Tests:\n'
+                  '\t{interrupted}\n'.format(
+                      finished=finished_count,
+                      successful=len(successes),
+                      unsuccessful=(len(failures) + len(errors)),
+                      skipped=len(skips),
+                      expected_fail=len(expected_failures),
+                      unexpected_successful=len(unexpected_successes),
+                      interrupted=str(running_names)))
+    tracebacks = '\n\n'.join(
+        [(_Colors.FAIL + '{test_name}' + _Colors.END + '\n' + _Colors.BOLD +
+          'traceback:' + _Colors.END + '\n' + '{traceback}\n' + _Colors.BOLD +
+          'stdout:' + _Colors.END + '\n' + '{stdout}\n' + _Colors.BOLD +
+          'stderr:' + _Colors.END + '\n' + '{stderr}\n').format(
+              test_name=result.name,
+              traceback=_traceback_string(*result.traceback),
+              stdout=result.stdout,
+              stderr=result.stderr)
+         for result in itertools.chain(failures, errors)])
+    notes = 'Unexpected successes: {}\n'.format(
+        [result.name for result in unexpected_successes])
+    return statistics + '\nErrors/Failures: \n' + tracebacks + '\n' + notes
 
 
 def jenkins_junit_xml(result):
-  """An XML tree object that when written is recognizable by Jenkins.
+    """An XML tree object that when written is recognizable by Jenkins.
 
   Args:
     result (AugmentedResult): The result object to get the junit xml output of.
@@ -434,20 +446,18 @@ def jenkins_junit_xml(result):
   Returns:
     ElementTree.ElementTree: The XML tree.
   """
-  assert isinstance(result, AugmentedResult)
-  root = ElementTree.Element('testsuites')
-  suite = ElementTree.SubElement(root, 'testsuite', {
-      'name': 'Python gRPC tests',
-  })
-  for case in result.cases.values():
-    if case.kind is CaseResult.Kind.SUCCESS:
-      ElementTree.SubElement(suite, 'testcase', {
-          'name': case.name,
-      })
-    elif case.kind in (CaseResult.Kind.ERROR, CaseResult.Kind.FAILURE):
-      case_xml = ElementTree.SubElement(suite, 'testcase', {
-          'name': case.name,
-      })
-      error_xml = ElementTree.SubElement(case_xml, 'error', {})
-      error_xml.text = ''.format(case.stderr, case.traceback)
-  return ElementTree.ElementTree(element=root)
+    assert isinstance(result, AugmentedResult)
+    root = ElementTree.Element('testsuites')
+    suite = ElementTree.SubElement(root, 'testsuite', {
+        'name': 'Python gRPC tests',
+    })
+    for case in result.cases.values():
+        if case.kind is CaseResult.Kind.SUCCESS:
+            ElementTree.SubElement(suite, 'testcase', {'name': case.name,})
+        elif case.kind in (CaseResult.Kind.ERROR, CaseResult.Kind.FAILURE):
+            case_xml = ElementTree.SubElement(suite, 'testcase', {
+                'name': case.name,
+            })
+            error_xml = ElementTree.SubElement(case_xml, 'error', {})
+            error_xml.text = ''.format(case.stderr, case.traceback)
+    return ElementTree.ElementTree(element=root)
diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py
index 926dcbe23a..59964b271c 100644
--- a/src/python/grpcio_tests/tests/_runner.py
+++ b/src/python/grpcio_tests/tests/_runner.py
@@ -49,7 +49,7 @@ from tests import _result
 
 
 class CaptureFile(object):
-  """A context-managed file to redirect output to a byte array.
+    """A context-managed file to redirect output to a byte array.
 
   Use by invoking `start` (`__enter__`) and at some point invoking `stop`
   (`__exit__`). At any point after the initial call to `start` call `output` to
@@ -66,57 +66,56 @@ class CaptureFile(object):
       Only non-None when self is started.
   """
 
-  def __init__(self, fd):
-    self._redirected_fd = fd
-    self._saved_fd = os.dup(self._redirected_fd)
-    self._into_file = None
+    def __init__(self, fd):
+        self._redirected_fd = fd
+        self._saved_fd = os.dup(self._redirected_fd)
+        self._into_file = None
 
-  def output(self):
-    """Get all output from the redirected-to file if it exists."""
-    if self._into_file:
-      self._into_file.seek(0)
-      return bytes(self._into_file.read())
-    else:
-      return bytes()
+    def output(self):
+        """Get all output from the redirected-to file if it exists."""
+        if self._into_file:
+            self._into_file.seek(0)
+            return bytes(self._into_file.read())
+        else:
+            return bytes()
 
-  def start(self):
-    """Start redirection of writes to the file descriptor."""
-    self._into_file = tempfile.TemporaryFile()
-    os.dup2(self._into_file.fileno(), self._redirected_fd)
+    def start(self):
+        """Start redirection of writes to the file descriptor."""
+        self._into_file = tempfile.TemporaryFile()
+        os.dup2(self._into_file.fileno(), self._redirected_fd)
 
-  def stop(self):
-    """Stop redirection of writes to the file descriptor."""
-    # n.b. this dup2 call auto-closes self._redirected_fd
-    os.dup2(self._saved_fd, self._redirected_fd)
+    def stop(self):
+        """Stop redirection of writes to the file descriptor."""
+        # n.b. this dup2 call auto-closes self._redirected_fd
+        os.dup2(self._saved_fd, self._redirected_fd)
 
-  def write_bypass(self, value):
-    """Bypass the redirection and write directly to the original file.
+    def write_bypass(self, value):
+        """Bypass the redirection and write directly to the original file.
 
     Arguments:
       value (str): What to write to the original file.
     """
-    if six.PY3 and not isinstance(value, six.binary_type):
-      value = bytes(value, 'ascii')
-    if self._saved_fd is None:
-      os.write(self._redirect_fd, value)
-    else:
-      os.write(self._saved_fd, value)
+        if six.PY3 and not isinstance(value, six.binary_type):
+            value = bytes(value, 'ascii')
+        if self._saved_fd is None:
+            os.write(self._redirect_fd, value)
+        else:
+            os.write(self._saved_fd, value)
 
-  def __enter__(self):
-    self.start()
-    return self
+    def __enter__(self):
+        self.start()
+        return self
 
-  def __exit__(self, type, value, traceback):
-    self.stop()
+    def __exit__(self, type, value, traceback):
+        self.stop()
 
-  def close(self):
-    """Close any resources used by self not closed by stop()."""
-    os.close(self._saved_fd)
+    def close(self):
+        """Close any resources used by self not closed by stop()."""
+        os.close(self._saved_fd)
 
 
-class AugmentedCase(collections.namedtuple('AugmentedCase', [
-    'case', 'id'])):
-  """A test case with a guaranteed unique externally specified identifier.
+class AugmentedCase(collections.namedtuple('AugmentedCase', ['case', 'id'])):
+    """A test case with a guaranteed unique externally specified identifier.
 
   Attributes:
     case (unittest.TestCase): TestCase we're decorating with an additional
@@ -125,105 +124,107 @@ class AugmentedCase(collections.namedtuple('AugmentedCase', [
       purposes.
   """
 
-  def __new__(cls, case, id=None):
-    if id is None:
-      id = uuid.uuid4()
-    return super(cls, AugmentedCase).__new__(cls, case, id)
+    def __new__(cls, case, id=None):
+        if id is None:
+            id = uuid.uuid4()
+        return super(cls, AugmentedCase).__new__(cls, case, id)
 
 
 class Runner(object):
 
-  def run(self, suite):
-    """See setuptools' test_runner setup argument for information."""
-    # only run test cases with id starting with given prefix
-    testcase_filter = os.getenv('GRPC_PYTHON_TESTRUNNER_FILTER')
-    filtered_cases = []
-    for case in _loader.iterate_suite_cases(suite):
-      if not testcase_filter or case.id().startswith(testcase_filter):
-        filtered_cases.append(case)
-
-    # Ensure that every test case has no collision with any other test case in
-    # the augmented results.
-    augmented_cases = [AugmentedCase(case, uuid.uuid4())
-                       for case in filtered_cases]
-    case_id_by_case = dict((augmented_case.case, augmented_case.id)
-                           for augmented_case in augmented_cases)
-    result_out = moves.cStringIO()
-    result = _result.TerminalResult(
-        result_out, id_map=lambda case: case_id_by_case[case])
-    stdout_pipe = CaptureFile(sys.stdout.fileno())
-    stderr_pipe = CaptureFile(sys.stderr.fileno())
-    kill_flag = [False]
-
-    def sigint_handler(signal_number, frame):
-      if signal_number == signal.SIGINT:
-        kill_flag[0] = True  # Python 2.7 not having 'local'... :-(
-      signal.signal(signal_number, signal.SIG_DFL)
-
-    def fault_handler(signal_number, frame):
-      stdout_pipe.write_bypass(
-          'Received fault signal {}\nstdout:\n{}\n\nstderr:{}\n'
-          .format(signal_number, stdout_pipe.output(),
-                  stderr_pipe.output()))
-      os._exit(1)
-
-    def check_kill_self():
-      if kill_flag[0]:
-        stdout_pipe.write_bypass('Stopping tests short...')
-        result.stopTestRun()
-        stdout_pipe.write_bypass(result_out.getvalue())
-        stdout_pipe.write_bypass(
-            '\ninterrupted stdout:\n{}\n'.format(stdout_pipe.output().decode()))
-        stderr_pipe.write_bypass(
-            '\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output().decode()))
-        os._exit(1)
-    def try_set_handler(name, handler):
-      try:
-        signal.signal(getattr(signal, name), handler)
-      except AttributeError:
-        pass
-    try_set_handler('SIGINT', sigint_handler)
-    try_set_handler('SIGSEGV', fault_handler)
-    try_set_handler('SIGBUS', fault_handler)
-    try_set_handler('SIGABRT', fault_handler)
-    try_set_handler('SIGFPE', fault_handler)
-    try_set_handler('SIGILL', fault_handler)
-    # Sometimes output will lag after a test has successfully finished; we
-    # ignore such writes to our pipes.
-    try_set_handler('SIGPIPE', signal.SIG_IGN)
-
-    # Run the tests
-    result.startTestRun()
-    for augmented_case in augmented_cases:
-      sys.stdout.write('Running       {}\n'.format(augmented_case.case.id()))
-      sys.stdout.flush()
-      case_thread = threading.Thread(
-          target=augmented_case.case.run, args=(result,))
-      try:
-        with stdout_pipe, stderr_pipe:
-          case_thread.start()
-          while case_thread.is_alive():
+    def run(self, suite):
+        """See setuptools' test_runner setup argument for information."""
+        # only run test cases with id starting with given prefix
+        testcase_filter = os.getenv('GRPC_PYTHON_TESTRUNNER_FILTER')
+        filtered_cases = []
+        for case in _loader.iterate_suite_cases(suite):
+            if not testcase_filter or case.id().startswith(testcase_filter):
+                filtered_cases.append(case)
+
+        # Ensure that every test case has no collision with any other test case in
+        # the augmented results.
+        augmented_cases = [
+            AugmentedCase(case, uuid.uuid4()) for case in filtered_cases
+        ]
+        case_id_by_case = dict((augmented_case.case, augmented_case.id)
+                               for augmented_case in augmented_cases)
+        result_out = moves.cStringIO()
+        result = _result.TerminalResult(
+            result_out, id_map=lambda case: case_id_by_case[case])
+        stdout_pipe = CaptureFile(sys.stdout.fileno())
+        stderr_pipe = CaptureFile(sys.stderr.fileno())
+        kill_flag = [False]
+
+        def sigint_handler(signal_number, frame):
+            if signal_number == signal.SIGINT:
+                kill_flag[0] = True  # Python 2.7 not having 'local'... :-(
+            signal.signal(signal_number, signal.SIG_DFL)
+
+        def fault_handler(signal_number, frame):
+            stdout_pipe.write_bypass(
+                'Received fault signal {}\nstdout:\n{}\n\nstderr:{}\n'.format(
+                    signal_number, stdout_pipe.output(), stderr_pipe.output()))
+            os._exit(1)
+
+        def check_kill_self():
+            if kill_flag[0]:
+                stdout_pipe.write_bypass('Stopping tests short...')
+                result.stopTestRun()
+                stdout_pipe.write_bypass(result_out.getvalue())
+                stdout_pipe.write_bypass('\ninterrupted stdout:\n{}\n'.format(
+                    stdout_pipe.output().decode()))
+                stderr_pipe.write_bypass('\ninterrupted stderr:\n{}\n'.format(
+                    stderr_pipe.output().decode()))
+                os._exit(1)
+
+        def try_set_handler(name, handler):
+            try:
+                signal.signal(getattr(signal, name), handler)
+            except AttributeError:
+                pass
+
+        try_set_handler('SIGINT', sigint_handler)
+        try_set_handler('SIGSEGV', fault_handler)
+        try_set_handler('SIGBUS', fault_handler)
+        try_set_handler('SIGABRT', fault_handler)
+        try_set_handler('SIGFPE', fault_handler)
+        try_set_handler('SIGILL', fault_handler)
+        # Sometimes output will lag after a test has successfully finished; we
+        # ignore such writes to our pipes.
+        try_set_handler('SIGPIPE', signal.SIG_IGN)
+
+        # Run the tests
+        result.startTestRun()
+        for augmented_case in augmented_cases:
+            sys.stdout.write('Running       {}\n'.format(augmented_case.case.id(
+            )))
+            sys.stdout.flush()
+            case_thread = threading.Thread(
+                target=augmented_case.case.run, args=(result,))
+            try:
+                with stdout_pipe, stderr_pipe:
+                    case_thread.start()
+                    while case_thread.is_alive():
+                        check_kill_self()
+                        time.sleep(0)
+                    case_thread.join()
+            except:
+                # re-raise the exception after forcing the with-block to end
+                raise
+            result.set_output(augmented_case.case,
+                              stdout_pipe.output(), stderr_pipe.output())
+            sys.stdout.write(result_out.getvalue())
+            sys.stdout.flush()
+            result_out.truncate(0)
             check_kill_self()
-            time.sleep(0)
-          case_thread.join()
-      except:
-        # re-raise the exception after forcing the with-block to end
-        raise
-      result.set_output(
-          augmented_case.case, stdout_pipe.output(), stderr_pipe.output())
-      sys.stdout.write(result_out.getvalue())
-      sys.stdout.flush()
-      result_out.truncate(0)
-      check_kill_self()
-    result.stopTestRun()
-    stdout_pipe.close()
-    stderr_pipe.close()
-
-    # Report results
-    sys.stdout.write(result_out.getvalue())
-    sys.stdout.flush()
-    signal.signal(signal.SIGINT, signal.SIG_DFL)
-    with open('report.xml', 'wb') as report_xml_file:
-      _result.jenkins_junit_xml(result).write(report_xml_file)
-    return result
-
+        result.stopTestRun()
+        stdout_pipe.close()
+        stderr_pipe.close()
+
+        # Report results
+        sys.stdout.write(result_out.getvalue())
+        sys.stdout.flush()
+        signal.signal(signal.SIGINT, signal.SIG_DFL)
+        with open('report.xml', 'wb') as report_xml_file:
+            _result.jenkins_junit_xml(result).write(report_xml_file)
+        return result
diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
index 5dde72b169..363b4c5f99 100644
--- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
+++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc_health.v1.health."""
 
 import unittest
@@ -41,55 +40,55 @@ from tests.unit.framework.common import test_constants
 
 class HealthServicerTest(unittest.TestCase):
 
-  def setUp(self):
-    servicer = health.HealthServicer()
-    servicer.set('', health_pb2.HealthCheckResponse.SERVING)
-    servicer.set('grpc.test.TestServiceServing',
-                 health_pb2.HealthCheckResponse.SERVING)
-    servicer.set('grpc.test.TestServiceUnknown',
-                 health_pb2.HealthCheckResponse.UNKNOWN)
-    servicer.set('grpc.test.TestServiceNotServing',
-                 health_pb2.HealthCheckResponse.NOT_SERVING)
-    server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(server_pool)
-    port = self._server.add_insecure_port('[::]:0')
-    health_pb2.add_HealthServicer_to_server(servicer, self._server)
-    self._server.start()
+    def setUp(self):
+        servicer = health.HealthServicer()
+        servicer.set('', health_pb2.HealthCheckResponse.SERVING)
+        servicer.set('grpc.test.TestServiceServing',
+                     health_pb2.HealthCheckResponse.SERVING)
+        servicer.set('grpc.test.TestServiceUnknown',
+                     health_pb2.HealthCheckResponse.UNKNOWN)
+        servicer.set('grpc.test.TestServiceNotServing',
+                     health_pb2.HealthCheckResponse.NOT_SERVING)
+        server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(server_pool)
+        port = self._server.add_insecure_port('[::]:0')
+        health_pb2.add_HealthServicer_to_server(servicer, self._server)
+        self._server.start()
+
+        channel = grpc.insecure_channel('localhost:%d' % port)
+        self._stub = health_pb2.HealthStub(channel)
 
-    channel = grpc.insecure_channel('localhost:%d' % port)
-    self._stub = health_pb2.HealthStub(channel)
+    def test_empty_service(self):
+        request = health_pb2.HealthCheckRequest()
+        resp = self._stub.Check(request)
+        self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
 
-  def test_empty_service(self):
-    request = health_pb2.HealthCheckRequest()
-    resp = self._stub.Check(request)
-    self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
+    def test_serving_service(self):
+        request = health_pb2.HealthCheckRequest(
+            service='grpc.test.TestServiceServing')
+        resp = self._stub.Check(request)
+        self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
 
-  def test_serving_service(self):
-    request = health_pb2.HealthCheckRequest(
-        service='grpc.test.TestServiceServing')
-    resp = self._stub.Check(request)
-    self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
+    def test_unknown_serivce(self):
+        request = health_pb2.HealthCheckRequest(
+            service='grpc.test.TestServiceUnknown')
+        resp = self._stub.Check(request)
+        self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)
 
-  def test_unknown_serivce(self):
-    request = health_pb2.HealthCheckRequest(
-        service='grpc.test.TestServiceUnknown')
-    resp = self._stub.Check(request)
-    self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)
+    def test_not_serving_service(self):
+        request = health_pb2.HealthCheckRequest(
+            service='grpc.test.TestServiceNotServing')
+        resp = self._stub.Check(request)
+        self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING,
+                         resp.status)
 
-  def test_not_serving_service(self):
-    request = health_pb2.HealthCheckRequest(
-        service='grpc.test.TestServiceNotServing')
-    resp = self._stub.Check(request)
-    self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status)
+    def test_not_found_service(self):
+        request = health_pb2.HealthCheckRequest(service='not-found')
+        with self.assertRaises(grpc.RpcError) as context:
+            resp = self._stub.Check(request)
 
-  def test_not_found_service(self):
-    request = health_pb2.HealthCheckRequest(
-        service='not-found')
-    with self.assertRaises(grpc.RpcError) as context:
-      resp = self._stub.Check(request)
-  
-    self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code())
+        self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/http2/_negative_http2_client.py b/src/python/grpcio_tests/tests/http2/_negative_http2_client.py
index f8604683b3..c192d827c4 100644
--- a/src/python/grpcio_tests/tests/http2/_negative_http2_client.py
+++ b/src/python/grpcio_tests/tests/http2/_negative_http2_client.py
@@ -26,7 +26,6 @@
 # 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.
-
 """The Python client used to test negative http2 conditions."""
 
 import argparse
@@ -35,29 +34,32 @@ import grpc
 from src.proto.grpc.testing import test_pb2
 from src.proto.grpc.testing import messages_pb2
 
+
 def _validate_payload_type_and_length(response, expected_type, expected_length):
-  if response.payload.type is not expected_type:
-    raise ValueError(
-      'expected payload type %s, got %s' %
-          (expected_type, type(response.payload.type)))
-  elif len(response.payload.body) != expected_length:
-    raise ValueError(
-      'expected payload body size %d, got %d' %
-          (expected_length, len(response.payload.body)))
+    if response.payload.type is not expected_type:
+        raise ValueError('expected payload type %s, got %s' %
+                         (expected_type, type(response.payload.type)))
+    elif len(response.payload.body) != expected_length:
+        raise ValueError('expected payload body size %d, got %d' %
+                         (expected_length, len(response.payload.body)))
+
 
 def _expect_status_code(call, expected_code):
-  if call.code() != expected_code:
-    raise ValueError(
-      'expected code %s, got %s' % (expected_code, call.code()))
+    if call.code() != expected_code:
+        raise ValueError('expected code %s, got %s' %
+                         (expected_code, call.code()))
+
 
 def _expect_status_details(call, expected_details):
-  if call.details() != expected_details:
-    raise ValueError(
-      'expected message %s, got %s' % (expected_details, call.details()))
+    if call.details() != expected_details:
+        raise ValueError('expected message %s, got %s' %
+                         (expected_details, call.details()))
+
 
 def _validate_status_code_and_details(call, expected_code, expected_details):
-  _expect_status_code(call, expected_code)
-  _expect_status_details(call, expected_details)
+    _expect_status_code(call, expected_code)
+    _expect_status_details(call, expected_details)
+
 
 # common requests
 _REQUEST_SIZE = 314159
@@ -68,86 +70,103 @@ _SIMPLE_REQUEST = messages_pb2.SimpleRequest(
     response_size=_RESPONSE_SIZE,
     payload=messages_pb2.Payload(body=b'\x00' * _REQUEST_SIZE))
 
+
 def _goaway(stub):
-  first_response = stub.UnaryCall(_SIMPLE_REQUEST)
-  _validate_payload_type_and_length(first_response, 
-      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
-  second_response = stub.UnaryCall(_SIMPLE_REQUEST)
-  _validate_payload_type_and_length(second_response, 
-      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+    first_response = stub.UnaryCall(_SIMPLE_REQUEST)
+    _validate_payload_type_and_length(first_response, messages_pb2.COMPRESSABLE,
+                                      _RESPONSE_SIZE)
+    second_response = stub.UnaryCall(_SIMPLE_REQUEST)
+    _validate_payload_type_and_length(second_response,
+                                      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
 
 def _rst_after_header(stub):
-  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
-  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNAVAILABLE, "")
+    resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+    _validate_status_code_and_details(resp_future, grpc.StatusCode.UNAVAILABLE,
+                                      "")
+
 
 def _rst_during_data(stub):
-  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
-  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+    resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+    _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+
 
 def _rst_after_data(stub):
-  resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
-  _validate_payload_type_and_length(next(resp_future),
-      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
-  _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+    resp_future = stub.UnaryCall.future(_SIMPLE_REQUEST)
+    _validate_payload_type_and_length(
+        next(resp_future), messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+    _validate_status_code_and_details(resp_future, grpc.StatusCode.UNKNOWN, "")
+
 
 def _ping(stub):
-  response = stub.UnaryCall(_SIMPLE_REQUEST)
-  _validate_payload_type_and_length(response, 
-      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+    response = stub.UnaryCall(_SIMPLE_REQUEST)
+    _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE,
+                                      _RESPONSE_SIZE)
+
 
 def _max_streams(stub):
-  # send one req to ensure server sets MAX_STREAMS
-  response = stub.UnaryCall(_SIMPLE_REQUEST)
-  _validate_payload_type_and_length(response, 
-      messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
-
-  # give the streams a workout
-  futures = []
-  for _ in range(15):
-    futures.append(stub.UnaryCall.future(_SIMPLE_REQUEST))
-  for future in futures:
-    _validate_payload_type_and_length(future.result(),
-        messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+    # send one req to ensure server sets MAX_STREAMS
+    response = stub.UnaryCall(_SIMPLE_REQUEST)
+    _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE,
+                                      _RESPONSE_SIZE)
+
+    # give the streams a workout
+    futures = []
+    for _ in range(15):
+        futures.append(stub.UnaryCall.future(_SIMPLE_REQUEST))
+    for future in futures:
+        _validate_payload_type_and_length(
+            future.result(), messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)
+
 
 def _run_test_case(test_case, stub):
-  if test_case == 'goaway':
-    _goaway(stub)
-  elif test_case == 'rst_after_header':
-    _rst_after_header(stub)
-  elif test_case == 'rst_during_data':
-    _rst_during_data(stub)
-  elif test_case == 'rst_after_data':
-    _rst_after_data(stub)
-  elif test_case =='ping':
-    _ping(stub)
-  elif test_case == 'max_streams':
-    _max_streams(stub)
-  else:
-    raise ValueError("Invalid test case: %s" % test_case)
+    if test_case == 'goaway':
+        _goaway(stub)
+    elif test_case == 'rst_after_header':
+        _rst_after_header(stub)
+    elif test_case == 'rst_during_data':
+        _rst_during_data(stub)
+    elif test_case == 'rst_after_data':
+        _rst_after_data(stub)
+    elif test_case == 'ping':
+        _ping(stub)
+    elif test_case == 'max_streams':
+        _max_streams(stub)
+    else:
+        raise ValueError("Invalid test case: %s" % test_case)
+
 
 def _args():
-  parser = argparse.ArgumentParser()
-  parser.add_argument(
-      '--server_host', help='the host to which to connect', type=str,
-      default="127.0.0.1")
-  parser.add_argument(
-      '--server_port', help='the port to which to connect', type=int,
-      default="8080")
-  parser.add_argument(
-      '--test_case', help='the test case to execute', type=str,
-      default="goaway")
-  return parser.parse_args()
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        '--server_host',
+        help='the host to which to connect',
+        type=str,
+        default="127.0.0.1")
+    parser.add_argument(
+        '--server_port',
+        help='the port to which to connect',
+        type=int,
+        default="8080")
+    parser.add_argument(
+        '--test_case',
+        help='the test case to execute',
+        type=str,
+        default="goaway")
+    return parser.parse_args()
+
 
 def _stub(server_host, server_port):
-  target = '{}:{}'.format(server_host, server_port)
-  channel = grpc.insecure_channel(target)
-  return test_pb2.TestServiceStub(channel)
+    target = '{}:{}'.format(server_host, server_port)
+    channel = grpc.insecure_channel(target)
+    return test_pb2.TestServiceStub(channel)
+
 
 def main():
-  args = _args()
-  stub = _stub(args.server_host, args.server_port)
-  _run_test_case(args.test_case, stub)
+    args = _args()
+    stub = _stub(args.server_host, args.server_port)
+    _run_test_case(args.test_case, stub)
 
 
 if __name__ == '__main__':
-  main()
+    main()
diff --git a/src/python/grpcio_tests/tests/interop/__init__.py b/src/python/grpcio_tests/tests/interop/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/interop/__init__.py
+++ b/src/python/grpcio_tests/tests/interop/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
index 4fb22b4d9d..58f3b364ba 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Insecure client-server interoperability as a unit test."""
 
 from concurrent import futures
@@ -40,19 +39,18 @@ from tests.interop import methods
 from tests.interop import server
 
 
-class InsecureIntraopTest(
-    _intraop_test_case.IntraopTestCase,
-    unittest.TestCase):
+class InsecureIntraopTest(_intraop_test_case.IntraopTestCase,
+                          unittest.TestCase):
 
-  def setUp(self):
-    self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-    test_pb2.add_TestServiceServicer_to_server(
-        methods.TestService(), self.server)
-    port = self.server.add_insecure_port('[::]:0')
-    self.server.start()
-    self.stub = test_pb2.TestServiceStub(
-        grpc.insecure_channel('localhost:{}'.format(port)))
+    def setUp(self):
+        self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+        test_pb2.add_TestServiceServicer_to_server(methods.TestService(),
+                                                   self.server)
+        port = self.server.add_insecure_port('[::]:0')
+        self.server.start()
+        self.stub = test_pb2.TestServiceStub(
+            grpc.insecure_channel('localhost:{}'.format(port)))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/_intraop_test_case.py b/src/python/grpcio_tests/tests/interop/_intraop_test_case.py
index fe1c173992..424f93980c 100644
--- a/src/python/grpcio_tests/tests/interop/_intraop_test_case.py
+++ b/src/python/grpcio_tests/tests/interop/_intraop_test_case.py
@@ -26,39 +26,41 @@
 # 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.
-
 """Common code for unit tests of the interoperability test code."""
 
 from tests.interop import methods
 
 
 class IntraopTestCase(object):
-  """Unit test methods.
+    """Unit test methods.
 
   This class must be mixed in with unittest.TestCase and a class that defines
   setUp and tearDown methods that manage a stub attribute.
   """
 
-  def testEmptyUnary(self):
-    methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None)
+    def testEmptyUnary(self):
+        methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None)
 
-  def testLargeUnary(self):
-    methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None)
+    def testLargeUnary(self):
+        methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None)
 
-  def testServerStreaming(self):
-    methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None)
+    def testServerStreaming(self):
+        methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None)
 
-  def testClientStreaming(self):
-    methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None)
+    def testClientStreaming(self):
+        methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None)
 
-  def testPingPong(self):
-    methods.TestCase.PING_PONG.test_interoperability(self.stub, None)
+    def testPingPong(self):
+        methods.TestCase.PING_PONG.test_interoperability(self.stub, None)
 
-  def testCancelAfterBegin(self):
-    methods.TestCase.CANCEL_AFTER_BEGIN.test_interoperability(self.stub, None)
+    def testCancelAfterBegin(self):
+        methods.TestCase.CANCEL_AFTER_BEGIN.test_interoperability(self.stub,
+                                                                  None)
 
-  def testCancelAfterFirstResponse(self):
-    methods.TestCase.CANCEL_AFTER_FIRST_RESPONSE.test_interoperability(self.stub, None)
+    def testCancelAfterFirstResponse(self):
+        methods.TestCase.CANCEL_AFTER_FIRST_RESPONSE.test_interoperability(
+            self.stub, None)
 
-  def testTimeoutOnSleepingServer(self):
-    methods.TestCase.TIMEOUT_ON_SLEEPING_SERVER.test_interoperability(self.stub, None)
+    def testTimeoutOnSleepingServer(self):
+        methods.TestCase.TIMEOUT_ON_SLEEPING_SERVER.test_interoperability(
+            self.stub, None)
diff --git a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
index 3665c69726..b28406ed3f 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Secure client-server interoperability as a unit test."""
 
 from concurrent import futures
@@ -42,24 +41,24 @@ from tests.interop import resources
 _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
 
-class SecureIntraopTest(
-    _intraop_test_case.IntraopTestCase,
-    unittest.TestCase):
+class SecureIntraopTest(_intraop_test_case.IntraopTestCase, unittest.TestCase):
 
-  def setUp(self):
-    self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-    test_pb2.add_TestServiceServicer_to_server(
-        methods.TestService(), self.server)
-    port = self.server.add_secure_port(
-        '[::]:0', grpc.ssl_server_credentials(
-            [(resources.private_key(), resources.certificate_chain())]))
-    self.server.start()
-    self.stub = test_pb2.TestServiceStub(
-        grpc.secure_channel(
-            'localhost:{}'.format(port),
-            grpc.ssl_channel_credentials(resources.test_root_certificates()),
-            (('grpc.ssl_target_name_override', _SERVER_HOST_OVERRIDE,),)))
+    def setUp(self):
+        self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+        test_pb2.add_TestServiceServicer_to_server(methods.TestService(),
+                                                   self.server)
+        port = self.server.add_secure_port(
+            '[::]:0',
+            grpc.ssl_server_credentials(
+                [(resources.private_key(), resources.certificate_chain())]))
+        self.server.start()
+        self.stub = test_pb2.TestServiceStub(
+            grpc.secure_channel('localhost:{}'.format(port),
+                                grpc.ssl_channel_credentials(
+                                    resources.test_root_certificates()), ((
+                                        'grpc.ssl_target_name_override',
+                                        _SERVER_HOST_OVERRIDE,),)))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index afaa466254..f177896e8e 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -26,7 +26,6 @@
 # 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.
-
 """The Python implementation of the GRPC interoperability test client."""
 
 import argparse
@@ -41,93 +40,107 @@ from tests.interop import resources
 
 
 def _args():
-  parser = argparse.ArgumentParser()
-  parser.add_argument(
-      '--server_host', help='the host to which to connect', type=str,
-      default="127.0.0.1")
-  parser.add_argument(
-      '--server_port', help='the port to which to connect', type=int)
-  parser.add_argument(
-      '--test_case', help='the test case to execute', type=str,
-      default="large_unary")
-  parser.add_argument(
-      '--use_tls', help='require a secure connection', default=False,
-      type=resources.parse_bool)
-  parser.add_argument(
-      '--use_test_ca', help='replace platform root CAs with ca.pem',
-      default=False, type=resources.parse_bool)
-  parser.add_argument(
-      '--server_host_override', default="foo.test.google.fr",
-      help='the server host to which to claim to connect', type=str)
-  parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str)
-  parser.add_argument(
-      '--default_service_account',
-      help='email address of the default service account', type=str)
-  return parser.parse_args()
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        '--server_host',
+        help='the host to which to connect',
+        type=str,
+        default="127.0.0.1")
+    parser.add_argument(
+        '--server_port', help='the port to which to connect', type=int)
+    parser.add_argument(
+        '--test_case',
+        help='the test case to execute',
+        type=str,
+        default="large_unary")
+    parser.add_argument(
+        '--use_tls',
+        help='require a secure connection',
+        default=False,
+        type=resources.parse_bool)
+    parser.add_argument(
+        '--use_test_ca',
+        help='replace platform root CAs with ca.pem',
+        default=False,
+        type=resources.parse_bool)
+    parser.add_argument(
+        '--server_host_override',
+        default="foo.test.google.fr",
+        help='the server host to which to claim to connect',
+        type=str)
+    parser.add_argument(
+        '--oauth_scope', help='scope for OAuth tokens', type=str)
+    parser.add_argument(
+        '--default_service_account',
+        help='email address of the default service account',
+        type=str)
+    return parser.parse_args()
 
 
 def _application_default_credentials():
-  return oauth2client_client.GoogleCredentials.get_application_default()
+    return oauth2client_client.GoogleCredentials.get_application_default()
 
 
 def _stub(args):
-  target = '{}:{}'.format(args.server_host, args.server_port)
-  if args.test_case == 'oauth2_auth_token':
-    google_credentials = _application_default_credentials()
-    scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
-    access_token = scoped_credentials.get_access_token().access_token
-    call_credentials = grpc.access_token_call_credentials(access_token)
-  elif args.test_case == 'compute_engine_creds':
-    google_credentials = _application_default_credentials()
-    scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
-    # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
-    # remaining use of the Beta API.
-    call_credentials = implementations.google_call_credentials(
-        scoped_credentials)
-  elif args.test_case == 'jwt_token_creds':
-    google_credentials = _application_default_credentials()
-    # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
-    # remaining use of the Beta API.
-    call_credentials = implementations.google_call_credentials(
-        google_credentials)
-  else:
-    call_credentials = None
-  if args.use_tls:
-    if args.use_test_ca:
-      root_certificates = resources.test_root_certificates()
+    target = '{}:{}'.format(args.server_host, args.server_port)
+    if args.test_case == 'oauth2_auth_token':
+        google_credentials = _application_default_credentials()
+        scoped_credentials = google_credentials.create_scoped(
+            [args.oauth_scope])
+        access_token = scoped_credentials.get_access_token().access_token
+        call_credentials = grpc.access_token_call_credentials(access_token)
+    elif args.test_case == 'compute_engine_creds':
+        google_credentials = _application_default_credentials()
+        scoped_credentials = google_credentials.create_scoped(
+            [args.oauth_scope])
+        # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+        # remaining use of the Beta API.
+        call_credentials = implementations.google_call_credentials(
+            scoped_credentials)
+    elif args.test_case == 'jwt_token_creds':
+        google_credentials = _application_default_credentials()
+        # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+        # remaining use of the Beta API.
+        call_credentials = implementations.google_call_credentials(
+            google_credentials)
     else:
-      root_certificates = None  # will load default roots.
-
-    channel_credentials = grpc.ssl_channel_credentials(root_certificates)
-    if call_credentials is not None:
-      channel_credentials = grpc.composite_channel_credentials(
-          channel_credentials, call_credentials)
-
-    channel = grpc.secure_channel(
-        target, channel_credentials,
-        (('grpc.ssl_target_name_override', args.server_host_override,),))
-  else:
-    channel = grpc.insecure_channel(target)
-  if args.test_case == "unimplemented_service":
-    return test_pb2.UnimplementedServiceStub(channel)
-  else:
-    return test_pb2.TestServiceStub(channel)
+        call_credentials = None
+    if args.use_tls:
+        if args.use_test_ca:
+            root_certificates = resources.test_root_certificates()
+        else:
+            root_certificates = None  # will load default roots.
+
+        channel_credentials = grpc.ssl_channel_credentials(root_certificates)
+        if call_credentials is not None:
+            channel_credentials = grpc.composite_channel_credentials(
+                channel_credentials, call_credentials)
+
+        channel = grpc.secure_channel(target, channel_credentials, ((
+            'grpc.ssl_target_name_override',
+            args.server_host_override,),))
+    else:
+        channel = grpc.insecure_channel(target)
+    if args.test_case == "unimplemented_service":
+        return test_pb2.UnimplementedServiceStub(channel)
+    else:
+        return test_pb2.TestServiceStub(channel)
 
 
 def _test_case_from_arg(test_case_arg):
-  for test_case in methods.TestCase:
-    if test_case_arg == test_case.value:
-      return test_case
-  else:
-    raise ValueError('No test case "%s"!' % test_case_arg)
+    for test_case in methods.TestCase:
+        if test_case_arg == test_case.value:
+            return test_case
+    else:
+        raise ValueError('No test case "%s"!' % test_case_arg)
 
 
 def test_interoperability():
-  args = _args()
-  stub = _stub(args)
-  test_case = _test_case_from_arg(args.test_case)
-  test_case.test_interoperability(stub, args)
+    args = _args()
+    stub = _stub(args)
+    test_case = _test_case_from_arg(args.test_case)
+    test_case.test_interoperability(stub, args)
 
 
 if __name__ == '__main__':
-  test_interoperability()
+    test_interoperability()
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 9038ae5751..e1f8722168 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Implementations of interoperability test methods."""
 
 import enum
@@ -46,463 +45,483 @@ from src.proto.grpc.testing import test_pb2
 _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial"
 _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin"
 
+
 def _maybe_echo_metadata(servicer_context):
-  """Copies metadata from request to response if it is present."""
-  invocation_metadata = dict(servicer_context.invocation_metadata())
-  if _INITIAL_METADATA_KEY in invocation_metadata:
-    initial_metadatum = (
-        _INITIAL_METADATA_KEY, invocation_metadata[_INITIAL_METADATA_KEY])
-    servicer_context.send_initial_metadata((initial_metadatum,))
-  if _TRAILING_METADATA_KEY in invocation_metadata:
-    trailing_metadatum = (
-      _TRAILING_METADATA_KEY, invocation_metadata[_TRAILING_METADATA_KEY])
-    servicer_context.set_trailing_metadata((trailing_metadatum,))
+    """Copies metadata from request to response if it is present."""
+    invocation_metadata = dict(servicer_context.invocation_metadata())
+    if _INITIAL_METADATA_KEY in invocation_metadata:
+        initial_metadatum = (_INITIAL_METADATA_KEY,
+                             invocation_metadata[_INITIAL_METADATA_KEY])
+        servicer_context.send_initial_metadata((initial_metadatum,))
+    if _TRAILING_METADATA_KEY in invocation_metadata:
+        trailing_metadatum = (_TRAILING_METADATA_KEY,
+                              invocation_metadata[_TRAILING_METADATA_KEY])
+        servicer_context.set_trailing_metadata((trailing_metadatum,))
+
 
 def _maybe_echo_status_and_message(request, servicer_context):
-  """Sets the response context code and details if the request asks for them"""
-  if request.HasField('response_status'):
-    servicer_context.set_code(request.response_status.code)
-    servicer_context.set_details(request.response_status.message)
+    """Sets the response context code and details if the request asks for them"""
+    if request.HasField('response_status'):
+        servicer_context.set_code(request.response_status.code)
+        servicer_context.set_details(request.response_status.message)
+
 
 class TestService(test_pb2.TestServiceServicer):
 
-  def EmptyCall(self, request, context):
-    _maybe_echo_metadata(context)
-    return empty_pb2.Empty()
+    def EmptyCall(self, request, context):
+        _maybe_echo_metadata(context)
+        return empty_pb2.Empty()
 
-  def UnaryCall(self, request, context):
-    _maybe_echo_metadata(context)
-    _maybe_echo_status_and_message(request, context)
-    return messages_pb2.SimpleResponse(
-        payload=messages_pb2.Payload(
+    def UnaryCall(self, request, context):
+        _maybe_echo_metadata(context)
+        _maybe_echo_status_and_message(request, context)
+        return messages_pb2.SimpleResponse(payload=messages_pb2.Payload(
             type=messages_pb2.COMPRESSABLE,
             body=b'\x00' * request.response_size))
 
-  def StreamingOutputCall(self, request, context):
-    _maybe_echo_status_and_message(request, context)
-    for response_parameters in request.response_parameters:
-      yield messages_pb2.StreamingOutputCallResponse(
-          payload=messages_pb2.Payload(
-              type=request.response_type,
-              body=b'\x00' * response_parameters.size))
-
-  def StreamingInputCall(self, request_iterator, context):
-    aggregate_size = 0
-    for request in request_iterator:
-      if request.payload is not None and request.payload.body:
-        aggregate_size += len(request.payload.body)
-    return messages_pb2.StreamingInputCallResponse(
-        aggregated_payload_size=aggregate_size)
-
-  def FullDuplexCall(self, request_iterator, context):
-    _maybe_echo_metadata(context)
-    for request in request_iterator:
-      _maybe_echo_status_and_message(request, context)
-      for response_parameters in request.response_parameters:
-        yield messages_pb2.StreamingOutputCallResponse(
-            payload=messages_pb2.Payload(
-                type=request.payload.type,
-                body=b'\x00' * response_parameters.size))
-
-  # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
-  # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)...
-  def HalfDuplexCall(self, request_iterator, context):
-    return self.FullDuplexCall(request_iterator, context)
+    def StreamingOutputCall(self, request, context):
+        _maybe_echo_status_and_message(request, context)
+        for response_parameters in request.response_parameters:
+            yield messages_pb2.StreamingOutputCallResponse(
+                payload=messages_pb2.Payload(
+                    type=request.response_type,
+                    body=b'\x00' * response_parameters.size))
+
+    def StreamingInputCall(self, request_iterator, context):
+        aggregate_size = 0
+        for request in request_iterator:
+            if request.payload is not None and request.payload.body:
+                aggregate_size += len(request.payload.body)
+        return messages_pb2.StreamingInputCallResponse(
+            aggregated_payload_size=aggregate_size)
+
+    def FullDuplexCall(self, request_iterator, context):
+        _maybe_echo_metadata(context)
+        for request in request_iterator:
+            _maybe_echo_status_and_message(request, context)
+            for response_parameters in request.response_parameters:
+                yield messages_pb2.StreamingOutputCallResponse(
+                    payload=messages_pb2.Payload(
+                        type=request.payload.type,
+                        body=b'\x00' * response_parameters.size))
+
+    # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
+    # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)...
+    def HalfDuplexCall(self, request_iterator, context):
+        return self.FullDuplexCall(request_iterator, context)
 
 
 def _expect_status_code(call, expected_code):
-  if call.code() != expected_code:
-    raise ValueError(
-      'expected code %s, got %s' % (expected_code, call.code()))
+    if call.code() != expected_code:
+        raise ValueError('expected code %s, got %s' %
+                         (expected_code, call.code()))
 
 
 def _expect_status_details(call, expected_details):
-  if call.details() != expected_details:
-    raise ValueError(
-      'expected message %s, got %s' % (expected_details, call.details()))
+    if call.details() != expected_details:
+        raise ValueError('expected message %s, got %s' %
+                         (expected_details, call.details()))
 
 
 def _validate_status_code_and_details(call, expected_code, expected_details):
-  _expect_status_code(call, expected_code)
-  _expect_status_details(call, expected_details)
+    _expect_status_code(call, expected_code)
+    _expect_status_details(call, expected_details)
 
 
 def _validate_payload_type_and_length(response, expected_type, expected_length):
-  if response.payload.type is not expected_type:
-    raise ValueError(
-      'expected payload type %s, got %s' %
-          (expected_type, type(response.payload.type)))
-  elif len(response.payload.body) != expected_length:
-    raise ValueError(
-      'expected payload body size %d, got %d' %
-          (expected_length, len(response.payload.body)))
-
-
-def _large_unary_common_behavior(
-    stub, fill_username, fill_oauth_scope, call_credentials):
-  size = 314159
-  request = messages_pb2.SimpleRequest(
-      response_type=messages_pb2.COMPRESSABLE, response_size=size,
-      payload=messages_pb2.Payload(body=b'\x00' * 271828),
-      fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
-  response_future = stub.UnaryCall.future(
-      request, credentials=call_credentials)
-  response = response_future.result()
-  _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size)
-  return response
+    if response.payload.type is not expected_type:
+        raise ValueError('expected payload type %s, got %s' %
+                         (expected_type, type(response.payload.type)))
+    elif len(response.payload.body) != expected_length:
+        raise ValueError('expected payload body size %d, got %d' %
+                         (expected_length, len(response.payload.body)))
+
+
+def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope,
+                                 call_credentials):
+    size = 314159
+    request = messages_pb2.SimpleRequest(
+        response_type=messages_pb2.COMPRESSABLE,
+        response_size=size,
+        payload=messages_pb2.Payload(body=b'\x00' * 271828),
+        fill_username=fill_username,
+        fill_oauth_scope=fill_oauth_scope)
+    response_future = stub.UnaryCall.future(
+        request, credentials=call_credentials)
+    response = response_future.result()
+    _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size)
+    return response
 
 
 def _empty_unary(stub):
-  response = stub.EmptyCall(empty_pb2.Empty())
-  if not isinstance(response, empty_pb2.Empty):
-    raise TypeError(
-        'response is of type "%s", not empty_pb2.Empty!', type(response))
+    response = stub.EmptyCall(empty_pb2.Empty())
+    if not isinstance(response, empty_pb2.Empty):
+        raise TypeError('response is of type "%s", not empty_pb2.Empty!',
+                        type(response))
 
 
 def _large_unary(stub):
-  _large_unary_common_behavior(stub, False, False, None)
+    _large_unary_common_behavior(stub, False, False, None)
 
 
 def _client_streaming(stub):
-  payload_body_sizes = (27182, 8, 1828, 45904,)
-  payloads = (
-      messages_pb2.Payload(body=b'\x00' * size)
-      for size in payload_body_sizes)
-  requests = (
-      messages_pb2.StreamingInputCallRequest(payload=payload)
-      for payload in payloads)
-  response = stub.StreamingInputCall(requests)
-  if response.aggregated_payload_size != 74922:
-    raise ValueError(
-        'incorrect size %d!' % response.aggregated_payload_size)
+    payload_body_sizes = (
+        27182,
+        8,
+        1828,
+        45904,)
+    payloads = (messages_pb2.Payload(body=b'\x00' * size)
+                for size in payload_body_sizes)
+    requests = (messages_pb2.StreamingInputCallRequest(payload=payload)
+                for payload in payloads)
+    response = stub.StreamingInputCall(requests)
+    if response.aggregated_payload_size != 74922:
+        raise ValueError('incorrect size %d!' %
+                         response.aggregated_payload_size)
 
 
 def _server_streaming(stub):
-  sizes = (31415, 9, 2653, 58979,)
-
-  request = messages_pb2.StreamingOutputCallRequest(
-      response_type=messages_pb2.COMPRESSABLE,
-      response_parameters=(
-          messages_pb2.ResponseParameters(size=sizes[0]),
-          messages_pb2.ResponseParameters(size=sizes[1]),
-          messages_pb2.ResponseParameters(size=sizes[2]),
-          messages_pb2.ResponseParameters(size=sizes[3]),
-      )
-  )
-  response_iterator = stub.StreamingOutputCall(request)
-  for index, response in enumerate(response_iterator):
-    _validate_payload_type_and_length(
-        response, messages_pb2.COMPRESSABLE, sizes[index])
+    sizes = (
+        31415,
+        9,
+        2653,
+        58979,)
 
+    request = messages_pb2.StreamingOutputCallRequest(
+        response_type=messages_pb2.COMPRESSABLE,
+        response_parameters=(
+            messages_pb2.ResponseParameters(size=sizes[0]),
+            messages_pb2.ResponseParameters(size=sizes[1]),
+            messages_pb2.ResponseParameters(size=sizes[2]),
+            messages_pb2.ResponseParameters(size=sizes[3]),))
+    response_iterator = stub.StreamingOutputCall(request)
+    for index, response in enumerate(response_iterator):
+        _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE,
+                                          sizes[index])
 
 
 class _Pipe(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._values = []
-    self._open = True
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._values = []
+        self._open = True
 
-  def __iter__(self):
-    return self
+    def __iter__(self):
+        return self
 
-  def __next__(self):
-    return self.next()
+    def __next__(self):
+        return self.next()
 
-  def next(self):
-    with self._condition:
-      while not self._values and self._open:
-        self._condition.wait()
-      if self._values:
-        return self._values.pop(0)
-      else:
-        raise StopIteration()
+    def next(self):
+        with self._condition:
+            while not self._values and self._open:
+                self._condition.wait()
+            if self._values:
+                return self._values.pop(0)
+            else:
+                raise StopIteration()
 
-  def add(self, value):
-    with self._condition:
-      self._values.append(value)
-      self._condition.notify()
+    def add(self, value):
+        with self._condition:
+            self._values.append(value)
+            self._condition.notify()
 
-  def close(self):
-    with self._condition:
-      self._open = False
-      self._condition.notify()
+    def close(self):
+        with self._condition:
+            self._open = False
+            self._condition.notify()
 
-  def __enter__(self):
-    return self
+    def __enter__(self):
+        return self
 
-  def __exit__(self, type, value, traceback):
-    self.close()
+    def __exit__(self, type, value, traceback):
+        self.close()
 
 
 def _ping_pong(stub):
-  request_response_sizes = (31415, 9, 2653, 58979,)
-  request_payload_sizes = (27182, 8, 1828, 45904,)
-
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe)
-    for response_size, payload_size in zip(
-        request_response_sizes, request_payload_sizes):
-      request = messages_pb2.StreamingOutputCallRequest(
-          response_type=messages_pb2.COMPRESSABLE,
-          response_parameters=(
-              messages_pb2.ResponseParameters(size=response_size),),
-          payload=messages_pb2.Payload(body=b'\x00' * payload_size))
-      pipe.add(request)
-      response = next(response_iterator)
-      _validate_payload_type_and_length(
-          response, messages_pb2.COMPRESSABLE, response_size)
+    request_response_sizes = (
+        31415,
+        9,
+        2653,
+        58979,)
+    request_payload_sizes = (
+        27182,
+        8,
+        1828,
+        45904,)
+
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe)
+        for response_size, payload_size in zip(request_response_sizes,
+                                               request_payload_sizes):
+            request = messages_pb2.StreamingOutputCallRequest(
+                response_type=messages_pb2.COMPRESSABLE,
+                response_parameters=(
+                    messages_pb2.ResponseParameters(size=response_size),),
+                payload=messages_pb2.Payload(body=b'\x00' * payload_size))
+            pipe.add(request)
+            response = next(response_iterator)
+            _validate_payload_type_and_length(
+                response, messages_pb2.COMPRESSABLE, response_size)
 
 
 def _cancel_after_begin(stub):
-  with _Pipe() as pipe:
-    response_future = stub.StreamingInputCall.future(pipe)
-    response_future.cancel()
-    if not response_future.cancelled():
-      raise ValueError('expected cancelled method to return True')
-    if response_future.code() is not grpc.StatusCode.CANCELLED:
-      raise ValueError('expected status code CANCELLED')
+    with _Pipe() as pipe:
+        response_future = stub.StreamingInputCall.future(pipe)
+        response_future.cancel()
+        if not response_future.cancelled():
+            raise ValueError('expected cancelled method to return True')
+        if response_future.code() is not grpc.StatusCode.CANCELLED:
+            raise ValueError('expected status code CANCELLED')
 
 
 def _cancel_after_first_response(stub):
-  request_response_sizes = (31415, 9, 2653, 58979,)
-  request_payload_sizes = (27182, 8, 1828, 45904,)
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe)
-
-    response_size = request_response_sizes[0]
-    payload_size = request_payload_sizes[0]
-    request = messages_pb2.StreamingOutputCallRequest(
-        response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(
-            messages_pb2.ResponseParameters(size=response_size),),
-        payload=messages_pb2.Payload(body=b'\x00' * payload_size))
-    pipe.add(request)
-    response = next(response_iterator)
-    # We test the contents of `response` in the Ping Pong test - don't check
-    # them here.
-    response_iterator.cancel()
-
-    try:
-      next(response_iterator)
-    except grpc.RpcError as rpc_error:
-      if rpc_error.code() is not grpc.StatusCode.CANCELLED:
-        raise
-    else:
-      raise ValueError('expected call to be cancelled')
+    request_response_sizes = (
+        31415,
+        9,
+        2653,
+        58979,)
+    request_payload_sizes = (
+        27182,
+        8,
+        1828,
+        45904,)
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe)
+
+        response_size = request_response_sizes[0]
+        payload_size = request_payload_sizes[0]
+        request = messages_pb2.StreamingOutputCallRequest(
+            response_type=messages_pb2.COMPRESSABLE,
+            response_parameters=(
+                messages_pb2.ResponseParameters(size=response_size),),
+            payload=messages_pb2.Payload(body=b'\x00' * payload_size))
+        pipe.add(request)
+        response = next(response_iterator)
+        # We test the contents of `response` in the Ping Pong test - don't check
+        # them here.
+        response_iterator.cancel()
+
+        try:
+            next(response_iterator)
+        except grpc.RpcError as rpc_error:
+            if rpc_error.code() is not grpc.StatusCode.CANCELLED:
+                raise
+        else:
+            raise ValueError('expected call to be cancelled')
 
 
 def _timeout_on_sleeping_server(stub):
-  request_payload_size = 27182
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, timeout=0.001)
-
-    request = messages_pb2.StreamingOutputCallRequest(
-        response_type=messages_pb2.COMPRESSABLE,
-        payload=messages_pb2.Payload(body=b'\x00' * request_payload_size))
-    pipe.add(request)
-    try:
-      next(response_iterator)
-    except grpc.RpcError as rpc_error:
-      if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED:
-        raise
-    else:
-      raise ValueError('expected call to exceed deadline')
+    request_payload_size = 27182
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe, timeout=0.001)
+
+        request = messages_pb2.StreamingOutputCallRequest(
+            response_type=messages_pb2.COMPRESSABLE,
+            payload=messages_pb2.Payload(body=b'\x00' * request_payload_size))
+        pipe.add(request)
+        try:
+            next(response_iterator)
+        except grpc.RpcError as rpc_error:
+            if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED:
+                raise
+        else:
+            raise ValueError('expected call to exceed deadline')
 
 
 def _empty_stream(stub):
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe)
-    pipe.close()
-    try:
-      next(response_iterator)
-      raise ValueError('expected exactly 0 responses')
-    except StopIteration:
-      pass
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe)
+        pipe.close()
+        try:
+            next(response_iterator)
+            raise ValueError('expected exactly 0 responses')
+        except StopIteration:
+            pass
 
 
 def _status_code_and_message(stub):
-  details = 'test status message'
-  code = 2
-  status = grpc.StatusCode.UNKNOWN # code = 2
-
-  # Test with a UnaryCall
-  request = messages_pb2.SimpleRequest(
-      response_type=messages_pb2.COMPRESSABLE,
-      response_size=1,
-      payload=messages_pb2.Payload(body=b'\x00'),
-      response_status=messages_pb2.EchoStatus(code=code, message=details)
-  )
-  response_future = stub.UnaryCall.future(request)
-  _validate_status_code_and_details(response_future, status, details)
-
-  # Test with a FullDuplexCall
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe)
-    request = messages_pb2.StreamingOutputCallRequest(
+    details = 'test status message'
+    code = 2
+    status = grpc.StatusCode.UNKNOWN  # code = 2
+
+    # Test with a UnaryCall
+    request = messages_pb2.SimpleRequest(
         response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(
-            messages_pb2.ResponseParameters(size=1),),
+        response_size=1,
         payload=messages_pb2.Payload(body=b'\x00'),
-        response_status=messages_pb2.EchoStatus(code=code, message=details))
-    pipe.add(request)   # sends the initial request.
-  # Dropping out of with block closes the pipe
-  _validate_status_code_and_details(response_iterator, status, details)
+        response_status=messages_pb2.EchoStatus(
+            code=code, message=details))
+    response_future = stub.UnaryCall.future(request)
+    _validate_status_code_and_details(response_future, status, details)
+
+    # Test with a FullDuplexCall
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe)
+        request = messages_pb2.StreamingOutputCallRequest(
+            response_type=messages_pb2.COMPRESSABLE,
+            response_parameters=(messages_pb2.ResponseParameters(size=1),),
+            payload=messages_pb2.Payload(body=b'\x00'),
+            response_status=messages_pb2.EchoStatus(
+                code=code, message=details))
+        pipe.add(request)  # sends the initial request.
+    # Dropping out of with block closes the pipe
+    _validate_status_code_and_details(response_iterator, status, details)
 
 
 def _unimplemented_method(test_service_stub):
-  response_future = (
-      test_service_stub.UnimplementedCall.future(empty_pb2.Empty()))
-  _expect_status_code(response_future, grpc.StatusCode.UNIMPLEMENTED)
+    response_future = (
+        test_service_stub.UnimplementedCall.future(empty_pb2.Empty()))
+    _expect_status_code(response_future, grpc.StatusCode.UNIMPLEMENTED)
 
 
 def _unimplemented_service(unimplemented_service_stub):
-  response_future = (
-      unimplemented_service_stub.UnimplementedCall.future(empty_pb2.Empty()))
-  _expect_status_code(response_future, grpc.StatusCode.UNIMPLEMENTED)
+    response_future = (
+        unimplemented_service_stub.UnimplementedCall.future(empty_pb2.Empty()))
+    _expect_status_code(response_future, grpc.StatusCode.UNIMPLEMENTED)
 
 
 def _custom_metadata(stub):
-  initial_metadata_value = "test_initial_metadata_value"
-  trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"
-  metadata = (
-      (_INITIAL_METADATA_KEY, initial_metadata_value),
-      (_TRAILING_METADATA_KEY, trailing_metadata_value))
-
-  def _validate_metadata(response):
-    initial_metadata = dict(response.initial_metadata())
-    if initial_metadata[_INITIAL_METADATA_KEY] != initial_metadata_value:
-      raise ValueError(
-        'expected initial metadata %s, got %s' % (
-            initial_metadata_value, initial_metadata[_INITIAL_METADATA_KEY]))
-    trailing_metadata = dict(response.trailing_metadata())
-    if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value:
-      raise ValueError(
-        'expected trailing metadata %s, got %s' % (
-            trailing_metadata_value, initial_metadata[_TRAILING_METADATA_KEY]))
-
-  # Testing with UnaryCall
-  request = messages_pb2.SimpleRequest(
-      response_type=messages_pb2.COMPRESSABLE,
-      response_size=1,
-      payload=messages_pb2.Payload(body=b'\x00'))
-  response_future = stub.UnaryCall.future(request, metadata=metadata)
-  _validate_metadata(response_future)
-
-  # Testing with FullDuplexCall
-  with _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, metadata=metadata)
-    request = messages_pb2.StreamingOutputCallRequest(
+    initial_metadata_value = "test_initial_metadata_value"
+    trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"
+    metadata = ((_INITIAL_METADATA_KEY, initial_metadata_value),
+                (_TRAILING_METADATA_KEY, trailing_metadata_value))
+
+    def _validate_metadata(response):
+        initial_metadata = dict(response.initial_metadata())
+        if initial_metadata[_INITIAL_METADATA_KEY] != initial_metadata_value:
+            raise ValueError('expected initial metadata %s, got %s' %
+                             (initial_metadata_value,
+                              initial_metadata[_INITIAL_METADATA_KEY]))
+        trailing_metadata = dict(response.trailing_metadata())
+        if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value:
+            raise ValueError('expected trailing metadata %s, got %s' %
+                             (trailing_metadata_value,
+                              initial_metadata[_TRAILING_METADATA_KEY]))
+
+    # Testing with UnaryCall
+    request = messages_pb2.SimpleRequest(
         response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(
-            messages_pb2.ResponseParameters(size=1),))
-    pipe.add(request)   # Sends the request
-    next(response_iterator)    # Causes server to send trailing metadata
-  # Dropping out of the with block closes the pipe
-  _validate_metadata(response_iterator)
+        response_size=1,
+        payload=messages_pb2.Payload(body=b'\x00'))
+    response_future = stub.UnaryCall.future(request, metadata=metadata)
+    _validate_metadata(response_future)
+
+    # Testing with FullDuplexCall
+    with _Pipe() as pipe:
+        response_iterator = stub.FullDuplexCall(pipe, metadata=metadata)
+        request = messages_pb2.StreamingOutputCallRequest(
+            response_type=messages_pb2.COMPRESSABLE,
+            response_parameters=(messages_pb2.ResponseParameters(size=1),))
+        pipe.add(request)  # Sends the request
+        next(response_iterator)  # Causes server to send trailing metadata
+    # Dropping out of the with block closes the pipe
+    _validate_metadata(response_iterator)
+
 
 def _compute_engine_creds(stub, args):
-  response = _large_unary_common_behavior(stub, True, True, None)
-  if args.default_service_account != response.username:
-    raise ValueError(
-        'expected username %s, got %s' % (
-            args.default_service_account, response.username))
+    response = _large_unary_common_behavior(stub, True, True, None)
+    if args.default_service_account != response.username:
+        raise ValueError('expected username %s, got %s' %
+                         (args.default_service_account, response.username))
 
 
 def _oauth2_auth_token(stub, args):
-  json_key_filename = os.environ[
-      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
-  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
-  response = _large_unary_common_behavior(stub, True, True, None)
-  if wanted_email != response.username:
-    raise ValueError(
-        'expected username %s, got %s' % (wanted_email, response.username))
-  if args.oauth_scope.find(response.oauth_scope) == -1:
-    raise ValueError(
-        'expected to find oauth scope "{}" in received "{}"'.format(
-            response.oauth_scope, args.oauth_scope))
+    json_key_filename = os.environ[
+        oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+    wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+    response = _large_unary_common_behavior(stub, True, True, None)
+    if wanted_email != response.username:
+        raise ValueError('expected username %s, got %s' %
+                         (wanted_email, response.username))
+    if args.oauth_scope.find(response.oauth_scope) == -1:
+        raise ValueError('expected to find oauth scope "{}" in received "{}"'.
+                         format(response.oauth_scope, args.oauth_scope))
 
 
 def _jwt_token_creds(stub, args):
-  json_key_filename = os.environ[
-      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
-  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
-  response = _large_unary_common_behavior(stub, True, False, None)
-  if wanted_email != response.username:
-    raise ValueError(
-        'expected username %s, got %s' % (wanted_email, response.username))
+    json_key_filename = os.environ[
+        oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+    wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+    response = _large_unary_common_behavior(stub, True, False, None)
+    if wanted_email != response.username:
+        raise ValueError('expected username %s, got %s' %
+                         (wanted_email, response.username))
 
 
 def _per_rpc_creds(stub, args):
-  json_key_filename = os.environ[
-      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
-  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
-  credentials = oauth2client_client.GoogleCredentials.get_application_default()
-  scoped_credentials = credentials.create_scoped([args.oauth_scope])
-  # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
-  # remaining use of the Beta API.
-  call_credentials = implementations.google_call_credentials(
-      scoped_credentials)
-  response = _large_unary_common_behavior(stub, True, False, call_credentials)
-  if wanted_email != response.username:
-    raise ValueError(
-        'expected username %s, got %s' % (wanted_email, response.username))
+    json_key_filename = os.environ[
+        oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+    wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+    credentials = oauth2client_client.GoogleCredentials.get_application_default(
+    )
+    scoped_credentials = credentials.create_scoped([args.oauth_scope])
+    # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+    # remaining use of the Beta API.
+    call_credentials = implementations.google_call_credentials(
+        scoped_credentials)
+    response = _large_unary_common_behavior(stub, True, False, call_credentials)
+    if wanted_email != response.username:
+        raise ValueError('expected username %s, got %s' %
+                         (wanted_email, response.username))
 
 
 @enum.unique
 class TestCase(enum.Enum):
-  EMPTY_UNARY = 'empty_unary'
-  LARGE_UNARY = 'large_unary'
-  SERVER_STREAMING = 'server_streaming'
-  CLIENT_STREAMING = 'client_streaming'
-  PING_PONG = 'ping_pong'
-  CANCEL_AFTER_BEGIN = 'cancel_after_begin'
-  CANCEL_AFTER_FIRST_RESPONSE = 'cancel_after_first_response'
-  EMPTY_STREAM = 'empty_stream'
-  STATUS_CODE_AND_MESSAGE = 'status_code_and_message'
-  UNIMPLEMENTED_METHOD = 'unimplemented_method'
-  UNIMPLEMENTED_SERVICE = 'unimplemented_service'
-  CUSTOM_METADATA = "custom_metadata"
-  COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
-  OAUTH2_AUTH_TOKEN = 'oauth2_auth_token'
-  JWT_TOKEN_CREDS = 'jwt_token_creds'
-  PER_RPC_CREDS = 'per_rpc_creds'
-  TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server'
-
-  def test_interoperability(self, stub, args):
-    if self is TestCase.EMPTY_UNARY:
-      _empty_unary(stub)
-    elif self is TestCase.LARGE_UNARY:
-      _large_unary(stub)
-    elif self is TestCase.SERVER_STREAMING:
-      _server_streaming(stub)
-    elif self is TestCase.CLIENT_STREAMING:
-      _client_streaming(stub)
-    elif self is TestCase.PING_PONG:
-      _ping_pong(stub)
-    elif self is TestCase.CANCEL_AFTER_BEGIN:
-      _cancel_after_begin(stub)
-    elif self is TestCase.CANCEL_AFTER_FIRST_RESPONSE:
-      _cancel_after_first_response(stub)
-    elif self is TestCase.TIMEOUT_ON_SLEEPING_SERVER:
-      _timeout_on_sleeping_server(stub)
-    elif self is TestCase.EMPTY_STREAM:
-      _empty_stream(stub)
-    elif self is TestCase.STATUS_CODE_AND_MESSAGE:
-      _status_code_and_message(stub)
-    elif self is TestCase.UNIMPLEMENTED_METHOD:
-      _unimplemented_method(stub)
-    elif self is TestCase.UNIMPLEMENTED_SERVICE:
-      _unimplemented_service(stub)
-    elif self is TestCase.CUSTOM_METADATA:
-      _custom_metadata(stub)
-    elif self is TestCase.COMPUTE_ENGINE_CREDS:
-      _compute_engine_creds(stub, args)
-    elif self is TestCase.OAUTH2_AUTH_TOKEN:
-      _oauth2_auth_token(stub, args)
-    elif self is TestCase.JWT_TOKEN_CREDS:
-      _jwt_token_creds(stub, args)
-    elif self is TestCase.PER_RPC_CREDS:
-      _per_rpc_creds(stub, args)
-    else:
-      raise NotImplementedError('Test case "%s" not implemented!' % self.name)
+    EMPTY_UNARY = 'empty_unary'
+    LARGE_UNARY = 'large_unary'
+    SERVER_STREAMING = 'server_streaming'
+    CLIENT_STREAMING = 'client_streaming'
+    PING_PONG = 'ping_pong'
+    CANCEL_AFTER_BEGIN = 'cancel_after_begin'
+    CANCEL_AFTER_FIRST_RESPONSE = 'cancel_after_first_response'
+    EMPTY_STREAM = 'empty_stream'
+    STATUS_CODE_AND_MESSAGE = 'status_code_and_message'
+    UNIMPLEMENTED_METHOD = 'unimplemented_method'
+    UNIMPLEMENTED_SERVICE = 'unimplemented_service'
+    CUSTOM_METADATA = "custom_metadata"
+    COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
+    OAUTH2_AUTH_TOKEN = 'oauth2_auth_token'
+    JWT_TOKEN_CREDS = 'jwt_token_creds'
+    PER_RPC_CREDS = 'per_rpc_creds'
+    TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server'
+
+    def test_interoperability(self, stub, args):
+        if self is TestCase.EMPTY_UNARY:
+            _empty_unary(stub)
+        elif self is TestCase.LARGE_UNARY:
+            _large_unary(stub)
+        elif self is TestCase.SERVER_STREAMING:
+            _server_streaming(stub)
+        elif self is TestCase.CLIENT_STREAMING:
+            _client_streaming(stub)
+        elif self is TestCase.PING_PONG:
+            _ping_pong(stub)
+        elif self is TestCase.CANCEL_AFTER_BEGIN:
+            _cancel_after_begin(stub)
+        elif self is TestCase.CANCEL_AFTER_FIRST_RESPONSE:
+            _cancel_after_first_response(stub)
+        elif self is TestCase.TIMEOUT_ON_SLEEPING_SERVER:
+            _timeout_on_sleeping_server(stub)
+        elif self is TestCase.EMPTY_STREAM:
+            _empty_stream(stub)
+        elif self is TestCase.STATUS_CODE_AND_MESSAGE:
+            _status_code_and_message(stub)
+        elif self is TestCase.UNIMPLEMENTED_METHOD:
+            _unimplemented_method(stub)
+        elif self is TestCase.UNIMPLEMENTED_SERVICE:
+            _unimplemented_service(stub)
+        elif self is TestCase.CUSTOM_METADATA:
+            _custom_metadata(stub)
+        elif self is TestCase.COMPUTE_ENGINE_CREDS:
+            _compute_engine_creds(stub, args)
+        elif self is TestCase.OAUTH2_AUTH_TOKEN:
+            _oauth2_auth_token(stub, args)
+        elif self is TestCase.JWT_TOKEN_CREDS:
+            _jwt_token_creds(stub, args)
+        elif self is TestCase.PER_RPC_CREDS:
+            _per_rpc_creds(stub, args)
+        else:
+            raise NotImplementedError('Test case "%s" not implemented!' %
+                                      self.name)
diff --git a/src/python/grpcio_tests/tests/interop/resources.py b/src/python/grpcio_tests/tests/interop/resources.py
index c424385cf6..2ec2eb92b4 100644
--- a/src/python/grpcio_tests/tests/interop/resources.py
+++ b/src/python/grpcio_tests/tests/interop/resources.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Constants and functions for data used in interoperability testing."""
 
 import argparse
@@ -40,22 +39,22 @@ _CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem'
 
 
 def test_root_certificates():
-  return pkg_resources.resource_string(
-      __name__, _ROOT_CERTIFICATES_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__,
+                                         _ROOT_CERTIFICATES_RESOURCE_PATH)
 
 
 def private_key():
-  return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH)
 
 
 def certificate_chain():
-  return pkg_resources.resource_string(
-      __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__,
+                                         _CERTIFICATE_CHAIN_RESOURCE_PATH)
 
 
 def parse_bool(value):
-  if value == 'true':
-    return True
-  if value == 'false':
-    return False
-  raise argparse.ArgumentTypeError('Only true/false allowed')
+    if value == 'true':
+        return True
+    if value == 'false':
+        return False
+    raise argparse.ArgumentTypeError('Only true/false allowed')
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index 1ae83bc57d..65f1604eb8 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -26,7 +26,6 @@
 # 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.
-
 """The Python implementation of the GRPC interoperability test server."""
 
 import argparse
@@ -44,34 +43,36 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
 
 
 def serve():
-  parser = argparse.ArgumentParser()
-  parser.add_argument(
-      '--port', help='the port on which to serve', type=int)
-  parser.add_argument(
-      '--use_tls', help='require a secure connection',
-      default=False, type=resources.parse_bool)
-  args = parser.parse_args()
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--port', help='the port on which to serve', type=int)
+    parser.add_argument(
+        '--use_tls',
+        help='require a secure connection',
+        default=False,
+        type=resources.parse_bool)
+    args = parser.parse_args()
+
+    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+    test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server)
+    if args.use_tls:
+        private_key = resources.private_key()
+        certificate_chain = resources.certificate_chain()
+        credentials = grpc.ssl_server_credentials((
+            (private_key, certificate_chain),))
+        server.add_secure_port('[::]:{}'.format(args.port), credentials)
+    else:
+        server.add_insecure_port('[::]:{}'.format(args.port))
 
-  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-  test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server)
-  if args.use_tls:
-    private_key = resources.private_key()
-    certificate_chain = resources.certificate_chain()
-    credentials = grpc.ssl_server_credentials(
-        ((private_key, certificate_chain),))
-    server.add_secure_port('[::]:{}'.format(args.port), credentials)
-  else:
-    server.add_insecure_port('[::]:{}'.format(args.port))
+    server.start()
+    logging.info('Server serving.')
+    try:
+        while True:
+            time.sleep(_ONE_DAY_IN_SECONDS)
+    except BaseException as e:
+        logging.info('Caught exception "%s"; stopping server...', e)
+        server.stop(None)
+        logging.info('Server stopped; exiting.')
 
-  server.start()
-  logging.info('Server serving.')
-  try:
-    while True:
-      time.sleep(_ONE_DAY_IN_SECONDS)
-  except BaseException as e:
-    logging.info('Caught exception "%s"; stopping server...', e)
-    server.stop(None)
-    logging.info('Server stopped; exiting.')
 
 if __name__ == '__main__':
-  serve()
+    serve()
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
index 7ca2bcff38..ae5da2c3db 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
@@ -58,436 +58,440 @@ ADD_SERVICER_TO_SERVER_IDENTIFIER = 'add_TestServiceServicer_to_server'
 
 class _ServicerMethods(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._paused = False
-    self._fail = False
-
-  @contextlib.contextmanager
-  def pause(self):  # pylint: disable=invalid-name
-    with self._condition:
-      self._paused = True
-    yield
-    with self._condition:
-      self._paused = False
-      self._condition.notify_all()
-
-  @contextlib.contextmanager
-  def fail(self):  # pylint: disable=invalid-name
-    with self._condition:
-      self._fail = True
-    yield
-    with self._condition:
-      self._fail = False
-
-  def _control(self):  # pylint: disable=invalid-name
-    with self._condition:
-      if self._fail:
-        raise ValueError()
-      while self._paused:
-        self._condition.wait()
-
-  def UnaryCall(self, request, unused_rpc_context):
-    response = response_pb2.SimpleResponse()
-    response.payload.payload_type = payload_pb2.COMPRESSABLE
-    response.payload.payload_compressable = 'a' * request.response_size
-    self._control()
-    return response
-
-  def StreamingOutputCall(self, request, unused_rpc_context):
-    for parameter in request.response_parameters:
-      response = response_pb2.StreamingOutputCallResponse()
-      response.payload.payload_type = payload_pb2.COMPRESSABLE
-      response.payload.payload_compressable = 'a' * parameter.size
-      self._control()
-      yield response
-
-  def StreamingInputCall(self, request_iter, unused_rpc_context):
-    response = response_pb2.StreamingInputCallResponse()
-    aggregated_payload_size = 0
-    for request in request_iter:
-      aggregated_payload_size += len(request.payload.payload_compressable)
-    response.aggregated_payload_size = aggregated_payload_size
-    self._control()
-    return response
-
-  def FullDuplexCall(self, request_iter, unused_rpc_context):
-    for request in request_iter:
-      for parameter in request.response_parameters:
-        response = response_pb2.StreamingOutputCallResponse()
-        response.payload.payload_type = payload_pb2.COMPRESSABLE
-        response.payload.payload_compressable = 'a' * parameter.size
-        self._control()
-        yield response
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._paused = False
+        self._fail = False
+
+    @contextlib.contextmanager
+    def pause(self):  # pylint: disable=invalid-name
+        with self._condition:
+            self._paused = True
+        yield
+        with self._condition:
+            self._paused = False
+            self._condition.notify_all()
 
-  def HalfDuplexCall(self, request_iter, unused_rpc_context):
-    responses = []
-    for request in request_iter:
-      for parameter in request.response_parameters:
-        response = response_pb2.StreamingOutputCallResponse()
+    @contextlib.contextmanager
+    def fail(self):  # pylint: disable=invalid-name
+        with self._condition:
+            self._fail = True
+        yield
+        with self._condition:
+            self._fail = False
+
+    def _control(self):  # pylint: disable=invalid-name
+        with self._condition:
+            if self._fail:
+                raise ValueError()
+            while self._paused:
+                self._condition.wait()
+
+    def UnaryCall(self, request, unused_rpc_context):
+        response = response_pb2.SimpleResponse()
         response.payload.payload_type = payload_pb2.COMPRESSABLE
-        response.payload.payload_compressable = 'a' * parameter.size
+        response.payload.payload_compressable = 'a' * request.response_size
+        self._control()
+        return response
+
+    def StreamingOutputCall(self, request, unused_rpc_context):
+        for parameter in request.response_parameters:
+            response = response_pb2.StreamingOutputCallResponse()
+            response.payload.payload_type = payload_pb2.COMPRESSABLE
+            response.payload.payload_compressable = 'a' * parameter.size
+            self._control()
+            yield response
+
+    def StreamingInputCall(self, request_iter, unused_rpc_context):
+        response = response_pb2.StreamingInputCallResponse()
+        aggregated_payload_size = 0
+        for request in request_iter:
+            aggregated_payload_size += len(request.payload.payload_compressable)
+        response.aggregated_payload_size = aggregated_payload_size
         self._control()
-        responses.append(response)
-    for response in responses:
-      yield response
+        return response
+
+    def FullDuplexCall(self, request_iter, unused_rpc_context):
+        for request in request_iter:
+            for parameter in request.response_parameters:
+                response = response_pb2.StreamingOutputCallResponse()
+                response.payload.payload_type = payload_pb2.COMPRESSABLE
+                response.payload.payload_compressable = 'a' * parameter.size
+                self._control()
+                yield response
+
+    def HalfDuplexCall(self, request_iter, unused_rpc_context):
+        responses = []
+        for request in request_iter:
+            for parameter in request.response_parameters:
+                response = response_pb2.StreamingOutputCallResponse()
+                response.payload.payload_type = payload_pb2.COMPRESSABLE
+                response.payload.payload_compressable = 'a' * parameter.size
+                self._control()
+                responses.append(response)
+        for response in responses:
+            yield response
 
 
 class _Service(
-    collections.namedtuple(
-      '_Service', ('servicer_methods', 'server', 'stub',))):
-  """A live and running service.
+        collections.namedtuple('_Service', (
+            'servicer_methods',
+            'server',
+            'stub',))):
+    """A live and running service.
 
   Attributes:
     servicer_methods: The _ServicerMethods servicing RPCs.
     server: The grpc.Server servicing RPCs.
     stub: A stub on which to invoke RPCs.
   """
-      
+
 
 def _CreateService():
-  """Provides a servicer backend and a stub.
+    """Provides a servicer backend and a stub.
 
   Returns:
     A _Service with which to test RPCs.
   """
-  servicer_methods = _ServicerMethods()
+    servicer_methods = _ServicerMethods()
 
-  class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
+    class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
 
-    def UnaryCall(self, request, context):
-      return servicer_methods.UnaryCall(request, context)
+        def UnaryCall(self, request, context):
+            return servicer_methods.UnaryCall(request, context)
 
-    def StreamingOutputCall(self, request, context):
-      return servicer_methods.StreamingOutputCall(request, context)
+        def StreamingOutputCall(self, request, context):
+            return servicer_methods.StreamingOutputCall(request, context)
 
-    def StreamingInputCall(self, request_iter, context):
-      return servicer_methods.StreamingInputCall(request_iter, context)
+        def StreamingInputCall(self, request_iter, context):
+            return servicer_methods.StreamingInputCall(request_iter, context)
 
-    def FullDuplexCall(self, request_iter, context):
-      return servicer_methods.FullDuplexCall(request_iter, context)
+        def FullDuplexCall(self, request_iter, context):
+            return servicer_methods.FullDuplexCall(request_iter, context)
 
-    def HalfDuplexCall(self, request_iter, context):
-      return servicer_methods.HalfDuplexCall(request_iter, context)
+        def HalfDuplexCall(self, request_iter, context):
+            return servicer_methods.HalfDuplexCall(request_iter, context)
 
-  server = grpc.server(
-      futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
-  getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
-  port = server.add_insecure_port('[::]:0')
-  server.start()
-  channel = grpc.insecure_channel('localhost:{}'.format(port))
-  stub = getattr(service_pb2, STUB_IDENTIFIER)(channel)
-  return _Service(servicer_methods, server, stub)
+    server = grpc.server(
+        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+    getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = grpc.insecure_channel('localhost:{}'.format(port))
+    stub = getattr(service_pb2, STUB_IDENTIFIER)(channel)
+    return _Service(servicer_methods, server, stub)
 
 
 def _CreateIncompleteService():
-  """Provides a servicer backend that fails to implement methods and its stub.
+    """Provides a servicer backend that fails to implement methods and its stub.
 
   Returns:
     A _Service with which to test RPCs. The returned _Service's
       servicer_methods implements none of the methods required of it.
   """
 
-  class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
-    pass
+    class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
+        pass
 
-  server = grpc.server(
-      futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
-  getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
-  port = server.add_insecure_port('[::]:0')
-  server.start()
-  channel = grpc.insecure_channel('localhost:{}'.format(port))
-  stub = getattr(service_pb2, STUB_IDENTIFIER)(channel)
-  return _Service(None, server, stub)
+    server = grpc.server(
+        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+    getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = grpc.insecure_channel('localhost:{}'.format(port))
+    stub = getattr(service_pb2, STUB_IDENTIFIER)(channel)
+    return _Service(None, server, stub)
 
 
 def _streaming_input_request_iterator():
-  for _ in range(3):
-    request = request_pb2.StreamingInputCallRequest()
-    request.payload.payload_type = payload_pb2.COMPRESSABLE
-    request.payload.payload_compressable = 'a'
-    yield request
+    for _ in range(3):
+        request = request_pb2.StreamingInputCallRequest()
+        request.payload.payload_type = payload_pb2.COMPRESSABLE
+        request.payload.payload_compressable = 'a'
+        yield request
 
 
 def _streaming_output_request():
-  request = request_pb2.StreamingOutputCallRequest()
-  sizes = [1, 2, 3]
-  request.response_parameters.add(size=sizes[0], interval_us=0)
-  request.response_parameters.add(size=sizes[1], interval_us=0)
-  request.response_parameters.add(size=sizes[2], interval_us=0)
-  return request
+    request = request_pb2.StreamingOutputCallRequest()
+    sizes = [1, 2, 3]
+    request.response_parameters.add(size=sizes[0], interval_us=0)
+    request.response_parameters.add(size=sizes[1], interval_us=0)
+    request.response_parameters.add(size=sizes[2], interval_us=0)
+    return request
 
 
 def _full_duplex_request_iterator():
-  request = request_pb2.StreamingOutputCallRequest()
-  request.response_parameters.add(size=1, interval_us=0)
-  yield request
-  request = request_pb2.StreamingOutputCallRequest()
-  request.response_parameters.add(size=2, interval_us=0)
-  request.response_parameters.add(size=3, interval_us=0)
-  yield request
+    request = request_pb2.StreamingOutputCallRequest()
+    request.response_parameters.add(size=1, interval_us=0)
+    yield request
+    request = request_pb2.StreamingOutputCallRequest()
+    request.response_parameters.add(size=2, interval_us=0)
+    request.response_parameters.add(size=3, interval_us=0)
+    yield request
 
 
 class PythonPluginTest(unittest.TestCase):
-  """Test case for the gRPC Python protoc-plugin.
+    """Test case for the gRPC Python protoc-plugin.
 
   While reading these tests, remember that the futures API
   (`stub.method.future()`) only gives futures for the *response-unary*
   methods and does not exist for response-streaming methods.
   """
 
-  def testImportAttributes(self):
-    # check that we can access the generated module and its members.
-    self.assertIsNotNone(
-        getattr(service_pb2, STUB_IDENTIFIER, None))
-    self.assertIsNotNone(
-        getattr(service_pb2, SERVICER_IDENTIFIER, None))
-    self.assertIsNotNone(
-        getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER, None))
-
-  def testUpDown(self):
-    service = _CreateService()
-    self.assertIsNotNone(service.servicer_methods)
-    self.assertIsNotNone(service.server)
-    self.assertIsNotNone(service.stub)
-
-  def testIncompleteServicer(self):
-    service = _CreateIncompleteService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      service.stub.UnaryCall(request)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.UNIMPLEMENTED)
-
-  def testUnaryCall(self):
-    service = _CreateService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    response = service.stub.UnaryCall(request)
-    expected_response = service.servicer_methods.UnaryCall(
-        request, 'not a real context!')
-    self.assertEqual(expected_response, response)
-
-  def testUnaryCallFuture(self):
-    service = _CreateService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    # Check that the call does not block waiting for the server to respond.
-    with service.servicer_methods.pause():
-      response_future = service.stub.UnaryCall.future(request)
-    response = response_future.result()
-    expected_response = service.servicer_methods.UnaryCall(
-        request, 'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testUnaryCallFutureExpired(self):
-    service = _CreateService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    with service.servicer_methods.pause():
-      response_future = service.stub.UnaryCall.future(
-          request, timeout=test_constants.SHORT_TIMEOUT)
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        response_future.result()
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-    self.assertIs(response_future.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-
-  def testUnaryCallFutureCancelled(self):
-    service = _CreateService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    with service.servicer_methods.pause():
-      response_future = service.stub.UnaryCall.future(request)
-      response_future.cancel()
-    self.assertTrue(response_future.cancelled())
-    self.assertIs(response_future.code(), grpc.StatusCode.CANCELLED)
-
-  def testUnaryCallFutureFailed(self):
-    service = _CreateService()
-    request = request_pb2.SimpleRequest(response_size=13)
-    with service.servicer_methods.fail():
-      response_future = service.stub.UnaryCall.future(request)
-      self.assertIsNotNone(response_future.exception())
-    self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
-
-  def testStreamingOutputCall(self):
-    service = _CreateService()
-    request = _streaming_output_request()
-    responses = service.stub.StreamingOutputCall(request)
-    expected_responses = service.servicer_methods.StreamingOutputCall(
-        request, 'not a real RpcContext!')
-    for expected_response, response in moves.zip_longest(
-        expected_responses, responses):
-      self.assertEqual(expected_response, response)
-
-  def testStreamingOutputCallExpired(self):
-    service = _CreateService()
-    request = _streaming_output_request()
-    with service.servicer_methods.pause():
-      responses = service.stub.StreamingOutputCall(
-          request, timeout=test_constants.SHORT_TIMEOUT)
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        list(responses)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-
-  def testStreamingOutputCallCancelled(self):
-    service = _CreateService()
-    request = _streaming_output_request()
-    responses = service.stub.StreamingOutputCall(request)
-    next(responses)
-    responses.cancel()
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      next(responses)
-    self.assertIs(responses.code(), grpc.StatusCode.CANCELLED)
-
-  def testStreamingOutputCallFailed(self):
-    service = _CreateService()
-    request = _streaming_output_request()
-    with service.servicer_methods.fail():
-      responses = service.stub.StreamingOutputCall(request)
-      self.assertIsNotNone(responses)
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        next(responses)
-    self.assertIs(exception_context.exception.code(), grpc.StatusCode.UNKNOWN)
-
-  def testStreamingInputCall(self):
-    service = _CreateService()
-    response = service.stub.StreamingInputCall(
-        _streaming_input_request_iterator())
-    expected_response = service.servicer_methods.StreamingInputCall(
-        _streaming_input_request_iterator(),
-        'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testStreamingInputCallFuture(self):
-    service = _CreateService()
-    with service.servicer_methods.pause():
-      response_future = service.stub.StreamingInputCall.future(
-          _streaming_input_request_iterator())
-    response = response_future.result()
-    expected_response = service.servicer_methods.StreamingInputCall(
-        _streaming_input_request_iterator(),
-        'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testStreamingInputCallFutureExpired(self):
-    service = _CreateService()
-    with service.servicer_methods.pause():
-      response_future = service.stub.StreamingInputCall.future(
-          _streaming_input_request_iterator(),
-          timeout=test_constants.SHORT_TIMEOUT)
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        response_future.result()
-    self.assertIsInstance(response_future.exception(), grpc.RpcError)
-    self.assertIs(
-        response_future.exception().code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-
-  def testStreamingInputCallFutureCancelled(self):
-    service = _CreateService()
-    with service.servicer_methods.pause():
-      response_future = service.stub.StreamingInputCall.future(
-          _streaming_input_request_iterator())
-      response_future.cancel()
-    self.assertTrue(response_future.cancelled())
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.result()
-
-  def testStreamingInputCallFutureFailed(self):
-    service = _CreateService()
-    with service.servicer_methods.fail():
-      response_future = service.stub.StreamingInputCall.future(
-          _streaming_input_request_iterator())
-      self.assertIsNotNone(response_future.exception())
-      self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
-
-  def testFullDuplexCall(self):
-    service = _CreateService()
-    responses = service.stub.FullDuplexCall(
-        _full_duplex_request_iterator())
-    expected_responses = service.servicer_methods.FullDuplexCall(
-        _full_duplex_request_iterator(),
-        'not a real RpcContext!')
-    for expected_response, response in moves.zip_longest(
-        expected_responses, responses):
-      self.assertEqual(expected_response, response)
-
-  def testFullDuplexCallExpired(self):
-    request_iterator = _full_duplex_request_iterator()
-    service = _CreateService()
-    with service.servicer_methods.pause():
-      responses = service.stub.FullDuplexCall(
-          request_iterator, timeout=test_constants.SHORT_TIMEOUT)
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        list(responses)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
-
-  def testFullDuplexCallCancelled(self):
-    service = _CreateService()
-    request_iterator = _full_duplex_request_iterator()
-    responses = service.stub.FullDuplexCall(request_iterator)
-    next(responses)
-    responses.cancel()
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      next(responses)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.CANCELLED)
-
-  def testFullDuplexCallFailed(self):
-    request_iterator = _full_duplex_request_iterator()
-    service = _CreateService()
-    with service.servicer_methods.fail():
-      responses = service.stub.FullDuplexCall(request_iterator)
-      with self.assertRaises(grpc.RpcError) as exception_context:
+    def testImportAttributes(self):
+        # check that we can access the generated module and its members.
+        self.assertIsNotNone(getattr(service_pb2, STUB_IDENTIFIER, None))
+        self.assertIsNotNone(getattr(service_pb2, SERVICER_IDENTIFIER, None))
+        self.assertIsNotNone(
+            getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER, None))
+
+    def testUpDown(self):
+        service = _CreateService()
+        self.assertIsNotNone(service.servicer_methods)
+        self.assertIsNotNone(service.server)
+        self.assertIsNotNone(service.stub)
+
+    def testIncompleteServicer(self):
+        service = _CreateIncompleteService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            service.stub.UnaryCall(request)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.UNIMPLEMENTED)
+
+    def testUnaryCall(self):
+        service = _CreateService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        response = service.stub.UnaryCall(request)
+        expected_response = service.servicer_methods.UnaryCall(
+            request, 'not a real context!')
+        self.assertEqual(expected_response, response)
+
+    def testUnaryCallFuture(self):
+        service = _CreateService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        # Check that the call does not block waiting for the server to respond.
+        with service.servicer_methods.pause():
+            response_future = service.stub.UnaryCall.future(request)
+        response = response_future.result()
+        expected_response = service.servicer_methods.UnaryCall(
+            request, 'not a real RpcContext!')
+        self.assertEqual(expected_response, response)
+
+    def testUnaryCallFutureExpired(self):
+        service = _CreateService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        with service.servicer_methods.pause():
+            response_future = service.stub.UnaryCall.future(
+                request, timeout=test_constants.SHORT_TIMEOUT)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                response_future.result()
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
+        self.assertIs(response_future.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
+
+    def testUnaryCallFutureCancelled(self):
+        service = _CreateService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        with service.servicer_methods.pause():
+            response_future = service.stub.UnaryCall.future(request)
+            response_future.cancel()
+        self.assertTrue(response_future.cancelled())
+        self.assertIs(response_future.code(), grpc.StatusCode.CANCELLED)
+
+    def testUnaryCallFutureFailed(self):
+        service = _CreateService()
+        request = request_pb2.SimpleRequest(response_size=13)
+        with service.servicer_methods.fail():
+            response_future = service.stub.UnaryCall.future(request)
+            self.assertIsNotNone(response_future.exception())
+        self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
+
+    def testStreamingOutputCall(self):
+        service = _CreateService()
+        request = _streaming_output_request()
+        responses = service.stub.StreamingOutputCall(request)
+        expected_responses = service.servicer_methods.StreamingOutputCall(
+            request, 'not a real RpcContext!')
+        for expected_response, response in moves.zip_longest(expected_responses,
+                                                             responses):
+            self.assertEqual(expected_response, response)
+
+    def testStreamingOutputCallExpired(self):
+        service = _CreateService()
+        request = _streaming_output_request()
+        with service.servicer_methods.pause():
+            responses = service.stub.StreamingOutputCall(
+                request, timeout=test_constants.SHORT_TIMEOUT)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                list(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
+
+    def testStreamingOutputCallCancelled(self):
+        service = _CreateService()
+        request = _streaming_output_request()
+        responses = service.stub.StreamingOutputCall(request)
         next(responses)
-    self.assertIs(exception_context.exception.code(), grpc.StatusCode.UNKNOWN)
-
-  def testHalfDuplexCall(self):
-    service = _CreateService()
-    def half_duplex_request_iterator():
-      request = request_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=1, interval_us=0)
-      yield request
-      request = request_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=2, interval_us=0)
-      request.response_parameters.add(size=3, interval_us=0)
-      yield request
-    responses = service.stub.HalfDuplexCall(half_duplex_request_iterator())
-    expected_responses = service.servicer_methods.HalfDuplexCall(
-        half_duplex_request_iterator(), 'not a real RpcContext!')
-    for expected_response, response in moves.zip_longest(
-        expected_responses, responses):
-      self.assertEqual(expected_response, response)
-
-  def testHalfDuplexCallWedged(self):
-    condition = threading.Condition()
-    wait_cell = [False]
-    @contextlib.contextmanager
-    def wait():  # pylint: disable=invalid-name
-      # Where's Python 3's 'nonlocal' statement when you need it?
-      with condition:
-        wait_cell[0] = True
-      yield
-      with condition:
-        wait_cell[0] = False
-        condition.notify_all()
-    def half_duplex_request_iterator():
-      request = request_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=1, interval_us=0)
-      yield request
-      with condition:
-        while wait_cell[0]:
-          condition.wait()
-    service = _CreateService()
-    with wait():
-      responses = service.stub.HalfDuplexCall(
-          half_duplex_request_iterator(), timeout=test_constants.SHORT_TIMEOUT)
-      # half-duplex waits for the client to send all info
-      with self.assertRaises(grpc.RpcError) as exception_context:
+        responses.cancel()
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(responses)
+        self.assertIs(responses.code(), grpc.StatusCode.CANCELLED)
+
+    def testStreamingOutputCallFailed(self):
+        service = _CreateService()
+        request = _streaming_output_request()
+        with service.servicer_methods.fail():
+            responses = service.stub.StreamingOutputCall(request)
+            self.assertIsNotNone(responses)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                next(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.UNKNOWN)
+
+    def testStreamingInputCall(self):
+        service = _CreateService()
+        response = service.stub.StreamingInputCall(
+            _streaming_input_request_iterator())
+        expected_response = service.servicer_methods.StreamingInputCall(
+            _streaming_input_request_iterator(), 'not a real RpcContext!')
+        self.assertEqual(expected_response, response)
+
+    def testStreamingInputCallFuture(self):
+        service = _CreateService()
+        with service.servicer_methods.pause():
+            response_future = service.stub.StreamingInputCall.future(
+                _streaming_input_request_iterator())
+        response = response_future.result()
+        expected_response = service.servicer_methods.StreamingInputCall(
+            _streaming_input_request_iterator(), 'not a real RpcContext!')
+        self.assertEqual(expected_response, response)
+
+    def testStreamingInputCallFutureExpired(self):
+        service = _CreateService()
+        with service.servicer_methods.pause():
+            response_future = service.stub.StreamingInputCall.future(
+                _streaming_input_request_iterator(),
+                timeout=test_constants.SHORT_TIMEOUT)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                response_future.result()
+        self.assertIsInstance(response_future.exception(), grpc.RpcError)
+        self.assertIs(response_future.exception().code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
+
+    def testStreamingInputCallFutureCancelled(self):
+        service = _CreateService()
+        with service.servicer_methods.pause():
+            response_future = service.stub.StreamingInputCall.future(
+                _streaming_input_request_iterator())
+            response_future.cancel()
+        self.assertTrue(response_future.cancelled())
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.result()
+
+    def testStreamingInputCallFutureFailed(self):
+        service = _CreateService()
+        with service.servicer_methods.fail():
+            response_future = service.stub.StreamingInputCall.future(
+                _streaming_input_request_iterator())
+            self.assertIsNotNone(response_future.exception())
+            self.assertIs(response_future.code(), grpc.StatusCode.UNKNOWN)
+
+    def testFullDuplexCall(self):
+        service = _CreateService()
+        responses = service.stub.FullDuplexCall(_full_duplex_request_iterator())
+        expected_responses = service.servicer_methods.FullDuplexCall(
+            _full_duplex_request_iterator(), 'not a real RpcContext!')
+        for expected_response, response in moves.zip_longest(expected_responses,
+                                                             responses):
+            self.assertEqual(expected_response, response)
+
+    def testFullDuplexCallExpired(self):
+        request_iterator = _full_duplex_request_iterator()
+        service = _CreateService()
+        with service.servicer_methods.pause():
+            responses = service.stub.FullDuplexCall(
+                request_iterator, timeout=test_constants.SHORT_TIMEOUT)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                list(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
+
+    def testFullDuplexCallCancelled(self):
+        service = _CreateService()
+        request_iterator = _full_duplex_request_iterator()
+        responses = service.stub.FullDuplexCall(request_iterator)
         next(responses)
-    self.assertIs(
-        exception_context.exception.code(), grpc.StatusCode.DEADLINE_EXCEEDED)
+        responses.cancel()
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.CANCELLED)
+
+    def testFullDuplexCallFailed(self):
+        request_iterator = _full_duplex_request_iterator()
+        service = _CreateService()
+        with service.servicer_methods.fail():
+            responses = service.stub.FullDuplexCall(request_iterator)
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                next(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.UNKNOWN)
+
+    def testHalfDuplexCall(self):
+        service = _CreateService()
+
+        def half_duplex_request_iterator():
+            request = request_pb2.StreamingOutputCallRequest()
+            request.response_parameters.add(size=1, interval_us=0)
+            yield request
+            request = request_pb2.StreamingOutputCallRequest()
+            request.response_parameters.add(size=2, interval_us=0)
+            request.response_parameters.add(size=3, interval_us=0)
+            yield request
+
+        responses = service.stub.HalfDuplexCall(half_duplex_request_iterator())
+        expected_responses = service.servicer_methods.HalfDuplexCall(
+            half_duplex_request_iterator(), 'not a real RpcContext!')
+        for expected_response, response in moves.zip_longest(expected_responses,
+                                                             responses):
+            self.assertEqual(expected_response, response)
+
+    def testHalfDuplexCallWedged(self):
+        condition = threading.Condition()
+        wait_cell = [False]
+
+        @contextlib.contextmanager
+        def wait():  # pylint: disable=invalid-name
+            # Where's Python 3's 'nonlocal' statement when you need it?
+            with condition:
+                wait_cell[0] = True
+            yield
+            with condition:
+                wait_cell[0] = False
+                condition.notify_all()
+
+        def half_duplex_request_iterator():
+            request = request_pb2.StreamingOutputCallRequest()
+            request.response_parameters.add(size=1, interval_us=0)
+            yield request
+            with condition:
+                while wait_cell[0]:
+                    condition.wait()
+
+        service = _CreateService()
+        with wait():
+            responses = service.stub.HalfDuplexCall(
+                half_duplex_request_iterator(),
+                timeout=test_constants.SHORT_TIMEOUT)
+            # half-duplex waits for the client to send all info
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                next(responses)
+        self.assertIs(exception_context.exception.code(),
+                      grpc.StatusCode.DEADLINE_EXCEEDED)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
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 f8ae05bb7a..bcc01f3978 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
@@ -49,256 +49,264 @@ from tests.unit.framework.common import test_constants
 
 _MESSAGES_IMPORT = b'import "messages.proto";'
 
+
 @contextlib.contextmanager
 def _system_path(path):
-  old_system_path = sys.path[:]
-  sys.path = sys.path[0:1] + path + sys.path[1:]
-  yield
-  sys.path = old_system_path
+    old_system_path = sys.path[:]
+    sys.path = sys.path[0:1] + path + sys.path[1:]
+    yield
+    sys.path = old_system_path
 
 
 class DummySplitServicer(object):
 
-  def __init__(self, request_class, response_class):
-    self.request_class = request_class
-    self.response_class = response_class
+    def __init__(self, request_class, response_class):
+        self.request_class = request_class
+        self.response_class = response_class
 
-  def Call(self, request, context):
-    return self.response_class()
+    def Call(self, request, context):
+        return self.response_class()
 
 
 class SeparateTestMixin(object):
 
-  def testImportAttributes(self):
-    with _system_path([self.python_out_directory]):
-      pb2 = importlib.import_module(self.pb2_import)
-    pb2.Request
-    pb2.Response
-    if self.should_find_services_in_pb2:
-      pb2.TestServiceServicer
-    else:
-      with self.assertRaises(AttributeError):
-        pb2.TestServiceServicer
-
-    with _system_path([self.grpc_python_out_directory]):
-      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
-    pb2_grpc.TestServiceServicer
-    with self.assertRaises(AttributeError):
-      pb2_grpc.Request
-    with self.assertRaises(AttributeError):
-      pb2_grpc.Response
-
-  def testCall(self):
-    with _system_path([self.python_out_directory]):
-      pb2 = importlib.import_module(self.pb2_import)
-    with _system_path([self.grpc_python_out_directory]):
-      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
-    server = grpc.server(
-        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
-    pb2_grpc.add_TestServiceServicer_to_server(
-        DummySplitServicer(
-            pb2.Request, pb2.Response), server)
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    stub = pb2_grpc.TestServiceStub(channel)
-    request = pb2.Request()
-    expected_response = pb2.Response()
-    response = stub.Call(request)
-    self.assertEqual(expected_response, response)
+    def testImportAttributes(self):
+        with _system_path([self.python_out_directory]):
+            pb2 = importlib.import_module(self.pb2_import)
+        pb2.Request
+        pb2.Response
+        if self.should_find_services_in_pb2:
+            pb2.TestServiceServicer
+        else:
+            with self.assertRaises(AttributeError):
+                pb2.TestServiceServicer
+
+        with _system_path([self.grpc_python_out_directory]):
+            pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+        pb2_grpc.TestServiceServicer
+        with self.assertRaises(AttributeError):
+            pb2_grpc.Request
+        with self.assertRaises(AttributeError):
+            pb2_grpc.Response
+
+    def testCall(self):
+        with _system_path([self.python_out_directory]):
+            pb2 = importlib.import_module(self.pb2_import)
+        with _system_path([self.grpc_python_out_directory]):
+            pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+        server = grpc.server(
+            futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+        pb2_grpc.add_TestServiceServicer_to_server(
+            DummySplitServicer(pb2.Request, pb2.Response), server)
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        stub = pb2_grpc.TestServiceStub(channel)
+        request = pb2.Request()
+        expected_response = pb2.Response()
+        response = stub.Call(request)
+        self.assertEqual(expected_response, response)
 
 
 class CommonTestMixin(object):
 
-  def testImportAttributes(self):
-    with _system_path([self.python_out_directory]):
-      pb2 = importlib.import_module(self.pb2_import)
-    pb2.Request
-    pb2.Response
-    if self.should_find_services_in_pb2:
-      pb2.TestServiceServicer
-    else:
-      with self.assertRaises(AttributeError):
-        pb2.TestServiceServicer
-
-    with _system_path([self.grpc_python_out_directory]):
-      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
-    pb2_grpc.TestServiceServicer
-    with self.assertRaises(AttributeError):
-      pb2_grpc.Request
-    with self.assertRaises(AttributeError):
-      pb2_grpc.Response
-
-  def testCall(self):
-    with _system_path([self.python_out_directory]):
-      pb2 = importlib.import_module(self.pb2_import)
-    with _system_path([self.grpc_python_out_directory]):
-      pb2_grpc = importlib.import_module(self.pb2_grpc_import)
-    server = grpc.server(
-        futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
-    pb2_grpc.add_TestServiceServicer_to_server(
-        DummySplitServicer(
-            pb2.Request, pb2.Response), server)
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    stub = pb2_grpc.TestServiceStub(channel)
-    request = pb2.Request()
-    expected_response = pb2.Response()
-    response = stub.Call(request)
-    self.assertEqual(expected_response, response)
+    def testImportAttributes(self):
+        with _system_path([self.python_out_directory]):
+            pb2 = importlib.import_module(self.pb2_import)
+        pb2.Request
+        pb2.Response
+        if self.should_find_services_in_pb2:
+            pb2.TestServiceServicer
+        else:
+            with self.assertRaises(AttributeError):
+                pb2.TestServiceServicer
+
+        with _system_path([self.grpc_python_out_directory]):
+            pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+        pb2_grpc.TestServiceServicer
+        with self.assertRaises(AttributeError):
+            pb2_grpc.Request
+        with self.assertRaises(AttributeError):
+            pb2_grpc.Response
+
+    def testCall(self):
+        with _system_path([self.python_out_directory]):
+            pb2 = importlib.import_module(self.pb2_import)
+        with _system_path([self.grpc_python_out_directory]):
+            pb2_grpc = importlib.import_module(self.pb2_grpc_import)
+        server = grpc.server(
+            futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+        pb2_grpc.add_TestServiceServicer_to_server(
+            DummySplitServicer(pb2.Request, pb2.Response), server)
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        stub = pb2_grpc.TestServiceStub(channel)
+        request = pb2.Request()
+        expected_response = pb2.Response()
+        response = stub.Call(request)
+        self.assertEqual(expected_response, response)
 
 
 class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
 
-  def setUp(self):
-    same_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
-    self.directory = tempfile.mkdtemp(suffix='same_separate', dir='.')
-    self.proto_directory = os.path.join(self.directory, 'proto_path')
-    self.python_out_directory = os.path.join(self.directory, 'python_out')
-    self.grpc_python_out_directory = os.path.join(self.directory, 'grpc_python_out')
-    os.makedirs(self.proto_directory)
-    os.makedirs(self.python_out_directory)
-    os.makedirs(self.grpc_python_out_directory)
-    same_proto_file = os.path.join(self.proto_directory, 'same_separate.proto')
-    open(same_proto_file, 'wb').write(same_proto_contents)
-    protoc_result = protoc.main([
-        '',
-        '--proto_path={}'.format(self.proto_directory),
-        '--python_out={}'.format(self.python_out_directory),
-        '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
-        same_proto_file,
-    ])
-    if protoc_result != 0:
-      raise Exception("unexpected protoc error")
-    open(os.path.join(self.grpc_python_out_directory, '__init__.py'), 'w').write('')
-    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
-    self.pb2_import = 'same_separate_pb2'
-    self.pb2_grpc_import = 'same_separate_pb2_grpc'
-    self.should_find_services_in_pb2 = False
-
-  def tearDown(self):
-    shutil.rmtree(self.directory)
+    def setUp(self):
+        same_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
+        self.directory = tempfile.mkdtemp(suffix='same_separate', dir='.')
+        self.proto_directory = os.path.join(self.directory, 'proto_path')
+        self.python_out_directory = os.path.join(self.directory, 'python_out')
+        self.grpc_python_out_directory = os.path.join(self.directory,
+                                                      'grpc_python_out')
+        os.makedirs(self.proto_directory)
+        os.makedirs(self.python_out_directory)
+        os.makedirs(self.grpc_python_out_directory)
+        same_proto_file = os.path.join(self.proto_directory,
+                                       'same_separate.proto')
+        open(same_proto_file, 'wb').write(same_proto_contents)
+        protoc_result = protoc.main([
+            '',
+            '--proto_path={}'.format(self.proto_directory),
+            '--python_out={}'.format(self.python_out_directory),
+            '--grpc_python_out=grpc_2_0:{}'.format(
+                self.grpc_python_out_directory),
+            same_proto_file,
+        ])
+        if protoc_result != 0:
+            raise Exception("unexpected protoc error")
+        open(os.path.join(self.grpc_python_out_directory, '__init__.py'),
+             'w').write('')
+        open(os.path.join(self.python_out_directory, '__init__.py'),
+             'w').write('')
+        self.pb2_import = 'same_separate_pb2'
+        self.pb2_grpc_import = 'same_separate_pb2_grpc'
+        self.should_find_services_in_pb2 = False
+
+    def tearDown(self):
+        shutil.rmtree(self.directory)
 
 
 class SameCommonTest(unittest.TestCase, CommonTestMixin):
 
-  def setUp(self):
-    same_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
-    self.directory = tempfile.mkdtemp(suffix='same_common', dir='.')
-    self.proto_directory = os.path.join(self.directory, 'proto_path')
-    self.python_out_directory = os.path.join(self.directory, 'python_out')
-    self.grpc_python_out_directory = self.python_out_directory
-    os.makedirs(self.proto_directory)
-    os.makedirs(self.python_out_directory)
-    same_proto_file = os.path.join(self.proto_directory, 'same_common.proto')
-    open(same_proto_file, 'wb').write(same_proto_contents)
-    protoc_result = protoc.main([
-        '',
-        '--proto_path={}'.format(self.proto_directory),
-        '--python_out={}'.format(self.python_out_directory),
-        '--grpc_python_out={}'.format(self.grpc_python_out_directory),
-        same_proto_file,
-    ])
-    if protoc_result != 0:
-      raise Exception("unexpected protoc error")
-    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
-    self.pb2_import = 'same_common_pb2'
-    self.pb2_grpc_import = 'same_common_pb2_grpc'
-    self.should_find_services_in_pb2 = True
-
-  def tearDown(self):
-    shutil.rmtree(self.directory)
+    def setUp(self):
+        same_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing', 'same.proto')
+        self.directory = tempfile.mkdtemp(suffix='same_common', dir='.')
+        self.proto_directory = os.path.join(self.directory, 'proto_path')
+        self.python_out_directory = os.path.join(self.directory, 'python_out')
+        self.grpc_python_out_directory = self.python_out_directory
+        os.makedirs(self.proto_directory)
+        os.makedirs(self.python_out_directory)
+        same_proto_file = os.path.join(self.proto_directory,
+                                       'same_common.proto')
+        open(same_proto_file, 'wb').write(same_proto_contents)
+        protoc_result = protoc.main([
+            '',
+            '--proto_path={}'.format(self.proto_directory),
+            '--python_out={}'.format(self.python_out_directory),
+            '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+            same_proto_file,
+        ])
+        if protoc_result != 0:
+            raise Exception("unexpected protoc error")
+        open(os.path.join(self.python_out_directory, '__init__.py'),
+             'w').write('')
+        self.pb2_import = 'same_common_pb2'
+        self.pb2_grpc_import = 'same_common_pb2_grpc'
+        self.should_find_services_in_pb2 = True
+
+    def tearDown(self):
+        shutil.rmtree(self.directory)
 
 
 class SplitCommonTest(unittest.TestCase, CommonTestMixin):
 
-  def setUp(self):
-    services_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing.split_services',
-        'services.proto')
-    messages_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing.split_messages',
-        'messages.proto')
-    self.directory = tempfile.mkdtemp(suffix='split_common', dir='.')
-    self.proto_directory = os.path.join(self.directory, 'proto_path')
-    self.python_out_directory = os.path.join(self.directory, 'python_out')
-    self.grpc_python_out_directory = self.python_out_directory
-    os.makedirs(self.proto_directory)
-    os.makedirs(self.python_out_directory)
-    services_proto_file = os.path.join(self.proto_directory,
-                                       'split_common_services.proto')
-    messages_proto_file = os.path.join(self.proto_directory,
-                                       'split_common_messages.proto')
-    open(services_proto_file, 'wb').write(services_proto_contents.replace(
-        _MESSAGES_IMPORT,
-        b'import "split_common_messages.proto";'
-    ))
-    open(messages_proto_file, 'wb').write(messages_proto_contents)
-    protoc_result = protoc.main([
-        '',
-        '--proto_path={}'.format(self.proto_directory),
-        '--python_out={}'.format(self.python_out_directory),
-        '--grpc_python_out={}'.format(self.grpc_python_out_directory),
-        services_proto_file,
-        messages_proto_file,
-    ])
-    if protoc_result != 0:
-      raise Exception("unexpected protoc error")
-    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
-    self.pb2_import = 'split_common_messages_pb2'
-    self.pb2_grpc_import = 'split_common_services_pb2_grpc'
-    self.should_find_services_in_pb2 = False
-
-  def tearDown(self):
-    shutil.rmtree(self.directory)
+    def setUp(self):
+        services_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing.split_services',
+            'services.proto')
+        messages_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing.split_messages',
+            'messages.proto')
+        self.directory = tempfile.mkdtemp(suffix='split_common', dir='.')
+        self.proto_directory = os.path.join(self.directory, 'proto_path')
+        self.python_out_directory = os.path.join(self.directory, 'python_out')
+        self.grpc_python_out_directory = self.python_out_directory
+        os.makedirs(self.proto_directory)
+        os.makedirs(self.python_out_directory)
+        services_proto_file = os.path.join(self.proto_directory,
+                                           'split_common_services.proto')
+        messages_proto_file = os.path.join(self.proto_directory,
+                                           'split_common_messages.proto')
+        open(services_proto_file, 'wb').write(
+            services_proto_contents.replace(
+                _MESSAGES_IMPORT, b'import "split_common_messages.proto";'))
+        open(messages_proto_file, 'wb').write(messages_proto_contents)
+        protoc_result = protoc.main([
+            '',
+            '--proto_path={}'.format(self.proto_directory),
+            '--python_out={}'.format(self.python_out_directory),
+            '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+            services_proto_file,
+            messages_proto_file,
+        ])
+        if protoc_result != 0:
+            raise Exception("unexpected protoc error")
+        open(os.path.join(self.python_out_directory, '__init__.py'),
+             'w').write('')
+        self.pb2_import = 'split_common_messages_pb2'
+        self.pb2_grpc_import = 'split_common_services_pb2_grpc'
+        self.should_find_services_in_pb2 = False
+
+    def tearDown(self):
+        shutil.rmtree(self.directory)
 
 
 class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
 
-  def setUp(self):
-    services_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing.split_services',
-        'services.proto')
-    messages_proto_contents = pkgutil.get_data(
-        'tests.protoc_plugin.protos.invocation_testing.split_messages',
-        'messages.proto')
-    self.directory = tempfile.mkdtemp(suffix='split_separate', dir='.')
-    self.proto_directory = os.path.join(self.directory, 'proto_path')
-    self.python_out_directory = os.path.join(self.directory, 'python_out')
-    self.grpc_python_out_directory = os.path.join(self.directory, 'grpc_python_out')
-    os.makedirs(self.proto_directory)
-    os.makedirs(self.python_out_directory)
-    os.makedirs(self.grpc_python_out_directory)
-    services_proto_file = os.path.join(self.proto_directory,
-                                       'split_separate_services.proto')
-    messages_proto_file = os.path.join(self.proto_directory,
-                                       'split_separate_messages.proto')
-    open(services_proto_file, 'wb').write(services_proto_contents.replace(
-        _MESSAGES_IMPORT,
-        b'import "split_separate_messages.proto";'
-    ))
-    open(messages_proto_file, 'wb').write(messages_proto_contents)
-    protoc_result = protoc.main([
-        '',
-        '--proto_path={}'.format(self.proto_directory),
-        '--python_out={}'.format(self.python_out_directory),
-        '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
-        services_proto_file,
-        messages_proto_file,
-    ])
-    if protoc_result != 0:
-      raise Exception("unexpected protoc error")
-    open(os.path.join(self.python_out_directory, '__init__.py'), 'w').write('')
-    self.pb2_import = 'split_separate_messages_pb2'
-    self.pb2_grpc_import = 'split_separate_services_pb2_grpc'
-    self.should_find_services_in_pb2 = False
-
-  def tearDown(self):
-    shutil.rmtree(self.directory)
+    def setUp(self):
+        services_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing.split_services',
+            'services.proto')
+        messages_proto_contents = pkgutil.get_data(
+            'tests.protoc_plugin.protos.invocation_testing.split_messages',
+            'messages.proto')
+        self.directory = tempfile.mkdtemp(suffix='split_separate', dir='.')
+        self.proto_directory = os.path.join(self.directory, 'proto_path')
+        self.python_out_directory = os.path.join(self.directory, 'python_out')
+        self.grpc_python_out_directory = os.path.join(self.directory,
+                                                      'grpc_python_out')
+        os.makedirs(self.proto_directory)
+        os.makedirs(self.python_out_directory)
+        os.makedirs(self.grpc_python_out_directory)
+        services_proto_file = os.path.join(self.proto_directory,
+                                           'split_separate_services.proto')
+        messages_proto_file = os.path.join(self.proto_directory,
+                                           'split_separate_messages.proto')
+        open(services_proto_file, 'wb').write(
+            services_proto_contents.replace(
+                _MESSAGES_IMPORT, b'import "split_separate_messages.proto";'))
+        open(messages_proto_file, 'wb').write(messages_proto_contents)
+        protoc_result = protoc.main([
+            '',
+            '--proto_path={}'.format(self.proto_directory),
+            '--python_out={}'.format(self.python_out_directory),
+            '--grpc_python_out=grpc_2_0:{}'.format(
+                self.grpc_python_out_directory),
+            services_proto_file,
+            messages_proto_file,
+        ])
+        if protoc_result != 0:
+            raise Exception("unexpected protoc error")
+        open(os.path.join(self.python_out_directory, '__init__.py'),
+             'w').write('')
+        self.pb2_import = 'split_separate_messages_pb2'
+        self.pb2_grpc_import = 'split_separate_services_pb2_grpc'
+        self.should_find_services_in_pb2 = False
+
+    def tearDown(self):
+        shutil.rmtree(self.directory)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
index 1eba9c9354..f64f4e962b 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
@@ -64,84 +64,84 @@ STUB_FACTORY_IDENTIFIER = 'beta_create_TestService_stub'
 
 class _ServicerMethods(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._paused = False
-    self._fail = False
-
-  @contextlib.contextmanager
-  def pause(self):  # pylint: disable=invalid-name
-    with self._condition:
-      self._paused = True
-    yield
-    with self._condition:
-      self._paused = False
-      self._condition.notify_all()
-
-  @contextlib.contextmanager
-  def fail(self):  # pylint: disable=invalid-name
-    with self._condition:
-      self._fail = True
-    yield
-    with self._condition:
-      self._fail = False
-
-  def _control(self):  # pylint: disable=invalid-name
-    with self._condition:
-      if self._fail:
-        raise ValueError()
-      while self._paused:
-        self._condition.wait()
-
-  def UnaryCall(self, request, unused_rpc_context):
-    response = response_pb2.SimpleResponse()
-    response.payload.payload_type = payload_pb2.COMPRESSABLE
-    response.payload.payload_compressable = 'a' * request.response_size
-    self._control()
-    return response
-
-  def StreamingOutputCall(self, request, unused_rpc_context):
-    for parameter in request.response_parameters:
-      response = response_pb2.StreamingOutputCallResponse()
-      response.payload.payload_type = payload_pb2.COMPRESSABLE
-      response.payload.payload_compressable = 'a' * parameter.size
-      self._control()
-      yield response
-
-  def StreamingInputCall(self, request_iter, unused_rpc_context):
-    response = response_pb2.StreamingInputCallResponse()
-    aggregated_payload_size = 0
-    for request in request_iter:
-      aggregated_payload_size += len(request.payload.payload_compressable)
-    response.aggregated_payload_size = aggregated_payload_size
-    self._control()
-    return response
-
-  def FullDuplexCall(self, request_iter, unused_rpc_context):
-    for request in request_iter:
-      for parameter in request.response_parameters:
-        response = response_pb2.StreamingOutputCallResponse()
-        response.payload.payload_type = payload_pb2.COMPRESSABLE
-        response.payload.payload_compressable = 'a' * parameter.size
-        self._control()
-        yield response
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._paused = False
+        self._fail = False
+
+    @contextlib.contextmanager
+    def pause(self):  # pylint: disable=invalid-name
+        with self._condition:
+            self._paused = True
+        yield
+        with self._condition:
+            self._paused = False
+            self._condition.notify_all()
 
-  def HalfDuplexCall(self, request_iter, unused_rpc_context):
-    responses = []
-    for request in request_iter:
-      for parameter in request.response_parameters:
-        response = response_pb2.StreamingOutputCallResponse()
+    @contextlib.contextmanager
+    def fail(self):  # pylint: disable=invalid-name
+        with self._condition:
+            self._fail = True
+        yield
+        with self._condition:
+            self._fail = False
+
+    def _control(self):  # pylint: disable=invalid-name
+        with self._condition:
+            if self._fail:
+                raise ValueError()
+            while self._paused:
+                self._condition.wait()
+
+    def UnaryCall(self, request, unused_rpc_context):
+        response = response_pb2.SimpleResponse()
         response.payload.payload_type = payload_pb2.COMPRESSABLE
-        response.payload.payload_compressable = 'a' * parameter.size
+        response.payload.payload_compressable = 'a' * request.response_size
+        self._control()
+        return response
+
+    def StreamingOutputCall(self, request, unused_rpc_context):
+        for parameter in request.response_parameters:
+            response = response_pb2.StreamingOutputCallResponse()
+            response.payload.payload_type = payload_pb2.COMPRESSABLE
+            response.payload.payload_compressable = 'a' * parameter.size
+            self._control()
+            yield response
+
+    def StreamingInputCall(self, request_iter, unused_rpc_context):
+        response = response_pb2.StreamingInputCallResponse()
+        aggregated_payload_size = 0
+        for request in request_iter:
+            aggregated_payload_size += len(request.payload.payload_compressable)
+        response.aggregated_payload_size = aggregated_payload_size
         self._control()
-        responses.append(response)
-    for response in responses:
-      yield response
+        return response
+
+    def FullDuplexCall(self, request_iter, unused_rpc_context):
+        for request in request_iter:
+            for parameter in request.response_parameters:
+                response = response_pb2.StreamingOutputCallResponse()
+                response.payload.payload_type = payload_pb2.COMPRESSABLE
+                response.payload.payload_compressable = 'a' * parameter.size
+                self._control()
+                yield response
+
+    def HalfDuplexCall(self, request_iter, unused_rpc_context):
+        responses = []
+        for request in request_iter:
+            for parameter in request.response_parameters:
+                response = response_pb2.StreamingOutputCallResponse()
+                response.payload.payload_type = payload_pb2.COMPRESSABLE
+                response.payload.payload_compressable = 'a' * parameter.size
+                self._control()
+                responses.append(response)
+        for response in responses:
+            yield response
 
 
 @contextlib.contextmanager
 def _CreateService():
-  """Provides a servicer backend and a stub.
+    """Provides a servicer backend and a stub.
 
   The servicer is just the implementation of the actual servicer passed to the
   face player of the python RPC implementation; the two are detached.
@@ -151,38 +151,38 @@ def _CreateService():
       the service bound to the stub and and stub is the stub on which to invoke
       RPCs.
   """
-  servicer_methods = _ServicerMethods()
+    servicer_methods = _ServicerMethods()
 
-  class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
+    class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
 
-    def UnaryCall(self, request, context):
-      return servicer_methods.UnaryCall(request, context)
+        def UnaryCall(self, request, context):
+            return servicer_methods.UnaryCall(request, context)
 
-    def StreamingOutputCall(self, request, context):
-      return servicer_methods.StreamingOutputCall(request, context)
+        def StreamingOutputCall(self, request, context):
+            return servicer_methods.StreamingOutputCall(request, context)
 
-    def StreamingInputCall(self, request_iter, context):
-      return servicer_methods.StreamingInputCall(request_iter, context)
+        def StreamingInputCall(self, request_iter, context):
+            return servicer_methods.StreamingInputCall(request_iter, context)
 
-    def FullDuplexCall(self, request_iter, context):
-      return servicer_methods.FullDuplexCall(request_iter, context)
+        def FullDuplexCall(self, request_iter, context):
+            return servicer_methods.FullDuplexCall(request_iter, context)
 
-    def HalfDuplexCall(self, request_iter, context):
-      return servicer_methods.HalfDuplexCall(request_iter, context)
+        def HalfDuplexCall(self, request_iter, context):
+            return servicer_methods.HalfDuplexCall(request_iter, context)
 
-  servicer = Servicer()
-  server = getattr(service_pb2, SERVER_FACTORY_IDENTIFIER)(servicer)
-  port = server.add_insecure_port('[::]:0')
-  server.start()
-  channel = implementations.insecure_channel('localhost', port)
-  stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel)
-  yield (servicer_methods, stub)
-  server.stop(0)
+    servicer = Servicer()
+    server = getattr(service_pb2, SERVER_FACTORY_IDENTIFIER)(servicer)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = implementations.insecure_channel('localhost', port)
+    stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel)
+    yield (servicer_methods, stub)
+    server.stop(0)
 
 
 @contextlib.contextmanager
 def _CreateIncompleteService():
-  """Provides a servicer backend that fails to implement methods and its stub.
+    """Provides a servicer backend that fails to implement methods and its stub.
 
   The servicer is just the implementation of the actual servicer passed to the
   face player of the python RPC implementation; the two are detached.
@@ -194,297 +194,297 @@ def _CreateIncompleteService():
       RPCs.
   """
 
-  class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
-    pass
+    class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
+        pass
 
-  servicer = Servicer()
-  server = getattr(service_pb2, SERVER_FACTORY_IDENTIFIER)(servicer)
-  port = server.add_insecure_port('[::]:0')
-  server.start()
-  channel = implementations.insecure_channel('localhost', port)
-  stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel)
-  yield None, stub
-  server.stop(0)
+    servicer = Servicer()
+    server = getattr(service_pb2, SERVER_FACTORY_IDENTIFIER)(servicer)
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = implementations.insecure_channel('localhost', port)
+    stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel)
+    yield None, stub
+    server.stop(0)
 
 
 def _streaming_input_request_iterator():
-  for _ in range(3):
-    request = request_pb2.StreamingInputCallRequest()
-    request.payload.payload_type = payload_pb2.COMPRESSABLE
-    request.payload.payload_compressable = 'a'
-    yield request
+    for _ in range(3):
+        request = request_pb2.StreamingInputCallRequest()
+        request.payload.payload_type = payload_pb2.COMPRESSABLE
+        request.payload.payload_compressable = 'a'
+        yield request
 
 
 def _streaming_output_request():
-  request = request_pb2.StreamingOutputCallRequest()
-  sizes = [1, 2, 3]
-  request.response_parameters.add(size=sizes[0], interval_us=0)
-  request.response_parameters.add(size=sizes[1], interval_us=0)
-  request.response_parameters.add(size=sizes[2], interval_us=0)
-  return request
+    request = request_pb2.StreamingOutputCallRequest()
+    sizes = [1, 2, 3]
+    request.response_parameters.add(size=sizes[0], interval_us=0)
+    request.response_parameters.add(size=sizes[1], interval_us=0)
+    request.response_parameters.add(size=sizes[2], interval_us=0)
+    return request
 
 
 def _full_duplex_request_iterator():
-  request = request_pb2.StreamingOutputCallRequest()
-  request.response_parameters.add(size=1, interval_us=0)
-  yield request
-  request = request_pb2.StreamingOutputCallRequest()
-  request.response_parameters.add(size=2, interval_us=0)
-  request.response_parameters.add(size=3, interval_us=0)
-  yield request
+    request = request_pb2.StreamingOutputCallRequest()
+    request.response_parameters.add(size=1, interval_us=0)
+    yield request
+    request = request_pb2.StreamingOutputCallRequest()
+    request.response_parameters.add(size=2, interval_us=0)
+    request.response_parameters.add(size=3, interval_us=0)
+    yield request
 
 
 class PythonPluginTest(unittest.TestCase):
-  """Test case for the gRPC Python protoc-plugin.
+    """Test case for the gRPC Python protoc-plugin.
 
   While reading these tests, remember that the futures API
   (`stub.method.future()`) only gives futures for the *response-unary*
   methods and does not exist for response-streaming methods.
   """
 
-  def testImportAttributes(self):
-    # check that we can access the generated module and its members.
-    self.assertIsNotNone(
-        getattr(service_pb2, SERVICER_IDENTIFIER, None))
-    self.assertIsNotNone(
-        getattr(service_pb2, STUB_IDENTIFIER, None))
-    self.assertIsNotNone(
-        getattr(service_pb2, SERVER_FACTORY_IDENTIFIER, None))
-    self.assertIsNotNone(
-        getattr(service_pb2, STUB_FACTORY_IDENTIFIER, None))
-
-  def testUpDown(self):
-    with _CreateService():
-      request_pb2.SimpleRequest(response_size=13)
-
-  def testIncompleteServicer(self):
-    with _CreateIncompleteService() as (_, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      try:
-        stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
-      except face.AbortionError as error:
-        self.assertEqual(interfaces.StatusCode.UNIMPLEMENTED, error.code)
-
-  def testUnaryCall(self):
-    with _CreateService() as (methods, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      response = stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
-    expected_response = methods.UnaryCall(request, 'not a real context!')
-    self.assertEqual(expected_response, response)
-
-  def testUnaryCallFuture(self):
-    with _CreateService() as (methods, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      # Check that the call does not block waiting for the server to respond.
-      with methods.pause():
-        response_future = stub.UnaryCall.future(
-            request, test_constants.LONG_TIMEOUT)
-      response = response_future.result()
-    expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testUnaryCallFutureExpired(self):
-    with _CreateService() as (methods, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      with methods.pause():
-        response_future = stub.UnaryCall.future(
-            request, test_constants.SHORT_TIMEOUT)
-        with self.assertRaises(face.ExpirationError):
-          response_future.result()
-
-  def testUnaryCallFutureCancelled(self):
-    with _CreateService() as (methods, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      with methods.pause():
-        response_future = stub.UnaryCall.future(request, 1)
-        response_future.cancel()
-        self.assertTrue(response_future.cancelled())
-
-  def testUnaryCallFutureFailed(self):
-    with _CreateService() as (methods, stub):
-      request = request_pb2.SimpleRequest(response_size=13)
-      with methods.fail():
-        response_future = stub.UnaryCall.future(
-            request, test_constants.LONG_TIMEOUT)
-        self.assertIsNotNone(response_future.exception())
-
-  def testStreamingOutputCall(self):
-    with _CreateService() as (methods, stub):
-      request = _streaming_output_request()
-      responses = stub.StreamingOutputCall(
-          request, test_constants.LONG_TIMEOUT)
-      expected_responses = methods.StreamingOutputCall(
-          request, 'not a real RpcContext!')
-      for expected_response, response in moves.zip_longest(
-          expected_responses, responses):
+    def testImportAttributes(self):
+        # check that we can access the generated module and its members.
+        self.assertIsNotNone(getattr(service_pb2, SERVICER_IDENTIFIER, None))
+        self.assertIsNotNone(getattr(service_pb2, STUB_IDENTIFIER, None))
+        self.assertIsNotNone(
+            getattr(service_pb2, SERVER_FACTORY_IDENTIFIER, None))
+        self.assertIsNotNone(
+            getattr(service_pb2, STUB_FACTORY_IDENTIFIER, None))
+
+    def testUpDown(self):
+        with _CreateService():
+            request_pb2.SimpleRequest(response_size=13)
+
+    def testIncompleteServicer(self):
+        with _CreateIncompleteService() as (_, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            try:
+                stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
+            except face.AbortionError as error:
+                self.assertEqual(interfaces.StatusCode.UNIMPLEMENTED,
+                                 error.code)
+
+    def testUnaryCall(self):
+        with _CreateService() as (methods, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            response = stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
+        expected_response = methods.UnaryCall(request, 'not a real context!')
         self.assertEqual(expected_response, response)
 
-  def testStreamingOutputCallExpired(self):
-    with _CreateService() as (methods, stub):
-      request = _streaming_output_request()
-      with methods.pause():
-        responses = stub.StreamingOutputCall(
-            request, test_constants.SHORT_TIMEOUT)
-        with self.assertRaises(face.ExpirationError):
-          list(responses)
-
-  def testStreamingOutputCallCancelled(self):
-    with _CreateService() as (methods, stub):
-      request = _streaming_output_request()
-      responses = stub.StreamingOutputCall(
-          request, test_constants.LONG_TIMEOUT)
-      next(responses)
-      responses.cancel()
-      with self.assertRaises(face.CancellationError):
-        next(responses)
-
-  def testStreamingOutputCallFailed(self):
-    with _CreateService() as (methods, stub):
-      request = _streaming_output_request()
-      with methods.fail():
-        responses = stub.StreamingOutputCall(request, 1)
-        self.assertIsNotNone(responses)
-        with self.assertRaises(face.RemoteError):
-          next(responses)
-
-  def testStreamingInputCall(self):
-    with _CreateService() as (methods, stub):
-      response = stub.StreamingInputCall(
-          _streaming_input_request_iterator(),
-          test_constants.LONG_TIMEOUT)
-    expected_response = methods.StreamingInputCall(
-        _streaming_input_request_iterator(),
-        'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testStreamingInputCallFuture(self):
-    with _CreateService() as (methods, stub):
-      with methods.pause():
-        response_future = stub.StreamingInputCall.future(
-            _streaming_input_request_iterator(),
-            test_constants.LONG_TIMEOUT)
-      response = response_future.result()
-    expected_response = methods.StreamingInputCall(
-        _streaming_input_request_iterator(),
-        'not a real RpcContext!')
-    self.assertEqual(expected_response, response)
-
-  def testStreamingInputCallFutureExpired(self):
-    with _CreateService() as (methods, stub):
-      with methods.pause():
-        response_future = stub.StreamingInputCall.future(
-            _streaming_input_request_iterator(),
-            test_constants.SHORT_TIMEOUT)
-        with self.assertRaises(face.ExpirationError):
-          response_future.result()
-        self.assertIsInstance(
-            response_future.exception(), face.ExpirationError)
-
-  def testStreamingInputCallFutureCancelled(self):
-    with _CreateService() as (methods, stub):
-      with methods.pause():
-        response_future = stub.StreamingInputCall.future(
-            _streaming_input_request_iterator(),
-            test_constants.LONG_TIMEOUT)
-        response_future.cancel()
-        self.assertTrue(response_future.cancelled())
-      with self.assertRaises(future.CancelledError):
-        response_future.result()
-
-  def testStreamingInputCallFutureFailed(self):
-    with _CreateService() as (methods, stub):
-      with methods.fail():
-        response_future = stub.StreamingInputCall.future(
-            _streaming_input_request_iterator(),
-            test_constants.LONG_TIMEOUT)
-        self.assertIsNotNone(response_future.exception())
-
-  def testFullDuplexCall(self):
-    with _CreateService() as (methods, stub):
-      responses = stub.FullDuplexCall(
-          _full_duplex_request_iterator(),
-          test_constants.LONG_TIMEOUT)
-      expected_responses = methods.FullDuplexCall(
-          _full_duplex_request_iterator(),
-          'not a real RpcContext!')
-      for expected_response, response in moves.zip_longest(
-          expected_responses, responses):
+    def testUnaryCallFuture(self):
+        with _CreateService() as (methods, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            # Check that the call does not block waiting for the server to respond.
+            with methods.pause():
+                response_future = stub.UnaryCall.future(
+                    request, test_constants.LONG_TIMEOUT)
+            response = response_future.result()
+        expected_response = methods.UnaryCall(request, 'not a real RpcContext!')
         self.assertEqual(expected_response, response)
 
-  def testFullDuplexCallExpired(self):
-    request_iterator = _full_duplex_request_iterator()
-    with _CreateService() as (methods, stub):
-      with methods.pause():
-        responses = stub.FullDuplexCall(
-            request_iterator, test_constants.SHORT_TIMEOUT)
-        with self.assertRaises(face.ExpirationError):
-          list(responses)
-
-  def testFullDuplexCallCancelled(self):
-    with _CreateService() as (methods, stub):
-      request_iterator = _full_duplex_request_iterator()
-      responses = stub.FullDuplexCall(
-          request_iterator, test_constants.LONG_TIMEOUT)
-      next(responses)
-      responses.cancel()
-      with self.assertRaises(face.CancellationError):
-        next(responses)
-
-  def testFullDuplexCallFailed(self):
-    request_iterator = _full_duplex_request_iterator()
-    with _CreateService() as (methods, stub):
-      with methods.fail():
-        responses = stub.FullDuplexCall(
-            request_iterator, test_constants.LONG_TIMEOUT)
-        self.assertIsNotNone(responses)
-        with self.assertRaises(face.RemoteError):
-          next(responses)
-
-  def testHalfDuplexCall(self):
-    with _CreateService() as (methods, stub):
-      def half_duplex_request_iterator():
-        request = request_pb2.StreamingOutputCallRequest()
-        request.response_parameters.add(size=1, interval_us=0)
-        yield request
-        request = request_pb2.StreamingOutputCallRequest()
-        request.response_parameters.add(size=2, interval_us=0)
-        request.response_parameters.add(size=3, interval_us=0)
-        yield request
-      responses = stub.HalfDuplexCall(
-          half_duplex_request_iterator(), test_constants.LONG_TIMEOUT)
-      expected_responses = methods.HalfDuplexCall(
-          half_duplex_request_iterator(), 'not a real RpcContext!')
-      for check in moves.zip_longest(expected_responses, responses):
-        expected_response, response = check
+    def testUnaryCallFutureExpired(self):
+        with _CreateService() as (methods, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            with methods.pause():
+                response_future = stub.UnaryCall.future(
+                    request, test_constants.SHORT_TIMEOUT)
+                with self.assertRaises(face.ExpirationError):
+                    response_future.result()
+
+    def testUnaryCallFutureCancelled(self):
+        with _CreateService() as (methods, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            with methods.pause():
+                response_future = stub.UnaryCall.future(request, 1)
+                response_future.cancel()
+                self.assertTrue(response_future.cancelled())
+
+    def testUnaryCallFutureFailed(self):
+        with _CreateService() as (methods, stub):
+            request = request_pb2.SimpleRequest(response_size=13)
+            with methods.fail():
+                response_future = stub.UnaryCall.future(
+                    request, test_constants.LONG_TIMEOUT)
+                self.assertIsNotNone(response_future.exception())
+
+    def testStreamingOutputCall(self):
+        with _CreateService() as (methods, stub):
+            request = _streaming_output_request()
+            responses = stub.StreamingOutputCall(request,
+                                                 test_constants.LONG_TIMEOUT)
+            expected_responses = methods.StreamingOutputCall(
+                request, 'not a real RpcContext!')
+            for expected_response, response in moves.zip_longest(
+                    expected_responses, responses):
+                self.assertEqual(expected_response, response)
+
+    def testStreamingOutputCallExpired(self):
+        with _CreateService() as (methods, stub):
+            request = _streaming_output_request()
+            with methods.pause():
+                responses = stub.StreamingOutputCall(
+                    request, test_constants.SHORT_TIMEOUT)
+                with self.assertRaises(face.ExpirationError):
+                    list(responses)
+
+    def testStreamingOutputCallCancelled(self):
+        with _CreateService() as (methods, stub):
+            request = _streaming_output_request()
+            responses = stub.StreamingOutputCall(request,
+                                                 test_constants.LONG_TIMEOUT)
+            next(responses)
+            responses.cancel()
+            with self.assertRaises(face.CancellationError):
+                next(responses)
+
+    def testStreamingOutputCallFailed(self):
+        with _CreateService() as (methods, stub):
+            request = _streaming_output_request()
+            with methods.fail():
+                responses = stub.StreamingOutputCall(request, 1)
+                self.assertIsNotNone(responses)
+                with self.assertRaises(face.RemoteError):
+                    next(responses)
+
+    def testStreamingInputCall(self):
+        with _CreateService() as (methods, stub):
+            response = stub.StreamingInputCall(
+                _streaming_input_request_iterator(),
+                test_constants.LONG_TIMEOUT)
+        expected_response = methods.StreamingInputCall(
+            _streaming_input_request_iterator(), 'not a real RpcContext!')
         self.assertEqual(expected_response, response)
 
-  def testHalfDuplexCallWedged(self):
-    condition = threading.Condition()
-    wait_cell = [False]
-    @contextlib.contextmanager
-    def wait():  # pylint: disable=invalid-name
-      # Where's Python 3's 'nonlocal' statement when you need it?
-      with condition:
-        wait_cell[0] = True
-      yield
-      with condition:
-        wait_cell[0] = False
-        condition.notify_all()
-    def half_duplex_request_iterator():
-      request = request_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=1, interval_us=0)
-      yield request
-      with condition:
-        while wait_cell[0]:
-          condition.wait()
-    with _CreateService() as (methods, stub):
-      with wait():
-        responses = stub.HalfDuplexCall(
-            half_duplex_request_iterator(), test_constants.SHORT_TIMEOUT)
-        # half-duplex waits for the client to send all info
-        with self.assertRaises(face.ExpirationError):
-          next(responses)
+    def testStreamingInputCallFuture(self):
+        with _CreateService() as (methods, stub):
+            with methods.pause():
+                response_future = stub.StreamingInputCall.future(
+                    _streaming_input_request_iterator(),
+                    test_constants.LONG_TIMEOUT)
+            response = response_future.result()
+        expected_response = methods.StreamingInputCall(
+            _streaming_input_request_iterator(), 'not a real RpcContext!')
+        self.assertEqual(expected_response, response)
+
+    def testStreamingInputCallFutureExpired(self):
+        with _CreateService() as (methods, stub):
+            with methods.pause():
+                response_future = stub.StreamingInputCall.future(
+                    _streaming_input_request_iterator(),
+                    test_constants.SHORT_TIMEOUT)
+                with self.assertRaises(face.ExpirationError):
+                    response_future.result()
+                self.assertIsInstance(response_future.exception(),
+                                      face.ExpirationError)
+
+    def testStreamingInputCallFutureCancelled(self):
+        with _CreateService() as (methods, stub):
+            with methods.pause():
+                response_future = stub.StreamingInputCall.future(
+                    _streaming_input_request_iterator(),
+                    test_constants.LONG_TIMEOUT)
+                response_future.cancel()
+                self.assertTrue(response_future.cancelled())
+            with self.assertRaises(future.CancelledError):
+                response_future.result()
+
+    def testStreamingInputCallFutureFailed(self):
+        with _CreateService() as (methods, stub):
+            with methods.fail():
+                response_future = stub.StreamingInputCall.future(
+                    _streaming_input_request_iterator(),
+                    test_constants.LONG_TIMEOUT)
+                self.assertIsNotNone(response_future.exception())
+
+    def testFullDuplexCall(self):
+        with _CreateService() as (methods, stub):
+            responses = stub.FullDuplexCall(_full_duplex_request_iterator(),
+                                            test_constants.LONG_TIMEOUT)
+            expected_responses = methods.FullDuplexCall(
+                _full_duplex_request_iterator(), 'not a real RpcContext!')
+            for expected_response, response in moves.zip_longest(
+                    expected_responses, responses):
+                self.assertEqual(expected_response, response)
+
+    def testFullDuplexCallExpired(self):
+        request_iterator = _full_duplex_request_iterator()
+        with _CreateService() as (methods, stub):
+            with methods.pause():
+                responses = stub.FullDuplexCall(request_iterator,
+                                                test_constants.SHORT_TIMEOUT)
+                with self.assertRaises(face.ExpirationError):
+                    list(responses)
+
+    def testFullDuplexCallCancelled(self):
+        with _CreateService() as (methods, stub):
+            request_iterator = _full_duplex_request_iterator()
+            responses = stub.FullDuplexCall(request_iterator,
+                                            test_constants.LONG_TIMEOUT)
+            next(responses)
+            responses.cancel()
+            with self.assertRaises(face.CancellationError):
+                next(responses)
+
+    def testFullDuplexCallFailed(self):
+        request_iterator = _full_duplex_request_iterator()
+        with _CreateService() as (methods, stub):
+            with methods.fail():
+                responses = stub.FullDuplexCall(request_iterator,
+                                                test_constants.LONG_TIMEOUT)
+                self.assertIsNotNone(responses)
+                with self.assertRaises(face.RemoteError):
+                    next(responses)
+
+    def testHalfDuplexCall(self):
+        with _CreateService() as (methods, stub):
+
+            def half_duplex_request_iterator():
+                request = request_pb2.StreamingOutputCallRequest()
+                request.response_parameters.add(size=1, interval_us=0)
+                yield request
+                request = request_pb2.StreamingOutputCallRequest()
+                request.response_parameters.add(size=2, interval_us=0)
+                request.response_parameters.add(size=3, interval_us=0)
+                yield request
+
+            responses = stub.HalfDuplexCall(half_duplex_request_iterator(),
+                                            test_constants.LONG_TIMEOUT)
+            expected_responses = methods.HalfDuplexCall(
+                half_duplex_request_iterator(), 'not a real RpcContext!')
+            for check in moves.zip_longest(expected_responses, responses):
+                expected_response, response = check
+                self.assertEqual(expected_response, response)
+
+    def testHalfDuplexCallWedged(self):
+        condition = threading.Condition()
+        wait_cell = [False]
+
+        @contextlib.contextmanager
+        def wait():  # pylint: disable=invalid-name
+            # Where's Python 3's 'nonlocal' statement when you need it?
+            with condition:
+                wait_cell[0] = True
+            yield
+            with condition:
+                wait_cell[0] = False
+                condition.notify_all()
+
+        def half_duplex_request_iterator():
+            request = request_pb2.StreamingOutputCallRequest()
+            request.response_parameters.add(size=1, interval_us=0)
+            yield request
+            with condition:
+                while wait_cell[0]:
+                    condition.wait()
+
+        with _CreateService() as (methods, stub):
+            with wait():
+                responses = stub.HalfDuplexCall(half_duplex_request_iterator(),
+                                                test_constants.SHORT_TIMEOUT)
+                # half-duplex waits for the client to send all info
+                with self.assertRaises(face.ExpirationError):
+                    next(responses)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
index 2f88fa0412..100a624dc9 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
index 2f88fa0412..100a624dc9 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_messages/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
index 2f88fa0412..100a624dc9 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/invocation_testing/split_services/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/payload/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/payload/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/payload/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/payload/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/r/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/r/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/r/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/requests/r/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/responses/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/responses/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/responses/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/responses/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/protos/service/__init__.py b/src/python/grpcio_tests/tests/protoc_plugin/protos/service/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/protos/service/__init__.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/protos/service/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py
index 650e4756e7..2e8afc8e7f 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_client.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Defines test client behaviors (UNARY/STREAMING) (SYNC/ASYNC)."""
 
 import abc
@@ -47,165 +46,168 @@ _TIMEOUT = 60 * 60 * 24
 
 class GenericStub(object):
 
-  def __init__(self, channel):
-    self.UnaryCall = channel.unary_unary(
-        '/grpc.testing.BenchmarkService/UnaryCall')
-    self.StreamingCall = channel.stream_stream(
-        '/grpc.testing.BenchmarkService/StreamingCall')
+    def __init__(self, channel):
+        self.UnaryCall = channel.unary_unary(
+            '/grpc.testing.BenchmarkService/UnaryCall')
+        self.StreamingCall = channel.stream_stream(
+            '/grpc.testing.BenchmarkService/StreamingCall')
 
 
 class BenchmarkClient:
-  """Benchmark client interface that exposes a non-blocking send_request()."""
-
-  __metaclass__ = abc.ABCMeta
-
-  def __init__(self, server, config, hist):
-    # Create the stub
-    if config.HasField('security_params'):
-      creds = grpc.ssl_channel_credentials(resources.test_root_certificates())
-      channel = test_common.test_secure_channel(
-        server, creds, config.security_params.server_host_override)
-    else:
-      channel = grpc.insecure_channel(server)
-
-    # waits for the channel to be ready before we start sending messages
-    grpc.channel_ready_future(channel).result()
-
-    if config.payload_config.WhichOneof('payload') == 'simple_params':
-      self._generic = False
-      self._stub = services_pb2.BenchmarkServiceStub(channel)
-      payload = messages_pb2.Payload(
-          body='\0' * config.payload_config.simple_params.req_size)
-      self._request = messages_pb2.SimpleRequest(
-          payload=payload,
-          response_size=config.payload_config.simple_params.resp_size)
-    else:
-      self._generic = True
-      self._stub = GenericStub(channel)
-      self._request = '\0' * config.payload_config.bytebuf_params.req_size
-
-    self._hist = hist
-    self._response_callbacks = []
-
-  def add_response_callback(self, callback):
-    """callback will be invoked as callback(client, query_time)"""
-    self._response_callbacks.append(callback)
-
-  @abc.abstractmethod
-  def send_request(self):
-    """Non-blocking wrapper for a client's request operation."""
-    raise NotImplementedError()
-
-  def start(self):
-    pass
-
-  def stop(self):
-    pass
-
-  def _handle_response(self, client, query_time):
-    self._hist.add(query_time * 1e9)  # Report times in nanoseconds
-    for callback in self._response_callbacks:
-      callback(client, query_time)
+    """Benchmark client interface that exposes a non-blocking send_request()."""
+
+    __metaclass__ = abc.ABCMeta
+
+    def __init__(self, server, config, hist):
+        # Create the stub
+        if config.HasField('security_params'):
+            creds = grpc.ssl_channel_credentials(
+                resources.test_root_certificates())
+            channel = test_common.test_secure_channel(
+                server, creds, config.security_params.server_host_override)
+        else:
+            channel = grpc.insecure_channel(server)
+
+        # waits for the channel to be ready before we start sending messages
+        grpc.channel_ready_future(channel).result()
+
+        if config.payload_config.WhichOneof('payload') == 'simple_params':
+            self._generic = False
+            self._stub = services_pb2.BenchmarkServiceStub(channel)
+            payload = messages_pb2.Payload(
+                body='\0' * config.payload_config.simple_params.req_size)
+            self._request = messages_pb2.SimpleRequest(
+                payload=payload,
+                response_size=config.payload_config.simple_params.resp_size)
+        else:
+            self._generic = True
+            self._stub = GenericStub(channel)
+            self._request = '\0' * config.payload_config.bytebuf_params.req_size
+
+        self._hist = hist
+        self._response_callbacks = []
+
+    def add_response_callback(self, callback):
+        """callback will be invoked as callback(client, query_time)"""
+        self._response_callbacks.append(callback)
+
+    @abc.abstractmethod
+    def send_request(self):
+        """Non-blocking wrapper for a client's request operation."""
+        raise NotImplementedError()
+
+    def start(self):
+        pass
+
+    def stop(self):
+        pass
+
+    def _handle_response(self, client, query_time):
+        self._hist.add(query_time * 1e9)  # Report times in nanoseconds
+        for callback in self._response_callbacks:
+            callback(client, query_time)
 
 
 class UnarySyncBenchmarkClient(BenchmarkClient):
 
-  def __init__(self, server, config, hist):
-    super(UnarySyncBenchmarkClient, self).__init__(server, config, hist)
-    self._pool = futures.ThreadPoolExecutor(
-        max_workers=config.outstanding_rpcs_per_channel)
+    def __init__(self, server, config, hist):
+        super(UnarySyncBenchmarkClient, self).__init__(server, config, hist)
+        self._pool = futures.ThreadPoolExecutor(
+            max_workers=config.outstanding_rpcs_per_channel)
 
-  def send_request(self):
-    # Send requests in seperate threads to support multiple outstanding rpcs
-    # (See src/proto/grpc/testing/control.proto)
-    self._pool.submit(self._dispatch_request)
+    def send_request(self):
+        # Send requests in seperate threads to support multiple outstanding rpcs
+        # (See src/proto/grpc/testing/control.proto)
+        self._pool.submit(self._dispatch_request)
 
-  def stop(self):
-    self._pool.shutdown(wait=True)
-    self._stub = None
+    def stop(self):
+        self._pool.shutdown(wait=True)
+        self._stub = None
 
-  def _dispatch_request(self):
-    start_time = time.time()
-    self._stub.UnaryCall(self._request, _TIMEOUT)
-    end_time = time.time()
-    self._handle_response(self, end_time - start_time)
+    def _dispatch_request(self):
+        start_time = time.time()
+        self._stub.UnaryCall(self._request, _TIMEOUT)
+        end_time = time.time()
+        self._handle_response(self, end_time - start_time)
 
 
 class UnaryAsyncBenchmarkClient(BenchmarkClient):
 
-  def send_request(self):
-    # Use the Future callback api to support multiple outstanding rpcs
-    start_time = time.time()
-    response_future = self._stub.UnaryCall.future(self._request, _TIMEOUT)
-    response_future.add_done_callback(
-        lambda resp: self._response_received(start_time, resp))
+    def send_request(self):
+        # Use the Future callback api to support multiple outstanding rpcs
+        start_time = time.time()
+        response_future = self._stub.UnaryCall.future(self._request, _TIMEOUT)
+        response_future.add_done_callback(
+            lambda resp: self._response_received(start_time, resp))
 
-  def _response_received(self, start_time, resp):
-    resp.result()
-    end_time = time.time()
-    self._handle_response(self, end_time - start_time)
+    def _response_received(self, start_time, resp):
+        resp.result()
+        end_time = time.time()
+        self._handle_response(self, end_time - start_time)
 
-  def stop(self):
-    self._stub = None
+    def stop(self):
+        self._stub = None
 
 
 class _SyncStream(object):
 
-  def __init__(self, stub, generic, request, handle_response):
-    self._stub = stub
-    self._generic = generic
-    self._request = request
-    self._handle_response = handle_response
-    self._is_streaming = False
-    self._request_queue = queue.Queue()
-    self._send_time_queue = queue.Queue()
-
-  def send_request(self):
-    self._send_time_queue.put(time.time())
-    self._request_queue.put(self._request)
-
-  def start(self):
-    self._is_streaming = True
-    response_stream = self._stub.StreamingCall(
-        self._request_generator(), _TIMEOUT)
-    for _ in response_stream:
-      self._handle_response(
-          self, time.time() - self._send_time_queue.get_nowait())
-
-  def stop(self):
-    self._is_streaming = False
-
-  def _request_generator(self):
-    while self._is_streaming:
-      try:
-        request = self._request_queue.get(block=True, timeout=1.0)
-        yield request
-      except queue.Empty:
-        pass
+    def __init__(self, stub, generic, request, handle_response):
+        self._stub = stub
+        self._generic = generic
+        self._request = request
+        self._handle_response = handle_response
+        self._is_streaming = False
+        self._request_queue = queue.Queue()
+        self._send_time_queue = queue.Queue()
+
+    def send_request(self):
+        self._send_time_queue.put(time.time())
+        self._request_queue.put(self._request)
+
+    def start(self):
+        self._is_streaming = True
+        response_stream = self._stub.StreamingCall(self._request_generator(),
+                                                   _TIMEOUT)
+        for _ in response_stream:
+            self._handle_response(
+                self, time.time() - self._send_time_queue.get_nowait())
+
+    def stop(self):
+        self._is_streaming = False
+
+    def _request_generator(self):
+        while self._is_streaming:
+            try:
+                request = self._request_queue.get(block=True, timeout=1.0)
+                yield request
+            except queue.Empty:
+                pass
 
 
 class StreamingSyncBenchmarkClient(BenchmarkClient):
 
-  def __init__(self, server, config, hist):
-    super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist)
-    self._pool = futures.ThreadPoolExecutor(
-        max_workers=config.outstanding_rpcs_per_channel)
-    self._streams = [_SyncStream(self._stub, self._generic, 
-                                 self._request, self._handle_response)
-                     for _ in xrange(config.outstanding_rpcs_per_channel)]
-    self._curr_stream = 0
-
-  def send_request(self):
-    # Use a round_robin scheduler to determine what stream to send on
-    self._streams[self._curr_stream].send_request()
-    self._curr_stream = (self._curr_stream + 1) % len(self._streams)
-
-  def start(self):
-    for stream in self._streams:
-      self._pool.submit(stream.start)
-
-  def stop(self):
-    for stream in self._streams:
-      stream.stop()
-    self._pool.shutdown(wait=True)
-    self._stub = None
+    def __init__(self, server, config, hist):
+        super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist)
+        self._pool = futures.ThreadPoolExecutor(
+            max_workers=config.outstanding_rpcs_per_channel)
+        self._streams = [
+            _SyncStream(self._stub, self._generic, self._request,
+                        self._handle_response)
+            for _ in xrange(config.outstanding_rpcs_per_channel)
+        ]
+        self._curr_stream = 0
+
+    def send_request(self):
+        # Use a round_robin scheduler to determine what stream to send on
+        self._streams[self._curr_stream].send_request()
+        self._curr_stream = (self._curr_stream + 1) % len(self._streams)
+
+    def start(self):
+        for stream in self._streams:
+            self._pool.submit(stream.start)
+
+    def stop(self):
+        for stream in self._streams:
+            stream.stop()
+        self._pool.shutdown(wait=True)
+        self._stub = None
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_server.py b/src/python/grpcio_tests/tests/qps/benchmark_server.py
index 2b76b810cd..423d03b804 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_server.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_server.py
@@ -32,27 +32,27 @@ from src.proto.grpc.testing import services_pb2
 
 
 class BenchmarkServer(services_pb2.BenchmarkServiceServicer):
-  """Synchronous Server implementation for the Benchmark service."""
+    """Synchronous Server implementation for the Benchmark service."""
 
-  def UnaryCall(self, request, context):
-    payload = messages_pb2.Payload(body='\0' * request.response_size)
-    return messages_pb2.SimpleResponse(payload=payload)
+    def UnaryCall(self, request, context):
+        payload = messages_pb2.Payload(body='\0' * request.response_size)
+        return messages_pb2.SimpleResponse(payload=payload)
 
-  def StreamingCall(self, request_iterator, context):
-    for request in request_iterator:
-      payload = messages_pb2.Payload(body='\0' * request.response_size)
-      yield messages_pb2.SimpleResponse(payload=payload)
+    def StreamingCall(self, request_iterator, context):
+        for request in request_iterator:
+            payload = messages_pb2.Payload(body='\0' * request.response_size)
+            yield messages_pb2.SimpleResponse(payload=payload)
 
 
 class GenericBenchmarkServer(services_pb2.BenchmarkServiceServicer):
-  """Generic Server implementation for the Benchmark service."""
+    """Generic Server implementation for the Benchmark service."""
 
-  def __init__(self, resp_size):
-    self._response = '\0' * resp_size
+    def __init__(self, resp_size):
+        self._response = '\0' * resp_size
 
-  def UnaryCall(self, request, context):
-    return self._response
+    def UnaryCall(self, request, context):
+        return self._response
 
-  def StreamingCall(self, request_iterator, context):
-    for request in request_iterator:
-      yield self._response
+    def StreamingCall(self, request_iterator, context):
+        for request in request_iterator:
+            yield self._response
diff --git a/src/python/grpcio_tests/tests/qps/client_runner.py b/src/python/grpcio_tests/tests/qps/client_runner.py
index 1fd58687ad..037092313c 100644
--- a/src/python/grpcio_tests/tests/qps/client_runner.py
+++ b/src/python/grpcio_tests/tests/qps/client_runner.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Defines behavior for WHEN clients send requests.
 
 Each client exposes a non-blocking send_request() method that the
@@ -39,68 +38,68 @@ import time
 
 
 class ClientRunner:
-  """Abstract interface for sending requests from clients."""
+    """Abstract interface for sending requests from clients."""
 
-  __metaclass__ = abc.ABCMeta
+    __metaclass__ = abc.ABCMeta
 
-  def __init__(self, client):
-    self._client = client
+    def __init__(self, client):
+        self._client = client
 
-  @abc.abstractmethod
-  def start(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def start(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stop(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def stop(self):
+        raise NotImplementedError()
 
 
 class OpenLoopClientRunner(ClientRunner):
 
-  def __init__(self, client, interval_generator):
-    super(OpenLoopClientRunner, self).__init__(client)
-    self._is_running = False
-    self._interval_generator = interval_generator
-    self._dispatch_thread = threading.Thread(
-        target=self._dispatch_requests, args=())
-
-  def start(self):
-    self._is_running = True
-    self._client.start()
-    self._dispatch_thread.start()
-   
-  def stop(self):
-    self._is_running = False
-    self._client.stop()
-    self._dispatch_thread.join()
-    self._client = None
-
-  def _dispatch_requests(self):
-    while self._is_running:
-      self._client.send_request()
-      time.sleep(next(self._interval_generator))
+    def __init__(self, client, interval_generator):
+        super(OpenLoopClientRunner, self).__init__(client)
+        self._is_running = False
+        self._interval_generator = interval_generator
+        self._dispatch_thread = threading.Thread(
+            target=self._dispatch_requests, args=())
+
+    def start(self):
+        self._is_running = True
+        self._client.start()
+        self._dispatch_thread.start()
+
+    def stop(self):
+        self._is_running = False
+        self._client.stop()
+        self._dispatch_thread.join()
+        self._client = None
+
+    def _dispatch_requests(self):
+        while self._is_running:
+            self._client.send_request()
+            time.sleep(next(self._interval_generator))
 
 
 class ClosedLoopClientRunner(ClientRunner):
 
-  def __init__(self, client, request_count):
-    super(ClosedLoopClientRunner, self).__init__(client)
-    self._is_running = False
-    self._request_count = request_count
-    # Send a new request on each response for closed loop
-    self._client.add_response_callback(self._send_request)
-
-  def start(self):
-    self._is_running = True
-    self._client.start()
-    for _ in xrange(self._request_count):
-      self._client.send_request()
-
-  def stop(self):
-    self._is_running = False
-    self._client.stop()
-    self._client = None
-
-  def _send_request(self, client, response_time):
-    if self._is_running:
-      client.send_request()
+    def __init__(self, client, request_count):
+        super(ClosedLoopClientRunner, self).__init__(client)
+        self._is_running = False
+        self._request_count = request_count
+        # Send a new request on each response for closed loop
+        self._client.add_response_callback(self._send_request)
+
+    def start(self):
+        self._is_running = True
+        self._client.start()
+        for _ in xrange(self._request_count):
+            self._client.send_request()
+
+    def stop(self):
+        self._is_running = False
+        self._client.stop()
+        self._client = None
+
+    def _send_request(self, client, response_time):
+        if self._is_running:
+            client.send_request()
diff --git a/src/python/grpcio_tests/tests/qps/histogram.py b/src/python/grpcio_tests/tests/qps/histogram.py
index 9a7b5eb2ba..61040b6f3b 100644
--- a/src/python/grpcio_tests/tests/qps/histogram.py
+++ b/src/python/grpcio_tests/tests/qps/histogram.py
@@ -34,52 +34,52 @@ from src.proto.grpc.testing import stats_pb2
 
 
 class Histogram(object):
-  """Histogram class used for recording performance testing data.
+    """Histogram class used for recording performance testing data.
 
   This class is thread safe.
   """
 
-  def __init__(self, resolution, max_possible):
-    self._lock = threading.Lock()
-    self._resolution = resolution
-    self._max_possible = max_possible
-    self._sum = 0
-    self._sum_of_squares = 0
-    self.multiplier = 1.0 + self._resolution
-    self._count = 0
-    self._min = self._max_possible
-    self._max = 0
-    self._buckets = [0] * (self._bucket_for(self._max_possible) + 1)
+    def __init__(self, resolution, max_possible):
+        self._lock = threading.Lock()
+        self._resolution = resolution
+        self._max_possible = max_possible
+        self._sum = 0
+        self._sum_of_squares = 0
+        self.multiplier = 1.0 + self._resolution
+        self._count = 0
+        self._min = self._max_possible
+        self._max = 0
+        self._buckets = [0] * (self._bucket_for(self._max_possible) + 1)
 
-  def reset(self):
-    with self._lock:
-      self._sum = 0
-      self._sum_of_squares = 0
-      self._count = 0
-      self._min = self._max_possible
-      self._max = 0
-      self._buckets = [0] * (self._bucket_for(self._max_possible) + 1)
+    def reset(self):
+        with self._lock:
+            self._sum = 0
+            self._sum_of_squares = 0
+            self._count = 0
+            self._min = self._max_possible
+            self._max = 0
+            self._buckets = [0] * (self._bucket_for(self._max_possible) + 1)
 
-  def add(self, val):
-    with self._lock:
-      self._sum += val
-      self._sum_of_squares += val * val
-      self._count += 1
-      self._min = min(self._min, val)
-      self._max = max(self._max, val)
-      self._buckets[self._bucket_for(val)] += 1
+    def add(self, val):
+        with self._lock:
+            self._sum += val
+            self._sum_of_squares += val * val
+            self._count += 1
+            self._min = min(self._min, val)
+            self._max = max(self._max, val)
+            self._buckets[self._bucket_for(val)] += 1
 
-  def get_data(self):
-    with self._lock:
-      data = stats_pb2.HistogramData()
-      data.bucket.extend(self._buckets)
-      data.min_seen = self._min
-      data.max_seen = self._max
-      data.sum = self._sum
-      data.sum_of_squares = self._sum_of_squares
-      data.count = self._count
-      return data
+    def get_data(self):
+        with self._lock:
+            data = stats_pb2.HistogramData()
+            data.bucket.extend(self._buckets)
+            data.min_seen = self._min
+            data.max_seen = self._max
+            data.sum = self._sum
+            data.sum_of_squares = self._sum_of_squares
+            data.count = self._count
+            return data
 
-  def _bucket_for(self, val):
-    val = min(val, self._max_possible)
-    return int(math.log(val, self.multiplier))
+    def _bucket_for(self, val):
+        val = min(val, self._max_possible)
+        return int(math.log(val, self.multiplier))
diff --git a/src/python/grpcio_tests/tests/qps/qps_worker.py b/src/python/grpcio_tests/tests/qps/qps_worker.py
index 2371ff0956..025dfb9d4a 100644
--- a/src/python/grpcio_tests/tests/qps/qps_worker.py
+++ b/src/python/grpcio_tests/tests/qps/qps_worker.py
@@ -26,7 +26,6 @@
 # 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.
-
 """The entry point for the qps worker."""
 
 import argparse
@@ -40,22 +39,23 @@ from tests.qps import worker_server
 
 
 def run_worker_server(port):
-  server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
-  servicer = worker_server.WorkerServer()
-  services_pb2.add_WorkerServiceServicer_to_server(servicer, server)
-  server.add_insecure_port('[::]:{}'.format(port))
-  server.start()
-  servicer.wait_for_quit()
-  server.stop(0)
+    server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
+    servicer = worker_server.WorkerServer()
+    services_pb2.add_WorkerServiceServicer_to_server(servicer, server)
+    server.add_insecure_port('[::]:{}'.format(port))
+    server.start()
+    servicer.wait_for_quit()
+    server.stop(0)
 
 
 if __name__ == '__main__':
-  parser = argparse.ArgumentParser(
-      description='gRPC Python performance testing worker')
-  parser.add_argument('--driver_port',
-                      type=int,
-                      dest='port',
-                      help='The port the worker should listen on')
-  args = parser.parse_args()
-
-  run_worker_server(args.port)
+    parser = argparse.ArgumentParser(
+        description='gRPC Python performance testing worker')
+    parser.add_argument(
+        '--driver_port',
+        type=int,
+        dest='port',
+        help='The port the worker should listen on')
+    args = parser.parse_args()
+
+    run_worker_server(args.port)
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 46d542940f..1deb7ed698 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -46,149 +46,156 @@ from tests.unit import resources
 
 
 class WorkerServer(services_pb2.WorkerServiceServicer):
-  """Python Worker Server implementation."""
-
-  def __init__(self):
-    self._quit_event = threading.Event()
-
-  def RunServer(self, request_iterator, context):
-    config = next(request_iterator).setup
-    server, port = self._create_server(config)
-    cores = multiprocessing.cpu_count()
-    server.start()
-    start_time = time.time()
-    yield self._get_server_status(start_time, start_time, port, cores)
-
-    for request in request_iterator:
-      end_time = time.time()
-      status = self._get_server_status(start_time, end_time, port, cores)
-      if request.mark.reset:
-        start_time = end_time
-      yield status
-    server.stop(None)
-
-  def _get_server_status(self, start_time, end_time, port, cores):
-    end_time = time.time()
-    elapsed_time = end_time - start_time
-    stats = stats_pb2.ServerStats(time_elapsed=elapsed_time,
-                                  time_user=elapsed_time,
-                                  time_system=elapsed_time)
-    return control_pb2.ServerStatus(stats=stats, port=port, cores=cores)
-
-  def _create_server(self, config):
-    if config.async_server_threads == 0:
-      # This is the default concurrent.futures thread pool size, but
-      # None doesn't seem to work
-      server_threads = multiprocessing.cpu_count() * 5
-    else:
-      server_threads = config.async_server_threads
-    server = grpc.server(futures.ThreadPoolExecutor(
-        max_workers=server_threads))
-    if config.server_type == control_pb2.ASYNC_SERVER:
-      servicer = benchmark_server.BenchmarkServer()
-      services_pb2.add_BenchmarkServiceServicer_to_server(servicer, server)
-    elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
-      resp_size = config.payload_config.bytebuf_params.resp_size
-      servicer = benchmark_server.GenericBenchmarkServer(resp_size)
-      method_implementations = {
-          'StreamingCall':
-          grpc.stream_stream_rpc_method_handler(servicer.StreamingCall),
-          'UnaryCall':
-          grpc.unary_unary_rpc_method_handler(servicer.UnaryCall),
-      }
-      handler = grpc.method_handlers_generic_handler(
-          'grpc.testing.BenchmarkService', method_implementations)
-      server.add_generic_rpc_handlers((handler,))
-    else:
-      raise Exception('Unsupported server type {}'.format(config.server_type))
-
-    if config.HasField('security_params'):  # Use SSL
-      server_creds = grpc.ssl_server_credentials(
-          ((resources.private_key(), resources.certificate_chain()),))
-      port = server.add_secure_port('[::]:{}'.format(config.port), server_creds)
-    else:
-      port = server.add_insecure_port('[::]:{}'.format(config.port))
-
-    return (server, port)
-
-  def RunClient(self, request_iterator, context):
-    config = next(request_iterator).setup
-    client_runners = []
-    qps_data = histogram.Histogram(config.histogram_params.resolution,
-                                   config.histogram_params.max_possible)
-    start_time = time.time()
-
-    # Create a client for each channel
-    for i in xrange(config.client_channels):
-      server = config.server_targets[i % len(config.server_targets)]
-      runner = self._create_client_runner(server, config, qps_data)
-      client_runners.append(runner)
-      runner.start()
-
-    end_time = time.time()
-    yield self._get_client_status(start_time, end_time, qps_data)
-
-    # Respond to stat requests
-    for request in request_iterator:
-      end_time = time.time()
-      status = self._get_client_status(start_time, end_time, qps_data)
-      if request.mark.reset:
-        qps_data.reset()
+    """Python Worker Server implementation."""
+
+    def __init__(self):
+        self._quit_event = threading.Event()
+
+    def RunServer(self, request_iterator, context):
+        config = next(request_iterator).setup
+        server, port = self._create_server(config)
+        cores = multiprocessing.cpu_count()
+        server.start()
         start_time = time.time()
-      yield status
-
-    # Cleanup the clients
-    for runner in client_runners:
-      runner.stop()
-
-  def _get_client_status(self, start_time, end_time, qps_data):
-    latencies = qps_data.get_data()
-    end_time = time.time()
-    elapsed_time = end_time - start_time
-    stats = stats_pb2.ClientStats(latencies=latencies,
-                                  time_elapsed=elapsed_time,
-                                  time_user=elapsed_time,
-                                  time_system=elapsed_time)
-    return control_pb2.ClientStatus(stats=stats)
-
-  def _create_client_runner(self, server, config, qps_data):
-    if config.client_type == control_pb2.SYNC_CLIENT:
-      if config.rpc_type == control_pb2.UNARY:
-        client = benchmark_client.UnarySyncBenchmarkClient(
-            server, config, qps_data)
-      elif config.rpc_type == control_pb2.STREAMING:
-        client = benchmark_client.StreamingSyncBenchmarkClient(
-            server, config, qps_data)
-    elif config.client_type == control_pb2.ASYNC_CLIENT:
-      if config.rpc_type == control_pb2.UNARY:
-        client = benchmark_client.UnaryAsyncBenchmarkClient(
-            server, config, qps_data)
-      else:
-        raise Exception('Async streaming client not supported')
-    else:
-      raise Exception('Unsupported client type {}'.format(config.client_type))
-
-    # In multi-channel tests, we split the load across all channels
-    load_factor = float(config.client_channels)
-    if config.load_params.WhichOneof('load') == 'closed_loop':
-      runner = client_runner.ClosedLoopClientRunner(
-          client, config.outstanding_rpcs_per_channel)
-    else:  # Open loop Poisson
-      alpha = config.load_params.poisson.offered_load / load_factor
-      def poisson():
-        while True:
-          yield random.expovariate(alpha)
-
-      runner = client_runner.OpenLoopClientRunner(client, poisson())
-
-    return runner
-
-  def CoreCount(self, request, context):
-    return control_pb2.CoreResponse(cores=multiprocessing.cpu_count())
-
-  def QuitWorker(self, request, context):
-    self._quit_event.set()
-    return control_pb2.Void()
-
-  def wait_for_quit(self):
-    self._quit_event.wait()
+        yield self._get_server_status(start_time, start_time, port, cores)
+
+        for request in request_iterator:
+            end_time = time.time()
+            status = self._get_server_status(start_time, end_time, port, cores)
+            if request.mark.reset:
+                start_time = end_time
+            yield status
+        server.stop(None)
+
+    def _get_server_status(self, start_time, end_time, port, cores):
+        end_time = time.time()
+        elapsed_time = end_time - start_time
+        stats = stats_pb2.ServerStats(
+            time_elapsed=elapsed_time,
+            time_user=elapsed_time,
+            time_system=elapsed_time)
+        return control_pb2.ServerStatus(stats=stats, port=port, cores=cores)
+
+    def _create_server(self, config):
+        if config.async_server_threads == 0:
+            # This is the default concurrent.futures thread pool size, but
+            # None doesn't seem to work
+            server_threads = multiprocessing.cpu_count() * 5
+        else:
+            server_threads = config.async_server_threads
+        server = grpc.server(
+            futures.ThreadPoolExecutor(max_workers=server_threads))
+        if config.server_type == control_pb2.ASYNC_SERVER:
+            servicer = benchmark_server.BenchmarkServer()
+            services_pb2.add_BenchmarkServiceServicer_to_server(servicer,
+                                                                server)
+        elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
+            resp_size = config.payload_config.bytebuf_params.resp_size
+            servicer = benchmark_server.GenericBenchmarkServer(resp_size)
+            method_implementations = {
+                'StreamingCall':
+                grpc.stream_stream_rpc_method_handler(servicer.StreamingCall),
+                'UnaryCall':
+                grpc.unary_unary_rpc_method_handler(servicer.UnaryCall),
+            }
+            handler = grpc.method_handlers_generic_handler(
+                'grpc.testing.BenchmarkService', method_implementations)
+            server.add_generic_rpc_handlers((handler,))
+        else:
+            raise Exception('Unsupported server type {}'.format(
+                config.server_type))
+
+        if config.HasField('security_params'):  # Use SSL
+            server_creds = grpc.ssl_server_credentials((
+                (resources.private_key(), resources.certificate_chain()),))
+            port = server.add_secure_port('[::]:{}'.format(config.port),
+                                          server_creds)
+        else:
+            port = server.add_insecure_port('[::]:{}'.format(config.port))
+
+        return (server, port)
+
+    def RunClient(self, request_iterator, context):
+        config = next(request_iterator).setup
+        client_runners = []
+        qps_data = histogram.Histogram(config.histogram_params.resolution,
+                                       config.histogram_params.max_possible)
+        start_time = time.time()
+
+        # Create a client for each channel
+        for i in xrange(config.client_channels):
+            server = config.server_targets[i % len(config.server_targets)]
+            runner = self._create_client_runner(server, config, qps_data)
+            client_runners.append(runner)
+            runner.start()
+
+        end_time = time.time()
+        yield self._get_client_status(start_time, end_time, qps_data)
+
+        # Respond to stat requests
+        for request in request_iterator:
+            end_time = time.time()
+            status = self._get_client_status(start_time, end_time, qps_data)
+            if request.mark.reset:
+                qps_data.reset()
+                start_time = time.time()
+            yield status
+
+        # Cleanup the clients
+        for runner in client_runners:
+            runner.stop()
+
+    def _get_client_status(self, start_time, end_time, qps_data):
+        latencies = qps_data.get_data()
+        end_time = time.time()
+        elapsed_time = end_time - start_time
+        stats = stats_pb2.ClientStats(
+            latencies=latencies,
+            time_elapsed=elapsed_time,
+            time_user=elapsed_time,
+            time_system=elapsed_time)
+        return control_pb2.ClientStatus(stats=stats)
+
+    def _create_client_runner(self, server, config, qps_data):
+        if config.client_type == control_pb2.SYNC_CLIENT:
+            if config.rpc_type == control_pb2.UNARY:
+                client = benchmark_client.UnarySyncBenchmarkClient(
+                    server, config, qps_data)
+            elif config.rpc_type == control_pb2.STREAMING:
+                client = benchmark_client.StreamingSyncBenchmarkClient(
+                    server, config, qps_data)
+        elif config.client_type == control_pb2.ASYNC_CLIENT:
+            if config.rpc_type == control_pb2.UNARY:
+                client = benchmark_client.UnaryAsyncBenchmarkClient(
+                    server, config, qps_data)
+            else:
+                raise Exception('Async streaming client not supported')
+        else:
+            raise Exception('Unsupported client type {}'.format(
+                config.client_type))
+
+        # In multi-channel tests, we split the load across all channels
+        load_factor = float(config.client_channels)
+        if config.load_params.WhichOneof('load') == 'closed_loop':
+            runner = client_runner.ClosedLoopClientRunner(
+                client, config.outstanding_rpcs_per_channel)
+        else:  # Open loop Poisson
+            alpha = config.load_params.poisson.offered_load / load_factor
+
+            def poisson():
+                while True:
+                    yield random.expovariate(alpha)
+
+            runner = client_runner.OpenLoopClientRunner(client, poisson())
+
+        return runner
+
+    def CoreCount(self, request, context):
+        return control_pb2.CoreResponse(cores=multiprocessing.cpu_count())
+
+    def QuitWorker(self, request, context):
+        self._quit_event.set()
+        return control_pb2.Void()
+
+    def wait_for_quit(self):
+        self._quit_event.wait()
diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
index 43d6c971b5..76e89ca039 100644
--- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
+++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc_reflection.v1alpha.reflection."""
 
 import unittest
@@ -45,141 +44,112 @@ from tests.unit.framework.common import test_constants
 
 _EMPTY_PROTO_FILE_NAME = 'src/proto/grpc/testing/empty.proto'
 _EMPTY_PROTO_SYMBOL_NAME = 'grpc.testing.Empty'
-_SERVICE_NAMES = (
-    'Angstrom', 'Bohr', 'Curie', 'Dyson', 'Einstein', 'Feynman', 'Galilei')
+_SERVICE_NAMES = ('Angstrom', 'Bohr', 'Curie', 'Dyson', 'Einstein', 'Feynman',
+                  'Galilei')
+
 
 def _file_descriptor_to_proto(descriptor):
-  proto = descriptor_pb2.FileDescriptorProto()
-  descriptor.CopyToProto(proto)
-  return proto.SerializeToString()
+    proto = descriptor_pb2.FileDescriptorProto()
+    descriptor.CopyToProto(proto)
+    return proto.SerializeToString()
+
 
 class ReflectionServicerTest(unittest.TestCase):
 
-  def setUp(self):
-    servicer = reflection.ReflectionServicer(service_names=_SERVICE_NAMES)
-    server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(server_pool)
-    port = self._server.add_insecure_port('[::]:0')
-    reflection_pb2.add_ServerReflectionServicer_to_server(servicer, self._server)
-    self._server.start()
-
-    channel = grpc.insecure_channel('localhost:%d' % port)
-    self._stub = reflection_pb2.ServerReflectionStub(channel)
-
-  def testFileByName(self):
-    requests = (
-      reflection_pb2.ServerReflectionRequest(
-        file_by_filename=_EMPTY_PROTO_FILE_NAME
-      ),
-      reflection_pb2.ServerReflectionRequest(
-        file_by_filename='i-donut-exist'
-      ),
-    )
-    responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
-    expected_responses = (
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        file_descriptor_response=reflection_pb2.FileDescriptorResponse(
-          file_descriptor_proto=(
-            _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
-          )
-        )
-      ),
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        error_response=reflection_pb2.ErrorResponse(
-          error_code=grpc.StatusCode.NOT_FOUND.value[0],
-          error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
-        )
-      ),
-    )
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testFileBySymbol(self):
-    requests = (
-      reflection_pb2.ServerReflectionRequest(
-        file_containing_symbol=_EMPTY_PROTO_SYMBOL_NAME
-      ),
-      reflection_pb2.ServerReflectionRequest(
-        file_containing_symbol='i.donut.exist.co.uk.org.net.me.name.foo'
-      ),
-    )
-    responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
-    expected_responses = (
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        file_descriptor_response=reflection_pb2.FileDescriptorResponse(
-          file_descriptor_proto=(
-            _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
-          )
-        )
-      ),
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        error_response=reflection_pb2.ErrorResponse(
-          error_code=grpc.StatusCode.NOT_FOUND.value[0],
-          error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
-        )
-      ),
-    )
-    self.assertSequenceEqual(expected_responses, responses)
-
-  @unittest.skip('TODO(atash): implement file-containing-extension reflection '
-                 '(see https://github.com/google/protobuf/issues/2248)')
-  def testFileContainingExtension(self):
-    requests = (
-      reflection_pb2.ServerReflectionRequest(
-        file_containing_extension=reflection_pb2.ExtensionRequest(
-          containing_type='grpc.testing.proto2.Empty',
-          extension_number=125,
-        ),
-      ),
-      reflection_pb2.ServerReflectionRequest(
-        file_containing_extension=reflection_pb2.ExtensionRequest(
-          containing_type='i.donut.exist.co.uk.org.net.me.name.foo',
-          extension_number=55,
-        ),
-      ),
-    )
-    responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
-    expected_responses = (
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        file_descriptor_response=reflection_pb2.FileDescriptorResponse(
-          file_descriptor_proto=(
-            _file_descriptor_to_proto(empty_extensions_pb2.DESCRIPTOR),
-          )
-        )
-      ),
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        error_response=reflection_pb2.ErrorResponse(
-          error_code=grpc.StatusCode.NOT_FOUND.value[0],
-          error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
-        )
-      ),
-    )
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testListServices(self):
-    requests = (
-      reflection_pb2.ServerReflectionRequest(
-        list_services='',
-      ),
-    )
-    responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
-    expected_responses = (
-      reflection_pb2.ServerReflectionResponse(
-        valid_host='',
-        list_services_response=reflection_pb2.ListServiceResponse(
-          service=tuple(
-            reflection_pb2.ServiceResponse(name=name)
-            for name in _SERVICE_NAMES
-          )
-        )
-      ),
-    )
-    self.assertSequenceEqual(expected_responses, responses)
+    def setUp(self):
+        servicer = reflection.ReflectionServicer(service_names=_SERVICE_NAMES)
+        server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(server_pool)
+        port = self._server.add_insecure_port('[::]:0')
+        reflection_pb2.add_ServerReflectionServicer_to_server(servicer,
+                                                              self._server)
+        self._server.start()
+
+        channel = grpc.insecure_channel('localhost:%d' % port)
+        self._stub = reflection_pb2.ServerReflectionStub(channel)
+
+    def testFileByName(self):
+        requests = (
+            reflection_pb2.ServerReflectionRequest(
+                file_by_filename=_EMPTY_PROTO_FILE_NAME),
+            reflection_pb2.ServerReflectionRequest(
+                file_by_filename='i-donut-exist'),)
+        responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
+        expected_responses = (
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
+                    file_descriptor_proto=(
+                        _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),))),
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                error_response=reflection_pb2.ErrorResponse(
+                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
+                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
+                )),)
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testFileBySymbol(self):
+        requests = (
+            reflection_pb2.ServerReflectionRequest(
+                file_containing_symbol=_EMPTY_PROTO_SYMBOL_NAME),
+            reflection_pb2.ServerReflectionRequest(
+                file_containing_symbol='i.donut.exist.co.uk.org.net.me.name.foo'
+            ),)
+        responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
+        expected_responses = (
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
+                    file_descriptor_proto=(
+                        _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),))),
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                error_response=reflection_pb2.ErrorResponse(
+                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
+                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
+                )),)
+        self.assertSequenceEqual(expected_responses, responses)
+
+    @unittest.skip(
+        'TODO(atash): implement file-containing-extension reflection '
+        '(see https://github.com/google/protobuf/issues/2248)')
+    def testFileContainingExtension(self):
+        requests = (
+            reflection_pb2.ServerReflectionRequest(
+                file_containing_extension=reflection_pb2.ExtensionRequest(
+                    containing_type='grpc.testing.proto2.Empty',
+                    extension_number=125,),),
+            reflection_pb2.ServerReflectionRequest(
+                file_containing_extension=reflection_pb2.ExtensionRequest(
+                    containing_type='i.donut.exist.co.uk.org.net.me.name.foo',
+                    extension_number=55,),),)
+        responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
+        expected_responses = (
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
+                    file_descriptor_proto=(_file_descriptor_to_proto(
+                        empty_extensions_pb2.DESCRIPTOR),))),
+            reflection_pb2.ServerReflectionResponse(
+                valid_host='',
+                error_response=reflection_pb2.ErrorResponse(
+                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
+                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
+                )),)
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testListServices(self):
+        requests = (reflection_pb2.ServerReflectionRequest(list_services='',),)
+        responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
+        expected_responses = (reflection_pb2.ServerReflectionResponse(
+            valid_host='',
+            list_services_response=reflection_pb2.ListServiceResponse(
+                service=tuple(
+                    reflection_pb2.ServiceResponse(name=name)
+                    for name in _SERVICE_NAMES))),)
+        self.assertSequenceEqual(expected_responses, responses)
+
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py
index b8116729b5..61f9e1c6b1 100644
--- a/src/python/grpcio_tests/tests/stress/client.py
+++ b/src/python/grpcio_tests/tests/stress/client.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Entry point for running stress tests."""
 
 import argparse
@@ -46,118 +45,132 @@ from tests.stress import test_runner
 
 
 def _args():
-  parser = argparse.ArgumentParser(description='gRPC Python stress test client')
-  parser.add_argument(
-      '--server_addresses',
-      help='comma seperated list of hostname:port to run servers on',
-      default='localhost:8080', type=str)
-  parser.add_argument(
-      '--test_cases',
-      help='comma seperated list of testcase:weighting of tests to run',
-      default='large_unary:100',
-      type=str)
-  parser.add_argument(
-      '--test_duration_secs',
-      help='number of seconds to run the stress test',
-      default=-1, type=int)
-  parser.add_argument(
-      '--num_channels_per_server',
-      help='number of channels per server',
-      default=1, type=int)
-  parser.add_argument(
-      '--num_stubs_per_channel',
-      help='number of stubs to create per channel',
-      default=1, type=int)
-  parser.add_argument(
-      '--metrics_port',
-      help='the port to listen for metrics requests on',
-      default=8081, type=int)
-  parser.add_argument(
-      '--use_test_ca',
-      help='Whether to use our fake CA. Requires --use_tls=true',
-      default=False, type=bool)
-  parser.add_argument(
-      '--use_tls',
-      help='Whether to use TLS', default=False, type=bool)
-  parser.add_argument(
-      '--server_host_override', default="foo.test.google.fr",
-      help='the server host to which to claim to connect', type=str)
-  return parser.parse_args()
+    parser = argparse.ArgumentParser(
+        description='gRPC Python stress test client')
+    parser.add_argument(
+        '--server_addresses',
+        help='comma seperated list of hostname:port to run servers on',
+        default='localhost:8080',
+        type=str)
+    parser.add_argument(
+        '--test_cases',
+        help='comma seperated list of testcase:weighting of tests to run',
+        default='large_unary:100',
+        type=str)
+    parser.add_argument(
+        '--test_duration_secs',
+        help='number of seconds to run the stress test',
+        default=-1,
+        type=int)
+    parser.add_argument(
+        '--num_channels_per_server',
+        help='number of channels per server',
+        default=1,
+        type=int)
+    parser.add_argument(
+        '--num_stubs_per_channel',
+        help='number of stubs to create per channel',
+        default=1,
+        type=int)
+    parser.add_argument(
+        '--metrics_port',
+        help='the port to listen for metrics requests on',
+        default=8081,
+        type=int)
+    parser.add_argument(
+        '--use_test_ca',
+        help='Whether to use our fake CA. Requires --use_tls=true',
+        default=False,
+        type=bool)
+    parser.add_argument(
+        '--use_tls', help='Whether to use TLS', default=False, type=bool)
+    parser.add_argument(
+        '--server_host_override',
+        default="foo.test.google.fr",
+        help='the server host to which to claim to connect',
+        type=str)
+    return parser.parse_args()
 
 
 def _test_case_from_arg(test_case_arg):
-  for test_case in methods.TestCase:
-    if test_case_arg == test_case.value:
-      return test_case
-  else:
-    raise ValueError('No test case {}!'.format(test_case_arg))
+    for test_case in methods.TestCase:
+        if test_case_arg == test_case.value:
+            return test_case
+    else:
+        raise ValueError('No test case {}!'.format(test_case_arg))
 
 
 def _parse_weighted_test_cases(test_case_args):
-  weighted_test_cases = {}
-  for test_case_arg in test_case_args.split(','):
-    name, weight = test_case_arg.split(':', 1)
-    test_case = _test_case_from_arg(name)
-    weighted_test_cases[test_case] = int(weight)
-  return weighted_test_cases
+    weighted_test_cases = {}
+    for test_case_arg in test_case_args.split(','):
+        name, weight = test_case_arg.split(':', 1)
+        test_case = _test_case_from_arg(name)
+        weighted_test_cases[test_case] = int(weight)
+    return weighted_test_cases
+
 
 def _get_channel(target, args):
-  if args.use_tls:
-    if args.use_test_ca:
-      root_certificates = resources.test_root_certificates()
+    if args.use_tls:
+        if args.use_test_ca:
+            root_certificates = resources.test_root_certificates()
+        else:
+            root_certificates = None  # will load default roots.
+        channel_credentials = grpc.ssl_channel_credentials(
+            root_certificates=root_certificates)
+        options = ((
+            'grpc.ssl_target_name_override',
+            args.server_host_override,),)
+        channel = grpc.secure_channel(
+            target, channel_credentials, options=options)
     else:
-      root_certificates = None  # will load default roots.
-    channel_credentials = grpc.ssl_channel_credentials(
-        root_certificates=root_certificates)
-    options = (('grpc.ssl_target_name_override', args.server_host_override,),)
-    channel = grpc.secure_channel(target, channel_credentials, options=options)
-  else:
-    channel = grpc.insecure_channel(target)
-
-  # waits for the channel to be ready before we start sending messages
-  grpc.channel_ready_future(channel).result()
-  return channel
+        channel = grpc.insecure_channel(target)
+
+    # waits for the channel to be ready before we start sending messages
+    grpc.channel_ready_future(channel).result()
+    return channel
+
 
 def run_test(args):
-  test_cases = _parse_weighted_test_cases(args.test_cases)
-  test_server_targets = args.server_addresses.split(',')
-  # Propagate any client exceptions with a queue
-  exception_queue = queue.Queue()
-  stop_event = threading.Event()
-  hist = histogram.Histogram(1, 1)
-  runners = []
-
-  server = grpc.server(futures.ThreadPoolExecutor(max_workers=25))
-  metrics_pb2.add_MetricsServiceServicer_to_server(
-      metrics_server.MetricsServer(hist), server)
-  server.add_insecure_port('[::]:{}'.format(args.metrics_port))
-  server.start()
-
-  for test_server_target in test_server_targets:
-    for _ in xrange(args.num_channels_per_server):
-      channel = _get_channel(test_server_target, args)
-      for _ in xrange(args.num_stubs_per_channel):
-        stub = test_pb2.TestServiceStub(channel)
-        runner = test_runner.TestRunner(stub, test_cases, hist,
-                                        exception_queue, stop_event)
-        runners.append(runner)
-
-  for runner in runners:
-    runner.start()
-  try:
-    timeout_secs = args.test_duration_secs
-    if timeout_secs < 0:
-      timeout_secs = None
-    raise exception_queue.get(block=True, timeout=timeout_secs)
-  except queue.Empty:
-    # No exceptions thrown, success
-    pass
-  finally:
-    stop_event.set()
+    test_cases = _parse_weighted_test_cases(args.test_cases)
+    test_server_targets = args.server_addresses.split(',')
+    # Propagate any client exceptions with a queue
+    exception_queue = queue.Queue()
+    stop_event = threading.Event()
+    hist = histogram.Histogram(1, 1)
+    runners = []
+
+    server = grpc.server(futures.ThreadPoolExecutor(max_workers=25))
+    metrics_pb2.add_MetricsServiceServicer_to_server(
+        metrics_server.MetricsServer(hist), server)
+    server.add_insecure_port('[::]:{}'.format(args.metrics_port))
+    server.start()
+
+    for test_server_target in test_server_targets:
+        for _ in xrange(args.num_channels_per_server):
+            channel = _get_channel(test_server_target, args)
+            for _ in xrange(args.num_stubs_per_channel):
+                stub = test_pb2.TestServiceStub(channel)
+                runner = test_runner.TestRunner(stub, test_cases, hist,
+                                                exception_queue, stop_event)
+                runners.append(runner)
+
     for runner in runners:
-      runner.join()
-    runner = None
-    server.stop(None)
+        runner.start()
+    try:
+        timeout_secs = args.test_duration_secs
+        if timeout_secs < 0:
+            timeout_secs = None
+        raise exception_queue.get(block=True, timeout=timeout_secs)
+    except queue.Empty:
+        # No exceptions thrown, success
+        pass
+    finally:
+        stop_event.set()
+        for runner in runners:
+            runner.join()
+        runner = None
+        server.stop(None)
+
 
 if __name__ == '__main__':
-  run_test(_args())
+    run_test(_args())
diff --git a/src/python/grpcio_tests/tests/stress/metrics_server.py b/src/python/grpcio_tests/tests/stress/metrics_server.py
index 33dd1d6f2a..3a4cbc27ba 100644
--- a/src/python/grpcio_tests/tests/stress/metrics_server.py
+++ b/src/python/grpcio_tests/tests/stress/metrics_server.py
@@ -26,7 +26,6 @@
 # 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.
-
 """MetricsService for publishing stress test qps data."""
 
 import time
@@ -38,23 +37,23 @@ GAUGE_NAME = 'python_overall_qps'
 
 class MetricsServer(metrics_pb2.MetricsServiceServicer):
 
-  def __init__(self, histogram):
-    self._start_time = time.time()
-    self._histogram = histogram
-
-  def _get_qps(self):
-    count = self._histogram.get_data().count
-    delta = time.time() - self._start_time
-    self._histogram.reset()
-    self._start_time = time.time()
-    return int(count/delta)
-
-  def GetAllGauges(self, request, context):
-    qps = self._get_qps()
-    return [metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps)]
-
-  def GetGauge(self, request, context):
-    if request.name != GAUGE_NAME:
-      raise Exception('Gauge {} does not exist'.format(request.name))
-    qps = self._get_qps()
-    return metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps)
+    def __init__(self, histogram):
+        self._start_time = time.time()
+        self._histogram = histogram
+
+    def _get_qps(self):
+        count = self._histogram.get_data().count
+        delta = time.time() - self._start_time
+        self._histogram.reset()
+        self._start_time = time.time()
+        return int(count / delta)
+
+    def GetAllGauges(self, request, context):
+        qps = self._get_qps()
+        return [metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps)]
+
+    def GetGauge(self, request, context):
+        if request.name != GAUGE_NAME:
+            raise Exception('Gauge {} does not exist'.format(request.name))
+        qps = self._get_qps()
+        return metrics_pb2.GaugeResponse(name=GAUGE_NAME, long_value=qps)
diff --git a/src/python/grpcio_tests/tests/stress/test_runner.py b/src/python/grpcio_tests/tests/stress/test_runner.py
index 88f13727e3..258abe9c21 100644
--- a/src/python/grpcio_tests/tests/stress/test_runner.py
+++ b/src/python/grpcio_tests/tests/stress/test_runner.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Thread that sends random weighted requests on a TestService stub."""
 
 import random
@@ -36,38 +35,38 @@ import traceback
 
 
 def _weighted_test_case_generator(weighted_cases):
-  weight_sum = sum(weighted_cases.itervalues())
+    weight_sum = sum(weighted_cases.itervalues())
 
-  while True:
-    val = random.uniform(0, weight_sum)
-    partial_sum = 0
-    for case in weighted_cases:
-      partial_sum += weighted_cases[case]
-      if val <= partial_sum:
-        yield case
-        break
+    while True:
+        val = random.uniform(0, weight_sum)
+        partial_sum = 0
+        for case in weighted_cases:
+            partial_sum += weighted_cases[case]
+            if val <= partial_sum:
+                yield case
+                break
 
 
 class TestRunner(threading.Thread):
 
-  def __init__(self, stub, test_cases, hist, exception_queue, stop_event):
-    super(TestRunner, self).__init__()
-    self._exception_queue = exception_queue
-    self._stop_event = stop_event
-    self._stub = stub
-    self._test_cases = _weighted_test_case_generator(test_cases)
-    self._histogram = hist
+    def __init__(self, stub, test_cases, hist, exception_queue, stop_event):
+        super(TestRunner, self).__init__()
+        self._exception_queue = exception_queue
+        self._stop_event = stop_event
+        self._stub = stub
+        self._test_cases = _weighted_test_case_generator(test_cases)
+        self._histogram = hist
 
-  def run(self):
-    while not self._stop_event.is_set():
-      try:
-        test_case = next(self._test_cases)
-        start_time = time.time()
-        test_case.test_interoperability(self._stub, None)
-        end_time = time.time()
-        self._histogram.add((end_time - start_time)*1e9)
-      except Exception as e:
-        traceback.print_exc()
-        self._exception_queue.put(
-            Exception("An exception occured during test {}"
-                      .format(test_case), e))
+    def run(self):
+        while not self._stop_event.is_set():
+            try:
+                test_case = next(self._test_cases)
+                start_time = time.time()
+                test_case.test_interoperability(self._stub, None)
+                end_time = time.time()
+                self._histogram.add((end_time - start_time) * 1e9)
+            except Exception as e:
+                traceback.print_exc()
+                self._exception_queue.put(
+                    Exception("An exception occured during test {}"
+                              .format(test_case), e))
diff --git a/src/python/grpcio_tests/tests/unit/__init__.py b/src/python/grpcio_tests/tests/unit/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py
index 51dc425420..5435c5500c 100644
--- a/src/python/grpcio_tests/tests/unit/_api_test.py
+++ b/src/python/grpcio_tests/tests/unit/_api_test.py
@@ -26,7 +26,6 @@
 # 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 of gRPC Python's application-layer API."""
 
 import unittest
@@ -40,73 +39,71 @@ from tests.unit import _from_grpc_import_star
 
 class AllTest(unittest.TestCase):
 
-  def testAll(self):
-    expected_grpc_code_elements = (
-        'FutureTimeoutError',
-        'FutureCancelledError',
-        'Future',
-        'ChannelConnectivity',
-        'StatusCode',
-        'RpcError',
-        'RpcContext',
-        'Call',
-        'ChannelCredentials',
-        'CallCredentials',
-        'AuthMetadataContext',
-        'AuthMetadataPluginCallback',
-        'AuthMetadataPlugin',
-        'ServerCredentials',
-        'UnaryUnaryMultiCallable',
-        'UnaryStreamMultiCallable',
-        'StreamUnaryMultiCallable',
-        'StreamStreamMultiCallable',
-        'Channel',
-        'ServicerContext',
-        'RpcMethodHandler',
-        'HandlerCallDetails',
-        'GenericRpcHandler',
-        'ServiceRpcHandler',
-        'Server',
-        'unary_unary_rpc_method_handler',
-        'unary_stream_rpc_method_handler',
-        'stream_unary_rpc_method_handler',
-        'stream_stream_rpc_method_handler',
-        'method_handlers_generic_handler',
-        'ssl_channel_credentials',
-        'metadata_call_credentials',
-        'access_token_call_credentials',
-        'composite_call_credentials',
-        'composite_channel_credentials',
-        'ssl_server_credentials',
-        'channel_ready_future',
-        'insecure_channel',
-        'secure_channel',
-        'server',
-    )
-
-    six.assertCountEqual(
-        self, expected_grpc_code_elements,
-        _from_grpc_import_star.GRPC_ELEMENTS)
+    def testAll(self):
+        expected_grpc_code_elements = (
+            'FutureTimeoutError',
+            'FutureCancelledError',
+            'Future',
+            'ChannelConnectivity',
+            'StatusCode',
+            'RpcError',
+            'RpcContext',
+            'Call',
+            'ChannelCredentials',
+            'CallCredentials',
+            'AuthMetadataContext',
+            'AuthMetadataPluginCallback',
+            'AuthMetadataPlugin',
+            'ServerCredentials',
+            'UnaryUnaryMultiCallable',
+            'UnaryStreamMultiCallable',
+            'StreamUnaryMultiCallable',
+            'StreamStreamMultiCallable',
+            'Channel',
+            'ServicerContext',
+            'RpcMethodHandler',
+            'HandlerCallDetails',
+            'GenericRpcHandler',
+            'ServiceRpcHandler',
+            'Server',
+            'unary_unary_rpc_method_handler',
+            'unary_stream_rpc_method_handler',
+            'stream_unary_rpc_method_handler',
+            'stream_stream_rpc_method_handler',
+            'method_handlers_generic_handler',
+            'ssl_channel_credentials',
+            'metadata_call_credentials',
+            'access_token_call_credentials',
+            'composite_call_credentials',
+            'composite_channel_credentials',
+            'ssl_server_credentials',
+            'channel_ready_future',
+            'insecure_channel',
+            'secure_channel',
+            'server',)
+
+        six.assertCountEqual(self, expected_grpc_code_elements,
+                             _from_grpc_import_star.GRPC_ELEMENTS)
 
 
 class ChannelConnectivityTest(unittest.TestCase):
 
-  def testChannelConnectivity(self):
-    self.assertSequenceEqual(
-        (grpc.ChannelConnectivity.IDLE,
-         grpc.ChannelConnectivity.CONNECTING,
-         grpc.ChannelConnectivity.READY,
-         grpc.ChannelConnectivity.TRANSIENT_FAILURE,
-         grpc.ChannelConnectivity.SHUTDOWN,),
-        tuple(grpc.ChannelConnectivity))
+    def testChannelConnectivity(self):
+        self.assertSequenceEqual((
+            grpc.ChannelConnectivity.IDLE,
+            grpc.ChannelConnectivity.CONNECTING,
+            grpc.ChannelConnectivity.READY,
+            grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+            grpc.ChannelConnectivity.SHUTDOWN,),
+                                 tuple(grpc.ChannelConnectivity))
 
 
 class ChannelTest(unittest.TestCase):
 
-  def test_secure_channel(self):
-    channel_credentials = grpc.ssl_channel_credentials()
-    channel = grpc.secure_channel('google.com:443', channel_credentials)
+    def test_secure_channel(self):
+        channel_credentials = grpc.ssl_channel_credentials()
+        channel = grpc.secure_channel('google.com:443', channel_credentials)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_auth_test.py b/src/python/grpcio_tests/tests/unit/_auth_test.py
index c31f7b06f7..52bd1cb7ba 100644
--- a/src/python/grpcio_tests/tests/unit/_auth_test.py
+++ b/src/python/grpcio_tests/tests/unit/_auth_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of standard AuthMetadataPlugins."""
 
 import collections
@@ -38,59 +37,59 @@ from grpc import _auth
 
 class MockGoogleCreds(object):
 
-  def get_access_token(self):
-    token = collections.namedtuple('MockAccessTokenInfo',
-                                   ('access_token', 'expires_in'))
-    token.access_token = 'token'
-    return token
+    def get_access_token(self):
+        token = collections.namedtuple('MockAccessTokenInfo',
+                                       ('access_token', 'expires_in'))
+        token.access_token = 'token'
+        return token
 
 
 class MockExceptionGoogleCreds(object):
 
-  def get_access_token(self):
-    raise Exception()
+    def get_access_token(self):
+        raise Exception()
 
 
 class GoogleCallCredentialsTest(unittest.TestCase):
 
-  def test_google_call_credentials_success(self):
-    callback_event = threading.Event()
+    def test_google_call_credentials_success(self):
+        callback_event = threading.Event()
 
-    def mock_callback(metadata, error):
-      self.assertEqual(metadata, (('authorization', 'Bearer token'),))
-      self.assertIsNone(error)
-      callback_event.set()
+        def mock_callback(metadata, error):
+            self.assertEqual(metadata, (('authorization', 'Bearer token'),))
+            self.assertIsNone(error)
+            callback_event.set()
 
-    call_creds = _auth.GoogleCallCredentials(MockGoogleCreds())
-    call_creds(None, mock_callback)
-    self.assertTrue(callback_event.wait(1.0))
+        call_creds = _auth.GoogleCallCredentials(MockGoogleCreds())
+        call_creds(None, mock_callback)
+        self.assertTrue(callback_event.wait(1.0))
 
-  def test_google_call_credentials_error(self):
-    callback_event = threading.Event()
+    def test_google_call_credentials_error(self):
+        callback_event = threading.Event()
 
-    def mock_callback(metadata, error):
-      self.assertIsNotNone(error)
-      callback_event.set()
+        def mock_callback(metadata, error):
+            self.assertIsNotNone(error)
+            callback_event.set()
 
-    call_creds = _auth.GoogleCallCredentials(MockExceptionGoogleCreds())
-    call_creds(None, mock_callback)
-    self.assertTrue(callback_event.wait(1.0))
+        call_creds = _auth.GoogleCallCredentials(MockExceptionGoogleCreds())
+        call_creds(None, mock_callback)
+        self.assertTrue(callback_event.wait(1.0))
 
 
 class AccessTokenCallCredentialsTest(unittest.TestCase):
 
-  def test_google_call_credentials_success(self):
-    callback_event = threading.Event()
+    def test_google_call_credentials_success(self):
+        callback_event = threading.Event()
 
-    def mock_callback(metadata, error):
-      self.assertEqual(metadata, (('authorization', 'Bearer token'),))
-      self.assertIsNone(error)
-      callback_event.set()
+        def mock_callback(metadata, error):
+            self.assertEqual(metadata, (('authorization', 'Bearer token'),))
+            self.assertIsNone(error)
+            callback_event.set()
 
-    call_creds = _auth.AccessTokenCallCredentials('token')
-    call_creds(None, mock_callback)
-    self.assertTrue(callback_event.wait(1.0))
+        call_creds = _auth.AccessTokenCallCredentials('token')
+        call_creds(None, mock_callback)
+        self.assertTrue(callback_event.wait(1.0))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_args_test.py b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
index b46497afd6..845db777a4 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_args_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
@@ -26,17 +26,17 @@
 # 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.
-
 """Tests of Channel Args on client/server side."""
 
 import unittest
 
 import grpc
 
+
 class TestPointerWrapper(object):
 
-  def __int__(self):
-    return 123456
+    def __int__(self):
+        return 123456
 
 
 TEST_CHANNEL_ARGS = (
@@ -44,17 +44,17 @@ TEST_CHANNEL_ARGS = (
     ('arg2', 'str_val'),
     ('arg3', 1),
     (b'arg4', 'str_val'),
-    ('arg6', TestPointerWrapper()),
-)
+    ('arg6', TestPointerWrapper()),)
 
 
 class ChannelArgsTest(unittest.TestCase):
 
-  def test_client(self):
-    grpc.insecure_channel('localhost:8080', options=TEST_CHANNEL_ARGS)
+    def test_client(self):
+        grpc.insecure_channel('localhost:8080', options=TEST_CHANNEL_ARGS)
+
+    def test_server(self):
+        grpc.server(None, options=TEST_CHANNEL_ARGS)
 
-  def test_server(self):
-    grpc.server(None, options=TEST_CHANNEL_ARGS)
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
index 3d9dd17ff6..d67693154b 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc._channel.Channel connectivity."""
 
 import threading
@@ -39,125 +38,123 @@ from tests.unit import _thread_pool
 
 
 def _ready_in_connectivities(connectivities):
-  return grpc.ChannelConnectivity.READY in connectivities
+    return grpc.ChannelConnectivity.READY in connectivities
 
 
 def _last_connectivity_is_not_ready(connectivities):
-  return connectivities[-1] is not grpc.ChannelConnectivity.READY
+    return connectivities[-1] is not grpc.ChannelConnectivity.READY
 
 
 class _Callback(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._connectivities = []
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._connectivities = []
 
-  def update(self, connectivity):
-    with self._condition:
-      self._connectivities.append(connectivity)
-      self._condition.notify()
+    def update(self, connectivity):
+        with self._condition:
+            self._connectivities.append(connectivity)
+            self._condition.notify()
 
-  def connectivities(self):
-    with self._condition:
-      return tuple(self._connectivities)
+    def connectivities(self):
+        with self._condition:
+            return tuple(self._connectivities)
 
-  def block_until_connectivities_satisfy(self, predicate):
-    with self._condition:
-      while True:
-        connectivities = tuple(self._connectivities)
-        if predicate(connectivities):
-          return connectivities
-        else:
-          self._condition.wait()
+    def block_until_connectivities_satisfy(self, predicate):
+        with self._condition:
+            while True:
+                connectivities = tuple(self._connectivities)
+                if predicate(connectivities):
+                    return connectivities
+                else:
+                    self._condition.wait()
 
 
 class ChannelConnectivityTest(unittest.TestCase):
 
-  def test_lonely_channel_connectivity(self):
-    callback = _Callback()
-
-    channel = grpc.insecure_channel('localhost:12345')
-    channel.subscribe(callback.update, try_to_connect=False)
-    first_connectivities = callback.block_until_connectivities_satisfy(bool)
-    channel.subscribe(callback.update, try_to_connect=True)
-    second_connectivities = callback.block_until_connectivities_satisfy(
-        lambda connectivities: 2 <= len(connectivities))
-    # Wait for a connection that will never happen.
-    time.sleep(test_constants.SHORT_TIMEOUT)
-    third_connectivities = callback.connectivities()
-    channel.unsubscribe(callback.update)
-    fourth_connectivities = callback.connectivities()
-    channel.unsubscribe(callback.update)
-    fifth_connectivities = callback.connectivities()
-
-    self.assertSequenceEqual(
-        (grpc.ChannelConnectivity.IDLE,), first_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.READY, second_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.READY, third_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.READY, fourth_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.READY, fifth_connectivities)
-
-  def test_immediately_connectable_channel_connectivity(self):
-    thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
-    server = grpc.server(thread_pool)
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    first_callback = _Callback()
-    second_callback = _Callback()
-
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    channel.subscribe(first_callback.update, try_to_connect=False)
-    first_connectivities = first_callback.block_until_connectivities_satisfy(
-        bool)
-    # Wait for a connection that will never happen because try_to_connect=True
-    # has not yet been passed.
-    time.sleep(test_constants.SHORT_TIMEOUT)
-    second_connectivities = first_callback.connectivities()
-    channel.subscribe(second_callback.update, try_to_connect=True)
-    third_connectivities = first_callback.block_until_connectivities_satisfy(
-        lambda connectivities: 2 <= len(connectivities))
-    fourth_connectivities = second_callback.block_until_connectivities_satisfy(
-        bool)
-    # Wait for a connection that will happen (or may already have happened).
-    first_callback.block_until_connectivities_satisfy(_ready_in_connectivities)
-    second_callback.block_until_connectivities_satisfy(_ready_in_connectivities)
-    del channel
-
-    self.assertSequenceEqual(
-        (grpc.ChannelConnectivity.IDLE,), first_connectivities)
-    self.assertSequenceEqual(
-        (grpc.ChannelConnectivity.IDLE,), second_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.TRANSIENT_FAILURE, third_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.SHUTDOWN, third_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.TRANSIENT_FAILURE,
-        fourth_connectivities)
-    self.assertNotIn(
-        grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities)
-    self.assertFalse(thread_pool.was_used())
-
-  def test_reachable_then_unreachable_channel_connectivity(self):
-    thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
-    server = grpc.server(thread_pool)
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    callback = _Callback()
-
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    channel.subscribe(callback.update, try_to_connect=True)
-    callback.block_until_connectivities_satisfy(_ready_in_connectivities)
-    # Now take down the server and confirm that channel readiness is repudiated.
-    server.stop(None)
-    callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready)
-    channel.unsubscribe(callback.update)
-    self.assertFalse(thread_pool.was_used())
+    def test_lonely_channel_connectivity(self):
+        callback = _Callback()
+
+        channel = grpc.insecure_channel('localhost:12345')
+        channel.subscribe(callback.update, try_to_connect=False)
+        first_connectivities = callback.block_until_connectivities_satisfy(bool)
+        channel.subscribe(callback.update, try_to_connect=True)
+        second_connectivities = callback.block_until_connectivities_satisfy(
+            lambda connectivities: 2 <= len(connectivities))
+        # Wait for a connection that will never happen.
+        time.sleep(test_constants.SHORT_TIMEOUT)
+        third_connectivities = callback.connectivities()
+        channel.unsubscribe(callback.update)
+        fourth_connectivities = callback.connectivities()
+        channel.unsubscribe(callback.update)
+        fifth_connectivities = callback.connectivities()
+
+        self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,),
+                                 first_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.READY, second_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.READY, third_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.READY, fourth_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.READY, fifth_connectivities)
+
+    def test_immediately_connectable_channel_connectivity(self):
+        thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
+        server = grpc.server(thread_pool)
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        first_callback = _Callback()
+        second_callback = _Callback()
+
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        channel.subscribe(first_callback.update, try_to_connect=False)
+        first_connectivities = first_callback.block_until_connectivities_satisfy(
+            bool)
+        # Wait for a connection that will never happen because try_to_connect=True
+        # has not yet been passed.
+        time.sleep(test_constants.SHORT_TIMEOUT)
+        second_connectivities = first_callback.connectivities()
+        channel.subscribe(second_callback.update, try_to_connect=True)
+        third_connectivities = first_callback.block_until_connectivities_satisfy(
+            lambda connectivities: 2 <= len(connectivities))
+        fourth_connectivities = second_callback.block_until_connectivities_satisfy(
+            bool)
+        # Wait for a connection that will happen (or may already have happened).
+        first_callback.block_until_connectivities_satisfy(
+            _ready_in_connectivities)
+        second_callback.block_until_connectivities_satisfy(
+            _ready_in_connectivities)
+        del channel
+
+        self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,),
+                                 first_connectivities)
+        self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,),
+                                 second_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+                         third_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.SHUTDOWN,
+                         third_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+                         fourth_connectivities)
+        self.assertNotIn(grpc.ChannelConnectivity.SHUTDOWN,
+                         fourth_connectivities)
+        self.assertFalse(thread_pool.was_used())
+
+    def test_reachable_then_unreachable_channel_connectivity(self):
+        thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
+        server = grpc.server(thread_pool)
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        callback = _Callback()
+
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        channel.subscribe(callback.update, try_to_connect=True)
+        callback.block_until_connectivities_satisfy(_ready_in_connectivities)
+        # Now take down the server and confirm that channel readiness is repudiated.
+        server.stop(None)
+        callback.block_until_connectivities_satisfy(
+            _last_connectivity_is_not_ready)
+        channel.unsubscribe(callback.update)
+        self.assertFalse(thread_pool.was_used())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
index 46a964db8c..2d1b63e15f 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc.channel_ready_future."""
 
 import threading
@@ -39,65 +38,66 @@ from tests.unit import _thread_pool
 
 class _Callback(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._value = None
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._value = None
 
-  def accept_value(self, value):
-    with self._condition:
-      self._value = value
-      self._condition.notify_all()
+    def accept_value(self, value):
+        with self._condition:
+            self._value = value
+            self._condition.notify_all()
 
-  def block_until_called(self):
-    with self._condition:
-      while self._value is None:
-        self._condition.wait()
-      return self._value
+    def block_until_called(self):
+        with self._condition:
+            while self._value is None:
+                self._condition.wait()
+            return self._value
 
 
 class ChannelReadyFutureTest(unittest.TestCase):
 
-  def test_lonely_channel_connectivity(self):
-    channel = grpc.insecure_channel('localhost:12345')
-    callback = _Callback()
-
-    ready_future = grpc.channel_ready_future(channel)
-    ready_future.add_done_callback(callback.accept_value)
-    with self.assertRaises(grpc.FutureTimeoutError):
-      ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
-    self.assertFalse(ready_future.cancelled())
-    self.assertFalse(ready_future.done())
-    self.assertTrue(ready_future.running())
-    ready_future.cancel()
-    value_passed_to_callback = callback.block_until_called()
-    self.assertIs(ready_future, value_passed_to_callback)
-    self.assertTrue(ready_future.cancelled())
-    self.assertTrue(ready_future.done())
-    self.assertFalse(ready_future.running())
-
-  def test_immediately_connectable_channel_connectivity(self):
-    thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
-    server = grpc.server(thread_pool)
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    callback = _Callback()
-
-    ready_future = grpc.channel_ready_future(channel)
-    ready_future.add_done_callback(callback.accept_value)
-    self.assertIsNone(ready_future.result(timeout=test_constants.LONG_TIMEOUT))
-    value_passed_to_callback = callback.block_until_called()
-    self.assertIs(ready_future, value_passed_to_callback)
-    self.assertFalse(ready_future.cancelled())
-    self.assertTrue(ready_future.done())
-    self.assertFalse(ready_future.running())
-    # Cancellation after maturity has no effect.
-    ready_future.cancel()
-    self.assertFalse(ready_future.cancelled())
-    self.assertTrue(ready_future.done())
-    self.assertFalse(ready_future.running())
-    self.assertFalse(thread_pool.was_used())
+    def test_lonely_channel_connectivity(self):
+        channel = grpc.insecure_channel('localhost:12345')
+        callback = _Callback()
+
+        ready_future = grpc.channel_ready_future(channel)
+        ready_future.add_done_callback(callback.accept_value)
+        with self.assertRaises(grpc.FutureTimeoutError):
+            ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
+        self.assertFalse(ready_future.cancelled())
+        self.assertFalse(ready_future.done())
+        self.assertTrue(ready_future.running())
+        ready_future.cancel()
+        value_passed_to_callback = callback.block_until_called()
+        self.assertIs(ready_future, value_passed_to_callback)
+        self.assertTrue(ready_future.cancelled())
+        self.assertTrue(ready_future.done())
+        self.assertFalse(ready_future.running())
+
+    def test_immediately_connectable_channel_connectivity(self):
+        thread_pool = _thread_pool.RecordingThreadPool(max_workers=None)
+        server = grpc.server(thread_pool)
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        callback = _Callback()
+
+        ready_future = grpc.channel_ready_future(channel)
+        ready_future.add_done_callback(callback.accept_value)
+        self.assertIsNone(
+            ready_future.result(timeout=test_constants.LONG_TIMEOUT))
+        value_passed_to_callback = callback.block_until_called()
+        self.assertIs(ready_future, value_passed_to_callback)
+        self.assertFalse(ready_future.cancelled())
+        self.assertTrue(ready_future.done())
+        self.assertFalse(ready_future.running())
+        # Cancellation after maturity has no effect.
+        ready_future.cancel()
+        self.assertFalse(ready_future.cancelled())
+        self.assertTrue(ready_future.done())
+        self.assertFalse(ready_future.running())
+        self.assertFalse(thread_pool.was_used())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 4d3f02e917..7dd944e600 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -42,93 +42,96 @@ _STREAM_STREAM = '/test/StreamStream'
 
 
 def handle_unary(request, servicer_context):
-  servicer_context.send_initial_metadata([
-    ('grpc-internal-encoding-request', 'gzip')])
-  return request
+    servicer_context.send_initial_metadata(
+        [('grpc-internal-encoding-request', 'gzip')])
+    return request
 
 
 def handle_stream(request_iterator, servicer_context):
-  # TODO(issue:#6891) We should be able to remove this loop,
-  # and replace with return; yield
-  servicer_context.send_initial_metadata([
-    ('grpc-internal-encoding-request', 'gzip')])
-  for request in request_iterator:
-    yield request
+    # TODO(issue:#6891) We should be able to remove this loop,
+    # and replace with return; yield
+    servicer_context.send_initial_metadata(
+        [('grpc-internal-encoding-request', 'gzip')])
+    for request in request_iterator:
+        yield request
 
 
 class _MethodHandler(grpc.RpcMethodHandler):
 
-  def __init__(self, request_streaming, response_streaming):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = None
-    self.response_serializer = None
-    self.unary_unary = None
-    self.unary_stream = None
-    self.stream_unary = None
-    self.stream_stream = None
-    if self.request_streaming and self.response_streaming:
-      self.stream_stream = lambda x, y: handle_stream(x, y)
-    elif not self.request_streaming and not self.response_streaming:
-      self.unary_unary = lambda x, y: handle_unary(x, y)
+    def __init__(self, request_streaming, response_streaming):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = None
+        self.response_serializer = None
+        self.unary_unary = None
+        self.unary_stream = None
+        self.stream_unary = None
+        self.stream_stream = None
+        if self.request_streaming and self.response_streaming:
+            self.stream_stream = lambda x, y: handle_stream(x, y)
+        elif not self.request_streaming and not self.response_streaming:
+            self.unary_unary = lambda x, y: handle_unary(x, y)
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
 
-  def service(self, handler_call_details):
-    if handler_call_details.method == _UNARY_UNARY:
-      return _MethodHandler(False, False)
-    elif handler_call_details.method == _STREAM_STREAM:
-      return _MethodHandler(True, True)
-    else:
-      return None
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(False, False)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(True, True)
+        else:
+            return None
 
 
 class CompressionTest(unittest.TestCase):
 
-  def setUp(self):
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(
-        self._server_pool, handlers=(_GenericHandler(),))
-    self._port = self._server.add_insecure_port('[::]:0')
-    self._server.start()
-
-  def testUnary(self):
-    request = b'\x00' * 100
-
-    # Client -> server compressed through default client channel compression
-    # settings. Server -> client compressed via server-side metadata setting.
-    # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
-    # literal with proper use of the public API.
-    compressed_channel = grpc.insecure_channel('localhost:%d' % self._port,
-        options=[('grpc.default_compression_algorithm', 1)])
-    multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
-    response = multi_callable(request)
-    self.assertEqual(request, response)
-
-    # Client -> server compressed through client metadata setting. Server ->
-    # client compressed via server-side metadata setting.
-    # TODO(https://github.com/grpc/grpc/issues/4078): replace the "0" integer
-    # literal with proper use of the public API.
-    uncompressed_channel = grpc.insecure_channel('localhost:%d' % self._port,
-        options=[('grpc.default_compression_algorithm', 0)])
-    multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
-    response = multi_callable(request, metadata=[
-      ('grpc-internal-encoding-request', 'gzip')])
-    self.assertEqual(request, response)
-
-  def testStreaming(self):
-    request = b'\x00' * 100
-
-    # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
-    # literal with proper use of the public API.
-    compressed_channel = grpc.insecure_channel('localhost:%d' % self._port,
-        options=[('grpc.default_compression_algorithm', 1)])
-    multi_callable = compressed_channel.stream_stream(_STREAM_STREAM)
-    call = multi_callable(iter([request] * test_constants.STREAM_LENGTH))
-    for response in call:
-      self.assertEqual(request, response)
+    def setUp(self):
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(
+            self._server_pool, handlers=(_GenericHandler(),))
+        self._port = self._server.add_insecure_port('[::]:0')
+        self._server.start()
+
+    def testUnary(self):
+        request = b'\x00' * 100
+
+        # Client -> server compressed through default client channel compression
+        # settings. Server -> client compressed via server-side metadata setting.
+        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
+        # literal with proper use of the public API.
+        compressed_channel = grpc.insecure_channel(
+            'localhost:%d' % self._port,
+            options=[('grpc.default_compression_algorithm', 1)])
+        multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
+        response = multi_callable(request)
+        self.assertEqual(request, response)
+
+        # Client -> server compressed through client metadata setting. Server ->
+        # client compressed via server-side metadata setting.
+        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "0" integer
+        # literal with proper use of the public API.
+        uncompressed_channel = grpc.insecure_channel(
+            'localhost:%d' % self._port,
+            options=[('grpc.default_compression_algorithm', 0)])
+        multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
+        response = multi_callable(
+            request, metadata=[('grpc-internal-encoding-request', 'gzip')])
+        self.assertEqual(request, response)
+
+    def testStreaming(self):
+        request = b'\x00' * 100
+
+        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
+        # literal with proper use of the public API.
+        compressed_channel = grpc.insecure_channel(
+            'localhost:%d' % self._port,
+            options=[('grpc.default_compression_algorithm', 1)])
+        multi_callable = compressed_channel.stream_stream(_STREAM_STREAM)
+        call = multi_callable(iter([request] * test_constants.STREAM_LENGTH))
+        for response in call:
+            self.assertEqual(request, response)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py
index 87af85a0b9..21bf29789a 100644
--- a/src/python/grpcio_tests/tests/unit/_credentials_test.py
+++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of credentials."""
 
 import unittest
@@ -36,37 +35,38 @@ import grpc
 
 class CredentialsTest(unittest.TestCase):
 
-  def test_call_credentials_composition(self):
-    first = grpc.access_token_call_credentials('abc')
-    second = grpc.access_token_call_credentials('def')
-    third = grpc.access_token_call_credentials('ghi')
+    def test_call_credentials_composition(self):
+        first = grpc.access_token_call_credentials('abc')
+        second = grpc.access_token_call_credentials('def')
+        third = grpc.access_token_call_credentials('ghi')
+
+        first_and_second = grpc.composite_call_credentials(first, second)
+        first_second_and_third = grpc.composite_call_credentials(first, second,
+                                                                 third)
 
-    first_and_second = grpc.composite_call_credentials(first, second)
-    first_second_and_third = grpc.composite_call_credentials(
-        first, second, third)
-    
-    self.assertIsInstance(first_and_second, grpc.CallCredentials)
-    self.assertIsInstance(first_second_and_third, grpc.CallCredentials)
+        self.assertIsInstance(first_and_second, grpc.CallCredentials)
+        self.assertIsInstance(first_second_and_third, grpc.CallCredentials)
 
-  def test_channel_credentials_composition(self):
-    first_call_credentials = grpc.access_token_call_credentials('abc')
-    second_call_credentials = grpc.access_token_call_credentials('def')
-    third_call_credentials = grpc.access_token_call_credentials('ghi')
-    channel_credentials = grpc.ssl_channel_credentials()
+    def test_channel_credentials_composition(self):
+        first_call_credentials = grpc.access_token_call_credentials('abc')
+        second_call_credentials = grpc.access_token_call_credentials('def')
+        third_call_credentials = grpc.access_token_call_credentials('ghi')
+        channel_credentials = grpc.ssl_channel_credentials()
 
-    channel_and_first = grpc.composite_channel_credentials(
-        channel_credentials, first_call_credentials)
-    channel_first_and_second = grpc.composite_channel_credentials(
-        channel_credentials, first_call_credentials, second_call_credentials)
-    channel_first_second_and_third = grpc.composite_channel_credentials(
-        channel_credentials, first_call_credentials, second_call_credentials,
-        third_call_credentials)
+        channel_and_first = grpc.composite_channel_credentials(
+            channel_credentials, first_call_credentials)
+        channel_first_and_second = grpc.composite_channel_credentials(
+            channel_credentials, first_call_credentials,
+            second_call_credentials)
+        channel_first_second_and_third = grpc.composite_channel_credentials(
+            channel_credentials, first_call_credentials,
+            second_call_credentials, third_call_credentials)
 
-    self.assertIsInstance(channel_and_first, grpc.ChannelCredentials)
-    self.assertIsInstance(channel_first_and_second, grpc.ChannelCredentials)
-    self.assertIsInstance(
-        channel_first_second_and_third, grpc.ChannelCredentials)
+        self.assertIsInstance(channel_and_first, grpc.ChannelCredentials)
+        self.assertIsInstance(channel_first_and_second, grpc.ChannelCredentials)
+        self.assertIsInstance(channel_first_second_and_third,
+                              grpc.ChannelCredentials)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
index 20115fb22c..d77f5ecb27 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
@@ -26,7 +26,6 @@
 # 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 making many calls and immediately cancelling most of them."""
 
 import threading
@@ -51,173 +50,178 @@ _SUCCESS_CALL_FRACTION = 1.0 / 8.0
 
 class _State(object):
 
-  def __init__(self):
-    self.condition = threading.Condition()
-    self.handlers_released = False
-    self.parked_handlers = 0
-    self.handled_rpcs = 0
+    def __init__(self):
+        self.condition = threading.Condition()
+        self.handlers_released = False
+        self.parked_handlers = 0
+        self.handled_rpcs = 0
 
 
 def _is_cancellation_event(event):
-  return (
-      event.tag is _RECEIVE_CLOSE_ON_SERVER_TAG and
-      event.batch_operations[0].received_cancelled)
+    return (event.tag is _RECEIVE_CLOSE_ON_SERVER_TAG and
+            event.batch_operations[0].received_cancelled)
 
 
 class _Handler(object):
 
-  def __init__(self, state, completion_queue, rpc_event):
-    self._state = state
-    self._lock = threading.Lock()
-    self._completion_queue = completion_queue
-    self._call = rpc_event.operation_call
-
-  def __call__(self):
-    with self._state.condition:
-      self._state.parked_handlers += 1
-      if self._state.parked_handlers == test_constants.THREAD_CONCURRENCY:
-        self._state.condition.notify_all()
-      while not self._state.handlers_released:
-        self._state.condition.wait()
-
-    with self._lock:
-      self._call.start_server_batch(
-          cygrpc.Operations(
-              (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
-          _RECEIVE_CLOSE_ON_SERVER_TAG)
-      self._call.start_server_batch(
-          cygrpc.Operations((cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
-          _RECEIVE_MESSAGE_TAG)
-    first_event = self._completion_queue.poll()
-    if _is_cancellation_event(first_event):
-      self._completion_queue.poll()
-    else:
-      with self._lock:
-        operations = (
-            cygrpc.operation_send_initial_metadata(
-                _EMPTY_METADATA, _EMPTY_FLAGS),
-            cygrpc.operation_send_message(b'\x79\x57', _EMPTY_FLAGS),
-            cygrpc.operation_send_status_from_server(
-                _EMPTY_METADATA, cygrpc.StatusCode.ok, b'test details!',
-                _EMPTY_FLAGS),
-        )
-        self._call.start_server_batch(
-            cygrpc.Operations(operations), _SERVER_COMPLETE_CALL_TAG)
-      self._completion_queue.poll()
-      self._completion_queue.poll()
+    def __init__(self, state, completion_queue, rpc_event):
+        self._state = state
+        self._lock = threading.Lock()
+        self._completion_queue = completion_queue
+        self._call = rpc_event.operation_call
+
+    def __call__(self):
+        with self._state.condition:
+            self._state.parked_handlers += 1
+            if self._state.parked_handlers == test_constants.THREAD_CONCURRENCY:
+                self._state.condition.notify_all()
+            while not self._state.handlers_released:
+                self._state.condition.wait()
+
+        with self._lock:
+            self._call.start_server_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
+                _RECEIVE_CLOSE_ON_SERVER_TAG)
+            self._call.start_server_batch(
+                cygrpc.Operations(
+                    (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+                _RECEIVE_MESSAGE_TAG)
+        first_event = self._completion_queue.poll()
+        if _is_cancellation_event(first_event):
+            self._completion_queue.poll()
+        else:
+            with self._lock:
+                operations = (
+                    cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                           _EMPTY_FLAGS),
+                    cygrpc.operation_send_message(b'\x79\x57', _EMPTY_FLAGS),
+                    cygrpc.operation_send_status_from_server(
+                        _EMPTY_METADATA, cygrpc.StatusCode.ok, b'test details!',
+                        _EMPTY_FLAGS),)
+                self._call.start_server_batch(
+                    cygrpc.Operations(operations), _SERVER_COMPLETE_CALL_TAG)
+            self._completion_queue.poll()
+            self._completion_queue.poll()
 
 
 def _serve(state, server, server_completion_queue, thread_pool):
-  for _ in range(test_constants.RPC_CONCURRENCY):
-    call_completion_queue = cygrpc.CompletionQueue()
-    server.request_call(
-        call_completion_queue, server_completion_queue, _REQUEST_CALL_TAG)
-    rpc_event = server_completion_queue.poll()
-    thread_pool.submit(_Handler(state, call_completion_queue, rpc_event))
-    with state.condition:
-      state.handled_rpcs += 1
-      if test_constants.RPC_CONCURRENCY <= state.handled_rpcs:
-        state.condition.notify_all()
-  server_completion_queue.poll()
+    for _ in range(test_constants.RPC_CONCURRENCY):
+        call_completion_queue = cygrpc.CompletionQueue()
+        server.request_call(call_completion_queue, server_completion_queue,
+                            _REQUEST_CALL_TAG)
+        rpc_event = server_completion_queue.poll()
+        thread_pool.submit(_Handler(state, call_completion_queue, rpc_event))
+        with state.condition:
+            state.handled_rpcs += 1
+            if test_constants.RPC_CONCURRENCY <= state.handled_rpcs:
+                state.condition.notify_all()
+    server_completion_queue.poll()
 
 
 class _QueueDriver(object):
 
-  def __init__(self, condition, completion_queue, due):
-    self._condition = condition
-    self._completion_queue = completion_queue
-    self._due = due
-    self._events = []
-    self._returned = False
-
-  def start(self):
-    def in_thread():
-      while True:
-        event = self._completion_queue.poll()
+    def __init__(self, condition, completion_queue, due):
+        self._condition = condition
+        self._completion_queue = completion_queue
+        self._due = due
+        self._events = []
+        self._returned = False
+
+    def start(self):
+
+        def in_thread():
+            while True:
+                event = self._completion_queue.poll()
+                with self._condition:
+                    self._events.append(event)
+                    self._due.remove(event.tag)
+                    self._condition.notify_all()
+                    if not self._due:
+                        self._returned = True
+                        return
+
+        thread = threading.Thread(target=in_thread)
+        thread.start()
+
+    def events(self, at_least):
         with self._condition:
-          self._events.append(event)
-          self._due.remove(event.tag)
-          self._condition.notify_all()
-          if not self._due:
-            self._returned = True
-            return
-    thread = threading.Thread(target=in_thread)
-    thread.start()
-
-  def events(self, at_least):
-    with self._condition:
-      while len(self._events) < at_least:
-        self._condition.wait()
-      return tuple(self._events)
+            while len(self._events) < at_least:
+                self._condition.wait()
+            return tuple(self._events)
 
 
 class CancelManyCallsTest(unittest.TestCase):
 
-  def testCancelManyCalls(self):
-    server_thread_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-
-    server_completion_queue = cygrpc.CompletionQueue()
-    server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    server.register_completion_queue(server_completion_queue)
-    port = server.add_http2_port(b'[::]:0')
-    server.start()
-    channel = cygrpc.Channel('localhost:{}'.format(port).encode(),
-                             cygrpc.ChannelArgs([]))
-
-    state = _State()
-
-    server_thread_args = (
-        state, server, server_completion_queue, server_thread_pool,)
-    server_thread = threading.Thread(target=_serve, args=server_thread_args)
-    server_thread.start()
-
-    client_condition = threading.Condition()
-    client_due = set()
-    client_completion_queue = cygrpc.CompletionQueue()
-    client_driver = _QueueDriver(
-        client_condition, client_completion_queue, client_due)
-    client_driver.start()
-
-    with client_condition:
-      client_calls = []
-      for index in range(test_constants.RPC_CONCURRENCY):
-        client_call = channel.create_call(
-            None, _EMPTY_FLAGS, client_completion_queue, b'/twinkies', None,
-            _INFINITE_FUTURE)
-        operations = (
-            cygrpc.operation_send_initial_metadata(
-                _EMPTY_METADATA, _EMPTY_FLAGS),
-            cygrpc.operation_send_message(b'\x45\x56', _EMPTY_FLAGS),
-            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-            cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
-            cygrpc.operation_receive_message(_EMPTY_FLAGS),
-            cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-        )
-        tag = 'client_complete_call_{0:04d}_tag'.format(index)
-        client_call.start_client_batch(cygrpc.Operations(operations), tag)
-        client_due.add(tag)
-        client_calls.append(client_call)
-
-    with state.condition:
-      while True:
-        if state.parked_handlers < test_constants.THREAD_CONCURRENCY:
-          state.condition.wait()
-        elif state.handled_rpcs < test_constants.RPC_CONCURRENCY:
-          state.condition.wait()
-        else:
-          state.handlers_released = True
-          state.condition.notify_all()
-          break
-
-    client_driver.events(
-        test_constants.RPC_CONCURRENCY * _SUCCESS_CALL_FRACTION)
-    with client_condition:
-      for client_call in client_calls:
-        client_call.cancel()
-
-    with state.condition:
-      server.shutdown(server_completion_queue, _SERVER_SHUTDOWN_TAG)
+    def testCancelManyCalls(self):
+        server_thread_pool = logging_pool.pool(
+            test_constants.THREAD_CONCURRENCY)
+
+        server_completion_queue = cygrpc.CompletionQueue()
+        server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        server.register_completion_queue(server_completion_queue)
+        port = server.add_http2_port(b'[::]:0')
+        server.start()
+        channel = cygrpc.Channel('localhost:{}'.format(port).encode(),
+                                 cygrpc.ChannelArgs([]))
+
+        state = _State()
+
+        server_thread_args = (
+            state,
+            server,
+            server_completion_queue,
+            server_thread_pool,)
+        server_thread = threading.Thread(target=_serve, args=server_thread_args)
+        server_thread.start()
+
+        client_condition = threading.Condition()
+        client_due = set()
+        client_completion_queue = cygrpc.CompletionQueue()
+        client_driver = _QueueDriver(client_condition, client_completion_queue,
+                                     client_due)
+        client_driver.start()
+
+        with client_condition:
+            client_calls = []
+            for index in range(test_constants.RPC_CONCURRENCY):
+                client_call = channel.create_call(
+                    None, _EMPTY_FLAGS, client_completion_queue, b'/twinkies',
+                    None, _INFINITE_FUTURE)
+                operations = (
+                    cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                           _EMPTY_FLAGS),
+                    cygrpc.operation_send_message(b'\x45\x56', _EMPTY_FLAGS),
+                    cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+                    cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+                    cygrpc.operation_receive_message(_EMPTY_FLAGS),
+                    cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+                tag = 'client_complete_call_{0:04d}_tag'.format(index)
+                client_call.start_client_batch(
+                    cygrpc.Operations(operations), tag)
+                client_due.add(tag)
+                client_calls.append(client_call)
+
+        with state.condition:
+            while True:
+                if state.parked_handlers < test_constants.THREAD_CONCURRENCY:
+                    state.condition.wait()
+                elif state.handled_rpcs < test_constants.RPC_CONCURRENCY:
+                    state.condition.wait()
+                else:
+                    state.handlers_released = True
+                    state.condition.notify_all()
+                    break
+
+        client_driver.events(test_constants.RPC_CONCURRENCY *
+                             _SUCCESS_CALL_FRACTION)
+        with client_condition:
+            for client_call in client_calls:
+                client_call.cancel()
+
+        with state.condition:
+            server.shutdown(server_completion_queue, _SERVER_SHUTDOWN_TAG)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
index f9c8a3ac62..0ca06868b2 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py
@@ -37,46 +37,49 @@ from tests.unit.framework.common import test_constants
 
 
 def _channel_and_completion_queue():
-  channel = cygrpc.Channel(b'localhost:54321', cygrpc.ChannelArgs(()))
-  completion_queue = cygrpc.CompletionQueue()
-  return channel, completion_queue
+    channel = cygrpc.Channel(b'localhost:54321', cygrpc.ChannelArgs(()))
+    completion_queue = cygrpc.CompletionQueue()
+    return channel, completion_queue
 
 
 def _connectivity_loop(channel, completion_queue):
-  for _ in range(100):
-    connectivity = channel.check_connectivity_state(True)
-    channel.watch_connectivity_state(
-        connectivity, cygrpc.Timespec(time.time() + 0.2), completion_queue,
-        None)
-    completion_queue.poll(deadline=cygrpc.Timespec(float('+inf')))
+    for _ in range(100):
+        connectivity = channel.check_connectivity_state(True)
+        channel.watch_connectivity_state(connectivity,
+                                         cygrpc.Timespec(time.time() + 0.2),
+                                         completion_queue, None)
+        completion_queue.poll(deadline=cygrpc.Timespec(float('+inf')))
 
 
 def _create_loop_destroy():
-  channel, completion_queue = _channel_and_completion_queue()
-  _connectivity_loop(channel, completion_queue)
-  completion_queue.shutdown()
+    channel, completion_queue = _channel_and_completion_queue()
+    _connectivity_loop(channel, completion_queue)
+    completion_queue.shutdown()
 
 
 def _in_parallel(behavior, arguments):
-  threads = tuple(
-      threading.Thread(target=behavior, args=arguments)
-      for _ in range(test_constants.THREAD_CONCURRENCY))
-  for thread in threads:
-    thread.start()
-  for thread in threads:
-    thread.join()
+    threads = tuple(
+        threading.Thread(
+            target=behavior, args=arguments)
+        for _ in range(test_constants.THREAD_CONCURRENCY))
+    for thread in threads:
+        thread.start()
+    for thread in threads:
+        thread.join()
 
 
 class ChannelTest(unittest.TestCase):
 
-  def test_single_channel_lonely_connectivity(self):
-    channel, completion_queue = _channel_and_completion_queue()
-    _in_parallel(_connectivity_loop, (channel, completion_queue,))
-    completion_queue.shutdown()
+    def test_single_channel_lonely_connectivity(self):
+        channel, completion_queue = _channel_and_completion_queue()
+        _in_parallel(_connectivity_loop, (
+            channel,
+            completion_queue,))
+        completion_queue.shutdown()
 
-  def test_multiple_channels_lonely_connectivity(self):
-    _in_parallel(_create_loop_destroy, ())
+    def test_multiple_channels_lonely_connectivity(self):
+        _in_parallel(_create_loop_destroy, ())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
index 2ae5285232..9fbfcbb9c0 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
@@ -26,7 +26,6 @@
 # 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 a corner-case at the level of the Cython API."""
 
 import threading
@@ -41,212 +40,221 @@ _EMPTY_METADATA = cygrpc.Metadata(())
 
 class _ServerDriver(object):
 
-  def __init__(self, completion_queue, shutdown_tag):
-    self._condition = threading.Condition()
-    self._completion_queue = completion_queue
-    self._shutdown_tag = shutdown_tag
-    self._events = []
-    self._saw_shutdown_tag = False
-
-  def start(self):
-    def in_thread():
-      while True:
-        event = self._completion_queue.poll()
+    def __init__(self, completion_queue, shutdown_tag):
+        self._condition = threading.Condition()
+        self._completion_queue = completion_queue
+        self._shutdown_tag = shutdown_tag
+        self._events = []
+        self._saw_shutdown_tag = False
+
+    def start(self):
+
+        def in_thread():
+            while True:
+                event = self._completion_queue.poll()
+                with self._condition:
+                    self._events.append(event)
+                    self._condition.notify()
+                    if event.tag is self._shutdown_tag:
+                        self._saw_shutdown_tag = True
+                        break
+
+        thread = threading.Thread(target=in_thread)
+        thread.start()
+
+    def done(self):
+        with self._condition:
+            return self._saw_shutdown_tag
+
+    def first_event(self):
+        with self._condition:
+            while not self._events:
+                self._condition.wait()
+            return self._events[0]
+
+    def events(self):
         with self._condition:
-          self._events.append(event)
-          self._condition.notify()
-          if event.tag is self._shutdown_tag:
-            self._saw_shutdown_tag = True
-            break
-    thread = threading.Thread(target=in_thread)
-    thread.start()
-
-  def done(self):
-    with self._condition:
-      return self._saw_shutdown_tag
-
-  def first_event(self):
-    with self._condition:
-      while not self._events:
-        self._condition.wait()
-      return self._events[0]
-
-  def events(self):
-    with self._condition:
-      while not self._saw_shutdown_tag:
-        self._condition.wait()
-      return tuple(self._events)
+            while not self._saw_shutdown_tag:
+                self._condition.wait()
+            return tuple(self._events)
 
 
 class _QueueDriver(object):
 
-  def __init__(self, condition, completion_queue, due):
-    self._condition = condition
-    self._completion_queue = completion_queue
-    self._due = due
-    self._events = []
-    self._returned = False
-
-  def start(self):
-    def in_thread():
-      while True:
-        event = self._completion_queue.poll()
+    def __init__(self, condition, completion_queue, due):
+        self._condition = condition
+        self._completion_queue = completion_queue
+        self._due = due
+        self._events = []
+        self._returned = False
+
+    def start(self):
+
+        def in_thread():
+            while True:
+                event = self._completion_queue.poll()
+                with self._condition:
+                    self._events.append(event)
+                    self._due.remove(event.tag)
+                    self._condition.notify_all()
+                    if not self._due:
+                        self._returned = True
+                        return
+
+        thread = threading.Thread(target=in_thread)
+        thread.start()
+
+    def done(self):
+        with self._condition:
+            return self._returned
+
+    def event_with_tag(self, tag):
+        with self._condition:
+            while True:
+                for event in self._events:
+                    if event.tag is tag:
+                        return event
+                self._condition.wait()
+
+    def events(self):
         with self._condition:
-          self._events.append(event)
-          self._due.remove(event.tag)
-          self._condition.notify_all()
-          if not self._due:
-            self._returned = True
-            return
-    thread = threading.Thread(target=in_thread)
-    thread.start()
-
-  def done(self):
-    with self._condition:
-      return self._returned
-
-  def event_with_tag(self, tag):
-    with self._condition:
-      while True:
-        for event in self._events:
-          if event.tag is tag:
-            return event
-        self._condition.wait()
-
-  def events(self):
-    with self._condition:
-      while not self._returned:
-        self._condition.wait()
-      return tuple(self._events)
+            while not self._returned:
+                self._condition.wait()
+            return tuple(self._events)
 
 
 class ReadSomeButNotAllResponsesTest(unittest.TestCase):
 
-  def testReadSomeButNotAllResponses(self):
-    server_completion_queue = cygrpc.CompletionQueue()
-    server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    server.register_completion_queue(server_completion_queue)
-    port = server.add_http2_port(b'[::]:0')
-    server.start()
-    channel = cygrpc.Channel('localhost:{}'.format(port).encode(),
-                             cygrpc.ChannelArgs([]))
-
-    server_shutdown_tag = 'server_shutdown_tag'
-    server_driver = _ServerDriver(server_completion_queue, server_shutdown_tag)
-    server_driver.start()
-
-    client_condition = threading.Condition()
-    client_due = set()
-    client_completion_queue = cygrpc.CompletionQueue()
-    client_driver = _QueueDriver(
-        client_condition, client_completion_queue, client_due)
-    client_driver.start()
-
-    server_call_condition = threading.Condition()
-    server_send_initial_metadata_tag = 'server_send_initial_metadata_tag'
-    server_send_first_message_tag = 'server_send_first_message_tag'
-    server_send_second_message_tag = 'server_send_second_message_tag'
-    server_complete_rpc_tag = 'server_complete_rpc_tag'
-    server_call_due = set((
-        server_send_initial_metadata_tag,
-        server_send_first_message_tag,
-        server_send_second_message_tag,
-        server_complete_rpc_tag,
-    ))
-    server_call_completion_queue = cygrpc.CompletionQueue()
-    server_call_driver = _QueueDriver(
-        server_call_condition, server_call_completion_queue, server_call_due)
-    server_call_driver.start()
-
-    server_rpc_tag = 'server_rpc_tag'
-    request_call_result = server.request_call(
-        server_call_completion_queue, server_completion_queue, server_rpc_tag)
-
-    client_call = channel.create_call(
-        None, _EMPTY_FLAGS, client_completion_queue, b'/twinkies', None,
-        _INFINITE_FUTURE)
-    client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
-    client_complete_rpc_tag = 'client_complete_rpc_tag'
-    with client_condition:
-      client_receive_initial_metadata_start_batch_result = (
-          client_call.start_client_batch(cygrpc.Operations([
-              cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
-          ]), client_receive_initial_metadata_tag))
-      client_due.add(client_receive_initial_metadata_tag)
-      client_complete_rpc_start_batch_result = (
-          client_call.start_client_batch(cygrpc.Operations([
-              cygrpc.operation_send_initial_metadata(
-                  _EMPTY_METADATA, _EMPTY_FLAGS),
-              cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-              cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
-          ]), client_complete_rpc_tag))
-      client_due.add(client_complete_rpc_tag)
-
-    server_rpc_event = server_driver.first_event()
-
-    with server_call_condition:
-      server_send_initial_metadata_start_batch_result = (
-          server_rpc_event.operation_call.start_server_batch([
-              cygrpc.operation_send_initial_metadata(
-                  _EMPTY_METADATA, _EMPTY_FLAGS),
-          ], server_send_initial_metadata_tag))
-      server_send_first_message_start_batch_result = (
-          server_rpc_event.operation_call.start_server_batch([
-              cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
-          ], server_send_first_message_tag))
-    server_send_initial_metadata_event = server_call_driver.event_with_tag(
-        server_send_initial_metadata_tag)
-    server_send_first_message_event = server_call_driver.event_with_tag(
-        server_send_first_message_tag)
-    with server_call_condition:
-      server_send_second_message_start_batch_result = (
-          server_rpc_event.operation_call.start_server_batch([
-              cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
-          ], server_send_second_message_tag))
-      server_complete_rpc_start_batch_result = (
-          server_rpc_event.operation_call.start_server_batch([
-              cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
-              cygrpc.operation_send_status_from_server(
-                  cygrpc.Metadata(()), cygrpc.StatusCode.ok, b'test details',
-                  _EMPTY_FLAGS),
-          ], server_complete_rpc_tag))
-    server_send_second_message_event = server_call_driver.event_with_tag(
-        server_send_second_message_tag)
-    server_complete_rpc_event = server_call_driver.event_with_tag(
-        server_complete_rpc_tag)
-    server_call_driver.events()
-
-    with client_condition:
-      client_receive_first_message_tag = 'client_receive_first_message_tag'
-      client_receive_first_message_start_batch_result = (
-          client_call.start_client_batch(cygrpc.Operations([
-              cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          ]), client_receive_first_message_tag))
-      client_due.add(client_receive_first_message_tag)
-    client_receive_first_message_event = client_driver.event_with_tag(
-        client_receive_first_message_tag)
-
-    client_call_cancel_result = client_call.cancel()
-    client_driver.events()
-
-    server.shutdown(server_completion_queue, server_shutdown_tag)
-    server.cancel_all_calls()
-    server_driver.events()
-
-    self.assertEqual(cygrpc.CallError.ok, request_call_result)
-    self.assertEqual(
-        cygrpc.CallError.ok, server_send_initial_metadata_start_batch_result)
-    self.assertEqual(
-        cygrpc.CallError.ok, client_receive_initial_metadata_start_batch_result)
-    self.assertEqual(
-        cygrpc.CallError.ok, client_complete_rpc_start_batch_result)
-    self.assertEqual(cygrpc.CallError.ok, client_call_cancel_result)
-    self.assertIs(server_rpc_tag, server_rpc_event.tag)
-    self.assertEqual(
-        cygrpc.CompletionType.operation_complete, server_rpc_event.type)
-    self.assertIsInstance(server_rpc_event.operation_call, cygrpc.Call)
-    self.assertEqual(0, len(server_rpc_event.batch_operations))
+    def testReadSomeButNotAllResponses(self):
+        server_completion_queue = cygrpc.CompletionQueue()
+        server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        server.register_completion_queue(server_completion_queue)
+        port = server.add_http2_port(b'[::]:0')
+        server.start()
+        channel = cygrpc.Channel('localhost:{}'.format(port).encode(),
+                                 cygrpc.ChannelArgs([]))
+
+        server_shutdown_tag = 'server_shutdown_tag'
+        server_driver = _ServerDriver(server_completion_queue,
+                                      server_shutdown_tag)
+        server_driver.start()
+
+        client_condition = threading.Condition()
+        client_due = set()
+        client_completion_queue = cygrpc.CompletionQueue()
+        client_driver = _QueueDriver(client_condition, client_completion_queue,
+                                     client_due)
+        client_driver.start()
+
+        server_call_condition = threading.Condition()
+        server_send_initial_metadata_tag = 'server_send_initial_metadata_tag'
+        server_send_first_message_tag = 'server_send_first_message_tag'
+        server_send_second_message_tag = 'server_send_second_message_tag'
+        server_complete_rpc_tag = 'server_complete_rpc_tag'
+        server_call_due = set((
+            server_send_initial_metadata_tag,
+            server_send_first_message_tag,
+            server_send_second_message_tag,
+            server_complete_rpc_tag,))
+        server_call_completion_queue = cygrpc.CompletionQueue()
+        server_call_driver = _QueueDriver(server_call_condition,
+                                          server_call_completion_queue,
+                                          server_call_due)
+        server_call_driver.start()
+
+        server_rpc_tag = 'server_rpc_tag'
+        request_call_result = server.request_call(server_call_completion_queue,
+                                                  server_completion_queue,
+                                                  server_rpc_tag)
+
+        client_call = channel.create_call(None, _EMPTY_FLAGS,
+                                          client_completion_queue, b'/twinkies',
+                                          None, _INFINITE_FUTURE)
+        client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
+        client_complete_rpc_tag = 'client_complete_rpc_tag'
+        with client_condition:
+            client_receive_initial_metadata_start_batch_result = (
+                client_call.start_client_batch(
+                    cygrpc.Operations([
+                        cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+                    ]), client_receive_initial_metadata_tag))
+            client_due.add(client_receive_initial_metadata_tag)
+            client_complete_rpc_start_batch_result = (
+                client_call.start_client_batch(
+                    cygrpc.Operations([
+                        cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                               _EMPTY_FLAGS),
+                        cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+                        cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+                    ]), client_complete_rpc_tag))
+            client_due.add(client_complete_rpc_tag)
+
+        server_rpc_event = server_driver.first_event()
+
+        with server_call_condition:
+            server_send_initial_metadata_start_batch_result = (
+                server_rpc_event.operation_call.start_server_batch([
+                    cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+                                                           _EMPTY_FLAGS),
+                ], server_send_initial_metadata_tag))
+            server_send_first_message_start_batch_result = (
+                server_rpc_event.operation_call.start_server_batch([
+                    cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
+                ], server_send_first_message_tag))
+        server_send_initial_metadata_event = server_call_driver.event_with_tag(
+            server_send_initial_metadata_tag)
+        server_send_first_message_event = server_call_driver.event_with_tag(
+            server_send_first_message_tag)
+        with server_call_condition:
+            server_send_second_message_start_batch_result = (
+                server_rpc_event.operation_call.start_server_batch([
+                    cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
+                ], server_send_second_message_tag))
+            server_complete_rpc_start_batch_result = (
+                server_rpc_event.operation_call.start_server_batch([
+                    cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+                    cygrpc.operation_send_status_from_server(
+                        cygrpc.Metadata(()), cygrpc.StatusCode.ok,
+                        b'test details', _EMPTY_FLAGS),
+                ], server_complete_rpc_tag))
+        server_send_second_message_event = server_call_driver.event_with_tag(
+            server_send_second_message_tag)
+        server_complete_rpc_event = server_call_driver.event_with_tag(
+            server_complete_rpc_tag)
+        server_call_driver.events()
+
+        with client_condition:
+            client_receive_first_message_tag = 'client_receive_first_message_tag'
+            client_receive_first_message_start_batch_result = (
+                client_call.start_client_batch(
+                    cygrpc.Operations([
+                        cygrpc.operation_receive_message(_EMPTY_FLAGS),
+                    ]), client_receive_first_message_tag))
+            client_due.add(client_receive_first_message_tag)
+        client_receive_first_message_event = client_driver.event_with_tag(
+            client_receive_first_message_tag)
+
+        client_call_cancel_result = client_call.cancel()
+        client_driver.events()
+
+        server.shutdown(server_completion_queue, server_shutdown_tag)
+        server.cancel_all_calls()
+        server_driver.events()
+
+        self.assertEqual(cygrpc.CallError.ok, request_call_result)
+        self.assertEqual(cygrpc.CallError.ok,
+                         server_send_initial_metadata_start_batch_result)
+        self.assertEqual(cygrpc.CallError.ok,
+                         client_receive_initial_metadata_start_batch_result)
+        self.assertEqual(cygrpc.CallError.ok,
+                         client_complete_rpc_start_batch_result)
+        self.assertEqual(cygrpc.CallError.ok, client_call_cancel_result)
+        self.assertIs(server_rpc_tag, server_rpc_event.tag)
+        self.assertEqual(cygrpc.CompletionType.operation_complete,
+                         server_rpc_event.type)
+        self.assertIsInstance(server_rpc_event.operation_call, cygrpc.Call)
+        self.assertEqual(0, len(server_rpc_event.batch_operations))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
index 8dedebfabe..7aec316b95 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
@@ -37,399 +37,421 @@ from tests.unit._cython import test_utilities
 from tests.unit import test_common
 from tests.unit import resources
 
-
 _SSL_HOST_OVERRIDE = b'foo.test.google.fr'
 _CALL_CREDENTIALS_METADATA_KEY = 'call-creds-key'
 _CALL_CREDENTIALS_METADATA_VALUE = 'call-creds-value'
 _EMPTY_FLAGS = 0
 
+
 def _metadata_plugin_callback(context, callback):
-  callback(cygrpc.Metadata(
-      [cygrpc.Metadatum(_CALL_CREDENTIALS_METADATA_KEY,
-                        _CALL_CREDENTIALS_METADATA_VALUE)]),
-      cygrpc.StatusCode.ok, b'')
+    callback(
+        cygrpc.Metadata([
+            cygrpc.Metadatum(_CALL_CREDENTIALS_METADATA_KEY,
+                             _CALL_CREDENTIALS_METADATA_VALUE)
+        ]), cygrpc.StatusCode.ok, b'')
 
 
 class TypeSmokeTest(unittest.TestCase):
 
-  def testStringsInUtilitiesUpDown(self):
-    self.assertEqual(0, cygrpc.StatusCode.ok)
-    metadatum = cygrpc.Metadatum(b'a', b'b')
-    self.assertEqual(b'a', metadatum.key)
-    self.assertEqual(b'b', metadatum.value)
-    metadata = cygrpc.Metadata([metadatum])
-    self.assertEqual(1, len(metadata))
-    self.assertEqual(metadatum.key, metadata[0].key)
-
-  def testMetadataIteration(self):
-    metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(b'a', b'b'), cygrpc.Metadatum(b'c', b'd')])
-    iterator = iter(metadata)
-    metadatum = next(iterator)
-    self.assertIsInstance(metadatum, cygrpc.Metadatum)
-    self.assertEqual(metadatum.key, b'a')
-    self.assertEqual(metadatum.value, b'b')
-    metadatum = next(iterator)
-    self.assertIsInstance(metadatum, cygrpc.Metadatum)
-    self.assertEqual(metadatum.key, b'c')
-    self.assertEqual(metadatum.value, b'd')
-    with self.assertRaises(StopIteration):
-      next(iterator)
-
-  def testOperationsIteration(self):
-    operations = cygrpc.Operations([
-        cygrpc.operation_send_message(b'asdf', _EMPTY_FLAGS)])
-    iterator = iter(operations)
-    operation = next(iterator)
-    self.assertIsInstance(operation, cygrpc.Operation)
-    # `Operation`s are write-only structures; can't directly debug anything out
-    # of them. Just check that we stop iterating.
-    with self.assertRaises(StopIteration):
-      next(iterator)
-
-  def testOperationFlags(self):
-    operation = cygrpc.operation_send_message(b'asdf',
-                                              cygrpc.WriteFlag.no_compress)
-    self.assertEqual(cygrpc.WriteFlag.no_compress, operation.flags)
-
-  def testTimespec(self):
-    now = time.time()
-    timespec = cygrpc.Timespec(now)
-    self.assertAlmostEqual(now, float(timespec), places=8)
-
-  def testCompletionQueueUpDown(self):
-    completion_queue = cygrpc.CompletionQueue()
-    del completion_queue
-
-  def testServerUpDown(self):
-    server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    del server
-
-  def testChannelUpDown(self):
-    channel = cygrpc.Channel(b'[::]:0', cygrpc.ChannelArgs([]))
-    del channel
-
-  def testCredentialsMetadataPluginUpDown(self):
-    plugin = cygrpc.CredentialsMetadataPlugin(
-        lambda ignored_a, ignored_b: None, b'')
-    del plugin
-
-  def testCallCredentialsFromPluginUpDown(self):
-    plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'')
-    call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
-    del plugin
-    del call_credentials
-
-  def testServerStartNoExplicitShutdown(self):
-    server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    completion_queue = cygrpc.CompletionQueue()
-    server.register_completion_queue(completion_queue)
-    port = server.add_http2_port(b'[::]:0')
-    self.assertIsInstance(port, int)
-    server.start()
-    del server
-
-  def testServerStartShutdown(self):
-    completion_queue = cygrpc.CompletionQueue()
-    server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    server.add_http2_port(b'[::]:0')
-    server.register_completion_queue(completion_queue)
-    server.start()
-    shutdown_tag = object()
-    server.shutdown(completion_queue, shutdown_tag)
-    event = completion_queue.poll()
-    self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
-    self.assertIs(shutdown_tag, event.tag)
-    del server
-    del completion_queue
+    def testStringsInUtilitiesUpDown(self):
+        self.assertEqual(0, cygrpc.StatusCode.ok)
+        metadatum = cygrpc.Metadatum(b'a', b'b')
+        self.assertEqual(b'a', metadatum.key)
+        self.assertEqual(b'b', metadatum.value)
+        metadata = cygrpc.Metadata([metadatum])
+        self.assertEqual(1, len(metadata))
+        self.assertEqual(metadatum.key, metadata[0].key)
+
+    def testMetadataIteration(self):
+        metadata = cygrpc.Metadata(
+            [cygrpc.Metadatum(b'a', b'b'), cygrpc.Metadatum(b'c', b'd')])
+        iterator = iter(metadata)
+        metadatum = next(iterator)
+        self.assertIsInstance(metadatum, cygrpc.Metadatum)
+        self.assertEqual(metadatum.key, b'a')
+        self.assertEqual(metadatum.value, b'b')
+        metadatum = next(iterator)
+        self.assertIsInstance(metadatum, cygrpc.Metadatum)
+        self.assertEqual(metadatum.key, b'c')
+        self.assertEqual(metadatum.value, b'd')
+        with self.assertRaises(StopIteration):
+            next(iterator)
+
+    def testOperationsIteration(self):
+        operations = cygrpc.Operations(
+            [cygrpc.operation_send_message(b'asdf', _EMPTY_FLAGS)])
+        iterator = iter(operations)
+        operation = next(iterator)
+        self.assertIsInstance(operation, cygrpc.Operation)
+        # `Operation`s are write-only structures; can't directly debug anything out
+        # of them. Just check that we stop iterating.
+        with self.assertRaises(StopIteration):
+            next(iterator)
+
+    def testOperationFlags(self):
+        operation = cygrpc.operation_send_message(b'asdf',
+                                                  cygrpc.WriteFlag.no_compress)
+        self.assertEqual(cygrpc.WriteFlag.no_compress, operation.flags)
+
+    def testTimespec(self):
+        now = time.time()
+        timespec = cygrpc.Timespec(now)
+        self.assertAlmostEqual(now, float(timespec), places=8)
+
+    def testCompletionQueueUpDown(self):
+        completion_queue = cygrpc.CompletionQueue()
+        del completion_queue
+
+    def testServerUpDown(self):
+        server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        del server
+
+    def testChannelUpDown(self):
+        channel = cygrpc.Channel(b'[::]:0', cygrpc.ChannelArgs([]))
+        del channel
+
+    def testCredentialsMetadataPluginUpDown(self):
+        plugin = cygrpc.CredentialsMetadataPlugin(
+            lambda ignored_a, ignored_b: None, b'')
+        del plugin
+
+    def testCallCredentialsFromPluginUpDown(self):
+        plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback,
+                                                  b'')
+        call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
+        del plugin
+        del call_credentials
+
+    def testServerStartNoExplicitShutdown(self):
+        server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        completion_queue = cygrpc.CompletionQueue()
+        server.register_completion_queue(completion_queue)
+        port = server.add_http2_port(b'[::]:0')
+        self.assertIsInstance(port, int)
+        server.start()
+        del server
+
+    def testServerStartShutdown(self):
+        completion_queue = cygrpc.CompletionQueue()
+        server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        server.add_http2_port(b'[::]:0')
+        server.register_completion_queue(completion_queue)
+        server.start()
+        shutdown_tag = object()
+        server.shutdown(completion_queue, shutdown_tag)
+        event = completion_queue.poll()
+        self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
+        self.assertIs(shutdown_tag, event.tag)
+        del server
+        del completion_queue
 
 
 class ServerClientMixin(object):
 
-  def setUpMixin(self, server_credentials, client_credentials, host_override):
-    self.server_completion_queue = cygrpc.CompletionQueue()
-    self.server = cygrpc.Server(cygrpc.ChannelArgs([]))
-    self.server.register_completion_queue(self.server_completion_queue)
-    if server_credentials:
-      self.port = self.server.add_http2_port(b'[::]:0', server_credentials)
-    else:
-      self.port = self.server.add_http2_port(b'[::]:0')
-    self.server.start()
-    self.client_completion_queue = cygrpc.CompletionQueue()
-    if client_credentials:
-      client_channel_arguments = cygrpc.ChannelArgs([
-          cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
-                            host_override)])
-      self.client_channel = cygrpc.Channel(
-          'localhost:{}'.format(self.port).encode(), client_channel_arguments,
-          client_credentials)
-    else:
-      self.client_channel = cygrpc.Channel(
-          'localhost:{}'.format(self.port).encode(), cygrpc.ChannelArgs([]))
-    if host_override:
-      self.host_argument = None  # default host
-      self.expected_host = host_override
-    else:
-      # arbitrary host name necessitating no further identification
-      self.host_argument = b'hostess'
-      self.expected_host = self.host_argument
-
-  def tearDownMixin(self):
-    del self.server
-    del self.client_completion_queue
-    del self.server_completion_queue
-
-  def _perform_operations(self, operations, call, queue, deadline, description):
-    """Perform the list of operations with given call, queue, and deadline.
+    def setUpMixin(self, server_credentials, client_credentials, host_override):
+        self.server_completion_queue = cygrpc.CompletionQueue()
+        self.server = cygrpc.Server(cygrpc.ChannelArgs([]))
+        self.server.register_completion_queue(self.server_completion_queue)
+        if server_credentials:
+            self.port = self.server.add_http2_port(b'[::]:0',
+                                                   server_credentials)
+        else:
+            self.port = self.server.add_http2_port(b'[::]:0')
+        self.server.start()
+        self.client_completion_queue = cygrpc.CompletionQueue()
+        if client_credentials:
+            client_channel_arguments = cygrpc.ChannelArgs([
+                cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
+                                  host_override)
+            ])
+            self.client_channel = cygrpc.Channel(
+                'localhost:{}'.format(self.port).encode(),
+                client_channel_arguments, client_credentials)
+        else:
+            self.client_channel = cygrpc.Channel(
+                'localhost:{}'.format(self.port).encode(),
+                cygrpc.ChannelArgs([]))
+        if host_override:
+            self.host_argument = None  # default host
+            self.expected_host = host_override
+        else:
+            # arbitrary host name necessitating no further identification
+            self.host_argument = b'hostess'
+            self.expected_host = self.host_argument
+
+    def tearDownMixin(self):
+        del self.server
+        del self.client_completion_queue
+        del self.server_completion_queue
+
+    def _perform_operations(self, operations, call, queue, deadline,
+                            description):
+        """Perform the list of operations with given call, queue, and deadline.
 
     Invocation errors are reported with as an exception with `description` in
     the message. Performs the operations asynchronously, returning a future.
     """
-    def performer():
-      tag = object()
-      try:
-        call_result = call.start_client_batch(
-            cygrpc.Operations(operations), tag)
-        self.assertEqual(cygrpc.CallError.ok, call_result)
-        event = queue.poll(deadline)
-        self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
-        self.assertTrue(event.success)
-        self.assertIs(tag, event.tag)
-      except Exception as error:
-        raise Exception("Error in '{}': {}".format(description, error.message))
-      return event
-    return test_utilities.SimpleFuture(performer)
-
-  def testEcho(self):
-    DEADLINE = time.time()+5
-    DEADLINE_TOLERANCE = 0.25
-    CLIENT_METADATA_ASCII_KEY = b'key'
-    CLIENT_METADATA_ASCII_VALUE = b'val'
-    CLIENT_METADATA_BIN_KEY = b'key-bin'
-    CLIENT_METADATA_BIN_VALUE = b'\0'*1000
-    SERVER_INITIAL_METADATA_KEY = b'init_me_me_me'
-    SERVER_INITIAL_METADATA_VALUE = b'whodawha?'
-    SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought'
-    SERVER_TRAILING_METADATA_VALUE = b'zomg it is'
-    SERVER_STATUS_CODE = cygrpc.StatusCode.ok
-    SERVER_STATUS_DETAILS = b'our work is never over'
-    REQUEST = b'in death a member of project mayhem has a name'
-    RESPONSE = b'his name is robert paulson'
-    METHOD = b'twinkies'
-
-    cygrpc_deadline = cygrpc.Timespec(DEADLINE)
-
-    server_request_tag = object()
-    request_call_result = self.server.request_call(
-        self.server_completion_queue, self.server_completion_queue,
-        server_request_tag)
-
-    self.assertEqual(cygrpc.CallError.ok, request_call_result)
-
-    client_call_tag = object()
-    client_call = self.client_channel.create_call(
-        None, 0, self.client_completion_queue, METHOD, self.host_argument,
-        cygrpc_deadline)
-    client_initial_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
-                         CLIENT_METADATA_ASCII_VALUE),
-        cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)])
-    client_start_batch_result = client_call.start_client_batch([
-        cygrpc.operation_send_initial_metadata(client_initial_metadata,
-                                               _EMPTY_FLAGS),
-        cygrpc.operation_send_message(REQUEST, _EMPTY_FLAGS),
-        cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-        cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
-        cygrpc.operation_receive_message(_EMPTY_FLAGS),
-        cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
-    ], client_call_tag)
-    self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
-    client_event_future = test_utilities.CompletionQueuePollFuture(
-        self.client_completion_queue, cygrpc_deadline)
-
-    request_event = self.server_completion_queue.poll(cygrpc_deadline)
-    self.assertEqual(cygrpc.CompletionType.operation_complete,
-                      request_event.type)
-    self.assertIsInstance(request_event.operation_call, cygrpc.Call)
-    self.assertIs(server_request_tag, request_event.tag)
-    self.assertEqual(0, len(request_event.batch_operations))
-    self.assertTrue(
-        test_common.metadata_transmitted(client_initial_metadata,
-                                         request_event.request_metadata))
-    self.assertEqual(METHOD, request_event.request_call_details.method)
-    self.assertEqual(self.expected_host,
-                     request_event.request_call_details.host)
-    self.assertLess(
-        abs(DEADLINE - float(request_event.request_call_details.deadline)),
-        DEADLINE_TOLERANCE)
-
-    server_call_tag = object()
-    server_call = request_event.operation_call
-    server_initial_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY,
-                         SERVER_INITIAL_METADATA_VALUE)])
-    server_trailing_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
-                         SERVER_TRAILING_METADATA_VALUE)])
-    server_start_batch_result = server_call.start_server_batch([
-        cygrpc.operation_send_initial_metadata(server_initial_metadata,
-                                               _EMPTY_FLAGS),
-        cygrpc.operation_receive_message(_EMPTY_FLAGS),
-        cygrpc.operation_send_message(RESPONSE, _EMPTY_FLAGS),
-        cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
-        cygrpc.operation_send_status_from_server(
-            server_trailing_metadata, SERVER_STATUS_CODE,
-            SERVER_STATUS_DETAILS, _EMPTY_FLAGS)
-    ], server_call_tag)
-    self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
-
-    server_event = self.server_completion_queue.poll(cygrpc_deadline)
-    client_event = client_event_future.result()
-
-    self.assertEqual(6, len(client_event.batch_operations))
-    found_client_op_types = set()
-    for client_result in client_event.batch_operations:
-      # we expect each op type to be unique
-      self.assertNotIn(client_result.type, found_client_op_types)
-      found_client_op_types.add(client_result.type)
-      if client_result.type == cygrpc.OperationType.receive_initial_metadata:
-        self.assertTrue(
-            test_common.metadata_transmitted(server_initial_metadata,
-                                             client_result.received_metadata))
-      elif client_result.type == cygrpc.OperationType.receive_message:
-        self.assertEqual(RESPONSE, client_result.received_message.bytes())
-      elif client_result.type == cygrpc.OperationType.receive_status_on_client:
+
+        def performer():
+            tag = object()
+            try:
+                call_result = call.start_client_batch(
+                    cygrpc.Operations(operations), tag)
+                self.assertEqual(cygrpc.CallError.ok, call_result)
+                event = queue.poll(deadline)
+                self.assertEqual(cygrpc.CompletionType.operation_complete,
+                                 event.type)
+                self.assertTrue(event.success)
+                self.assertIs(tag, event.tag)
+            except Exception as error:
+                raise Exception("Error in '{}': {}".format(description,
+                                                           error.message))
+            return event
+
+        return test_utilities.SimpleFuture(performer)
+
+    def testEcho(self):
+        DEADLINE = time.time() + 5
+        DEADLINE_TOLERANCE = 0.25
+        CLIENT_METADATA_ASCII_KEY = b'key'
+        CLIENT_METADATA_ASCII_VALUE = b'val'
+        CLIENT_METADATA_BIN_KEY = b'key-bin'
+        CLIENT_METADATA_BIN_VALUE = b'\0' * 1000
+        SERVER_INITIAL_METADATA_KEY = b'init_me_me_me'
+        SERVER_INITIAL_METADATA_VALUE = b'whodawha?'
+        SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought'
+        SERVER_TRAILING_METADATA_VALUE = b'zomg it is'
+        SERVER_STATUS_CODE = cygrpc.StatusCode.ok
+        SERVER_STATUS_DETAILS = b'our work is never over'
+        REQUEST = b'in death a member of project mayhem has a name'
+        RESPONSE = b'his name is robert paulson'
+        METHOD = b'twinkies'
+
+        cygrpc_deadline = cygrpc.Timespec(DEADLINE)
+
+        server_request_tag = object()
+        request_call_result = self.server.request_call(
+            self.server_completion_queue, self.server_completion_queue,
+            server_request_tag)
+
+        self.assertEqual(cygrpc.CallError.ok, request_call_result)
+
+        client_call_tag = object()
+        client_call = self.client_channel.create_call(
+            None, 0, self.client_completion_queue, METHOD, self.host_argument,
+            cygrpc_deadline)
+        client_initial_metadata = cygrpc.Metadata([
+            cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
+                             CLIENT_METADATA_ASCII_VALUE),
+            cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)
+        ])
+        client_start_batch_result = client_call.start_client_batch([
+            cygrpc.operation_send_initial_metadata(client_initial_metadata,
+                                                   _EMPTY_FLAGS),
+            cygrpc.operation_send_message(REQUEST, _EMPTY_FLAGS),
+            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+            cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+            cygrpc.operation_receive_message(_EMPTY_FLAGS),
+            cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
+        ], client_call_tag)
+        self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
+        client_event_future = test_utilities.CompletionQueuePollFuture(
+            self.client_completion_queue, cygrpc_deadline)
+
+        request_event = self.server_completion_queue.poll(cygrpc_deadline)
+        self.assertEqual(cygrpc.CompletionType.operation_complete,
+                         request_event.type)
+        self.assertIsInstance(request_event.operation_call, cygrpc.Call)
+        self.assertIs(server_request_tag, request_event.tag)
+        self.assertEqual(0, len(request_event.batch_operations))
         self.assertTrue(
-            test_common.metadata_transmitted(server_trailing_metadata,
-                                             client_result.received_metadata))
-        self.assertEqual(SERVER_STATUS_DETAILS,
-                         client_result.received_status_details)
-        self.assertEqual(SERVER_STATUS_CODE, client_result.received_status_code)
-    self.assertEqual(set([
-          cygrpc.OperationType.send_initial_metadata,
-          cygrpc.OperationType.send_message,
-          cygrpc.OperationType.send_close_from_client,
-          cygrpc.OperationType.receive_initial_metadata,
-          cygrpc.OperationType.receive_message,
-          cygrpc.OperationType.receive_status_on_client
-      ]), found_client_op_types)
-
-    self.assertEqual(5, len(server_event.batch_operations))
-    found_server_op_types = set()
-    for server_result in server_event.batch_operations:
-      self.assertNotIn(client_result.type, found_server_op_types)
-      found_server_op_types.add(server_result.type)
-      if server_result.type == cygrpc.OperationType.receive_message:
-        self.assertEqual(REQUEST, server_result.received_message.bytes())
-      elif server_result.type == cygrpc.OperationType.receive_close_on_server:
-        self.assertFalse(server_result.received_cancelled)
-    self.assertEqual(set([
-          cygrpc.OperationType.send_initial_metadata,
-          cygrpc.OperationType.receive_message,
-          cygrpc.OperationType.send_message,
-          cygrpc.OperationType.receive_close_on_server,
-          cygrpc.OperationType.send_status_from_server
-      ]), found_server_op_types)
-
-    del client_call
-    del server_call
-
-  def test6522(self):
-    DEADLINE = time.time()+5
-    DEADLINE_TOLERANCE = 0.25
-    METHOD = b'twinkies'
-
-    cygrpc_deadline = cygrpc.Timespec(DEADLINE)
-    empty_metadata = cygrpc.Metadata([])
-
-    server_request_tag = object()
-    self.server.request_call(
-        self.server_completion_queue, self.server_completion_queue,
-        server_request_tag)
-    client_call = self.client_channel.create_call(
-        None, 0, self.client_completion_queue, METHOD, self.host_argument,
-        cygrpc_deadline)
-
-    # Prologue
-    def perform_client_operations(operations, description):
-      return self._perform_operations(
-          operations, client_call,
-          self.client_completion_queue, cygrpc_deadline, description)
-
-    client_event_future = perform_client_operations([
+            test_common.metadata_transmitted(client_initial_metadata,
+                                             request_event.request_metadata))
+        self.assertEqual(METHOD, request_event.request_call_details.method)
+        self.assertEqual(self.expected_host,
+                         request_event.request_call_details.host)
+        self.assertLess(
+            abs(DEADLINE - float(request_event.request_call_details.deadline)),
+            DEADLINE_TOLERANCE)
+
+        server_call_tag = object()
+        server_call = request_event.operation_call
+        server_initial_metadata = cygrpc.Metadata([
+            cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY,
+                             SERVER_INITIAL_METADATA_VALUE)
+        ])
+        server_trailing_metadata = cygrpc.Metadata([
+            cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
+                             SERVER_TRAILING_METADATA_VALUE)
+        ])
+        server_start_batch_result = server_call.start_server_batch([
+            cygrpc.operation_send_initial_metadata(
+                server_initial_metadata,
+                _EMPTY_FLAGS), cygrpc.operation_receive_message(_EMPTY_FLAGS),
+            cygrpc.operation_send_message(RESPONSE, _EMPTY_FLAGS),
+            cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+            cygrpc.operation_send_status_from_server(
+                server_trailing_metadata, SERVER_STATUS_CODE,
+                SERVER_STATUS_DETAILS, _EMPTY_FLAGS)
+        ], server_call_tag)
+        self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
+
+        server_event = self.server_completion_queue.poll(cygrpc_deadline)
+        client_event = client_event_future.result()
+
+        self.assertEqual(6, len(client_event.batch_operations))
+        found_client_op_types = set()
+        for client_result in client_event.batch_operations:
+            # we expect each op type to be unique
+            self.assertNotIn(client_result.type, found_client_op_types)
+            found_client_op_types.add(client_result.type)
+            if client_result.type == cygrpc.OperationType.receive_initial_metadata:
+                self.assertTrue(
+                    test_common.metadata_transmitted(
+                        server_initial_metadata,
+                        client_result.received_metadata))
+            elif client_result.type == cygrpc.OperationType.receive_message:
+                self.assertEqual(RESPONSE,
+                                 client_result.received_message.bytes())
+            elif client_result.type == cygrpc.OperationType.receive_status_on_client:
+                self.assertTrue(
+                    test_common.metadata_transmitted(
+                        server_trailing_metadata,
+                        client_result.received_metadata))
+                self.assertEqual(SERVER_STATUS_DETAILS,
+                                 client_result.received_status_details)
+                self.assertEqual(SERVER_STATUS_CODE,
+                                 client_result.received_status_code)
+        self.assertEqual(
+            set([
+                cygrpc.OperationType.send_initial_metadata,
+                cygrpc.OperationType.send_message,
+                cygrpc.OperationType.send_close_from_client,
+                cygrpc.OperationType.receive_initial_metadata,
+                cygrpc.OperationType.receive_message,
+                cygrpc.OperationType.receive_status_on_client
+            ]), found_client_op_types)
+
+        self.assertEqual(5, len(server_event.batch_operations))
+        found_server_op_types = set()
+        for server_result in server_event.batch_operations:
+            self.assertNotIn(client_result.type, found_server_op_types)
+            found_server_op_types.add(server_result.type)
+            if server_result.type == cygrpc.OperationType.receive_message:
+                self.assertEqual(REQUEST,
+                                 server_result.received_message.bytes())
+            elif server_result.type == cygrpc.OperationType.receive_close_on_server:
+                self.assertFalse(server_result.received_cancelled)
+        self.assertEqual(
+            set([
+                cygrpc.OperationType.send_initial_metadata,
+                cygrpc.OperationType.receive_message,
+                cygrpc.OperationType.send_message,
+                cygrpc.OperationType.receive_close_on_server,
+                cygrpc.OperationType.send_status_from_server
+            ]), found_server_op_types)
+
+        del client_call
+        del server_call
+
+    def test6522(self):
+        DEADLINE = time.time() + 5
+        DEADLINE_TOLERANCE = 0.25
+        METHOD = b'twinkies'
+
+        cygrpc_deadline = cygrpc.Timespec(DEADLINE)
+        empty_metadata = cygrpc.Metadata([])
+
+        server_request_tag = object()
+        self.server.request_call(self.server_completion_queue,
+                                 self.server_completion_queue,
+                                 server_request_tag)
+        client_call = self.client_channel.create_call(
+            None, 0, self.client_completion_queue, METHOD, self.host_argument,
+            cygrpc_deadline)
+
+        # Prologue
+        def perform_client_operations(operations, description):
+            return self._perform_operations(operations, client_call,
+                                            self.client_completion_queue,
+                                            cygrpc_deadline, description)
+
+        client_event_future = perform_client_operations([
             cygrpc.operation_send_initial_metadata(empty_metadata,
                                                    _EMPTY_FLAGS),
             cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
         ], "Client prologue")
 
-    request_event = self.server_completion_queue.poll(cygrpc_deadline)
-    server_call = request_event.operation_call
+        request_event = self.server_completion_queue.poll(cygrpc_deadline)
+        server_call = request_event.operation_call
 
-    def perform_server_operations(operations, description):
-      return self._perform_operations(
-          operations, server_call,
-          self.server_completion_queue, cygrpc_deadline, description)
+        def perform_server_operations(operations, description):
+            return self._perform_operations(operations, server_call,
+                                            self.server_completion_queue,
+                                            cygrpc_deadline, description)
 
-    server_event_future = perform_server_operations([
+        server_event_future = perform_server_operations([
             cygrpc.operation_send_initial_metadata(empty_metadata,
                                                    _EMPTY_FLAGS),
         ], "Server prologue")
 
-    client_event_future.result()  # force completion
-    server_event_future.result()
-
-    # Messaging
-    for _ in range(10):
-      client_event_future = perform_client_operations([
-              cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
-              cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          ], "Client message")
-      server_event_future = perform_server_operations([
-              cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
-              cygrpc.operation_receive_message(_EMPTY_FLAGS),
-          ], "Server receive")
-
-      client_event_future.result()  # force completion
-      server_event_future.result()
-
-    # Epilogue
-    client_event_future = perform_client_operations([
+        client_event_future.result()  # force completion
+        server_event_future.result()
+
+        # Messaging
+        for _ in range(10):
+            client_event_future = perform_client_operations([
+                cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+                cygrpc.operation_receive_message(_EMPTY_FLAGS),
+            ], "Client message")
+            server_event_future = perform_server_operations([
+                cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+                cygrpc.operation_receive_message(_EMPTY_FLAGS),
+            ], "Server receive")
+
+            client_event_future.result()  # force completion
+            server_event_future.result()
+
+        # Epilogue
+        client_event_future = perform_client_operations([
             cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
             cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
         ], "Client epilogue")
 
-    server_event_future = perform_server_operations([
+        server_event_future = perform_server_operations([
             cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
             cygrpc.operation_send_status_from_server(
                 empty_metadata, cygrpc.StatusCode.ok, b'', _EMPTY_FLAGS)
         ], "Server epilogue")
 
-    client_event_future.result()  # force completion
-    server_event_future.result()
+        client_event_future.result()  # force completion
+        server_event_future.result()
 
 
 class InsecureServerInsecureClient(unittest.TestCase, ServerClientMixin):
 
-  def setUp(self):
-    self.setUpMixin(None, None, None)
+    def setUp(self):
+        self.setUpMixin(None, None, None)
 
-  def tearDown(self):
-    self.tearDownMixin()
+    def tearDown(self):
+        self.tearDownMixin()
 
 
 class SecureServerSecureClient(unittest.TestCase, ServerClientMixin):
 
-  def setUp(self):
-    server_credentials = cygrpc.server_credentials_ssl(
-        None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
-                                        resources.certificate_chain())], False)
-    client_credentials = cygrpc.channel_credentials_ssl(
-        resources.test_root_certificates(), None)
-    self.setUpMixin(server_credentials, client_credentials, _SSL_HOST_OVERRIDE)
+    def setUp(self):
+        server_credentials = cygrpc.server_credentials_ssl(None, [
+            cygrpc.SslPemKeyCertPair(resources.private_key(),
+                                     resources.certificate_chain())
+        ], False)
+        client_credentials = cygrpc.channel_credentials_ssl(
+            resources.test_root_certificates(), None)
+        self.setUpMixin(server_credentials, client_credentials,
+                        _SSL_HOST_OVERRIDE)
 
-  def tearDown(self):
-    self.tearDownMixin()
+    def tearDown(self):
+        self.tearDownMixin()
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
index 6280ce74c4..dffb3733b6 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/test_utilities.py
@@ -33,34 +33,35 @@ from grpc._cython import cygrpc
 
 
 class SimpleFuture(object):
-  """A simple future mechanism."""
+    """A simple future mechanism."""
 
-  def __init__(self, function, *args, **kwargs):
-    def wrapped_function():
-      try:
-        self._result = function(*args, **kwargs)
-      except Exception as error:
-        self._error = error
-    self._result = None
-    self._error = None
-    self._thread = threading.Thread(target=wrapped_function)
-    self._thread.start()
+    def __init__(self, function, *args, **kwargs):
 
-  def result(self):
-    """The resulting value of this future.
+        def wrapped_function():
+            try:
+                self._result = function(*args, **kwargs)
+            except Exception as error:
+                self._error = error
+
+        self._result = None
+        self._error = None
+        self._thread = threading.Thread(target=wrapped_function)
+        self._thread.start()
+
+    def result(self):
+        """The resulting value of this future.
 
     Re-raises any exceptions.
     """
-    self._thread.join()
-    if self._error:
-      # TODO(atash): re-raise exceptions in a way that preserves tracebacks
-      raise self._error
-    return self._result
+        self._thread.join()
+        if self._error:
+            # TODO(atash): re-raise exceptions in a way that preserves tracebacks
+            raise self._error
+        return self._result
 
 
 class CompletionQueuePollFuture(SimpleFuture):
 
-  def __init__(self, completion_queue, deadline):
-    super(CompletionQueuePollFuture, self).__init__(
-        lambda: completion_queue.poll(deadline))
-
+    def __init__(self, completion_queue, deadline):
+        super(CompletionQueuePollFuture,
+              self).__init__(lambda: completion_queue.poll(deadline))
diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
index 69f4689279..4588688ea6 100644
--- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
@@ -44,95 +44,94 @@ _STREAM_STREAM = '/test/StreamStream'
 
 
 def handle_unary_unary(request, servicer_context):
-  return _RESPONSE
+    return _RESPONSE
 
 
 def handle_unary_stream(request, servicer_context):
-  for _ in range(test_constants.STREAM_LENGTH):
-    yield _RESPONSE
+    for _ in range(test_constants.STREAM_LENGTH):
+        yield _RESPONSE
 
 
 def handle_stream_unary(request_iterator, servicer_context):
-  for request in request_iterator:
-    pass
-  return _RESPONSE
+    for request in request_iterator:
+        pass
+    return _RESPONSE
 
 
 def handle_stream_stream(request_iterator, servicer_context):
-  for request in request_iterator:
-    yield _RESPONSE
+    for request in request_iterator:
+        yield _RESPONSE
 
 
 class _MethodHandler(grpc.RpcMethodHandler):
 
-  def __init__(self, request_streaming, response_streaming):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = None
-    self.response_serializer = None
-    self.unary_unary = None
-    self.unary_stream = None
-    self.stream_unary = None
-    self.stream_stream = None
-    if self.request_streaming and self.response_streaming:
-      self.stream_stream = handle_stream_stream
-    elif self.request_streaming:
-      self.stream_unary = handle_stream_unary
-    elif self.response_streaming:
-      self.unary_stream = handle_unary_stream
-    else:
-      self.unary_unary = handle_unary_unary
+    def __init__(self, request_streaming, response_streaming):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = None
+        self.response_serializer = None
+        self.unary_unary = None
+        self.unary_stream = None
+        self.stream_unary = None
+        self.stream_stream = None
+        if self.request_streaming and self.response_streaming:
+            self.stream_stream = handle_stream_stream
+        elif self.request_streaming:
+            self.stream_unary = handle_stream_unary
+        elif self.response_streaming:
+            self.unary_stream = handle_unary_stream
+        else:
+            self.unary_unary = handle_unary_unary
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
 
-  def service(self, handler_call_details):
-    if handler_call_details.method == _UNARY_UNARY:
-      return _MethodHandler(False, False)
-    elif handler_call_details.method == _UNARY_STREAM:
-      return _MethodHandler(False, True)
-    elif handler_call_details.method == _STREAM_UNARY:
-      return _MethodHandler(True, False)
-    elif handler_call_details.method == _STREAM_STREAM:
-      return _MethodHandler(True, True)
-    else:
-      return None
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(False, False)
+        elif handler_call_details.method == _UNARY_STREAM:
+            return _MethodHandler(False, True)
+        elif handler_call_details.method == _STREAM_UNARY:
+            return _MethodHandler(True, False)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(True, True)
+        else:
+            return None
 
 
 class EmptyMessageTest(unittest.TestCase):
 
-  def setUp(self):
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(
-        self._server_pool, handlers=(_GenericHandler(),))
-    port = self._server.add_insecure_port('[::]:0')
-    self._server.start()
-    self._channel = grpc.insecure_channel('localhost:%d' % port)
+    def setUp(self):
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(
+            self._server_pool, handlers=(_GenericHandler(),))
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.start()
+        self._channel = grpc.insecure_channel('localhost:%d' % port)
 
-  def tearDown(self):
-    self._server.stop(0)
+    def tearDown(self):
+        self._server.stop(0)
 
-  def testUnaryUnary(self):
-    response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST)
-    self.assertEqual(_RESPONSE, response)
+    def testUnaryUnary(self):
+        response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST)
+        self.assertEqual(_RESPONSE, response)
 
-  def testUnaryStream(self):
-    response_iterator = self._channel.unary_stream(_UNARY_STREAM)(_REQUEST)
-    self.assertSequenceEqual(
-        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+    def testUnaryStream(self):
+        response_iterator = self._channel.unary_stream(_UNARY_STREAM)(_REQUEST)
+        self.assertSequenceEqual([_RESPONSE] * test_constants.STREAM_LENGTH,
+                                 list(response_iterator))
 
-  def testStreamUnary(self):
-    response = self._channel.stream_unary(_STREAM_UNARY)(
-        iter([_REQUEST] * test_constants.STREAM_LENGTH))
-    self.assertEqual(_RESPONSE, response)
+    def testStreamUnary(self):
+        response = self._channel.stream_unary(_STREAM_UNARY)(iter(
+            [_REQUEST] * test_constants.STREAM_LENGTH))
+        self.assertEqual(_RESPONSE, response)
 
-  def testStreamStream(self):
-    response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
-        iter([_REQUEST] * test_constants.STREAM_LENGTH))
-    self.assertSequenceEqual(
-        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+    def testStreamStream(self):
+        response_iterator = self._channel.stream_stream(_STREAM_STREAM)(iter(
+            [_REQUEST] * test_constants.STREAM_LENGTH))
+        self.assertSequenceEqual([_RESPONSE] * test_constants.STREAM_LENGTH,
+                                 list(response_iterator))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
-
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index 777527137f..22a6643848 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Defines a number of module-scope gRPC scenarios to test clean exit."""
 
 import argparse
@@ -73,88 +72,88 @@ TEST_TO_METHOD = {
 
 
 def hang_unary_unary(request, servicer_context):
-  time.sleep(WAIT_TIME)
+    time.sleep(WAIT_TIME)
 
 
 def hang_unary_stream(request, servicer_context):
-  time.sleep(WAIT_TIME)
+    time.sleep(WAIT_TIME)
 
 
 def hang_partial_unary_stream(request, servicer_context):
-  for _ in range(test_constants.STREAM_LENGTH // 2):
-    yield request
-  time.sleep(WAIT_TIME)
+    for _ in range(test_constants.STREAM_LENGTH // 2):
+        yield request
+    time.sleep(WAIT_TIME)
 
 
 def hang_stream_unary(request_iterator, servicer_context):
-  time.sleep(WAIT_TIME)
+    time.sleep(WAIT_TIME)
 
 
 def hang_partial_stream_unary(request_iterator, servicer_context):
-  for _ in range(test_constants.STREAM_LENGTH // 2):
-    next(request_iterator)
-  time.sleep(WAIT_TIME)
+    for _ in range(test_constants.STREAM_LENGTH // 2):
+        next(request_iterator)
+    time.sleep(WAIT_TIME)
 
 
 def hang_stream_stream(request_iterator, servicer_context):
-  time.sleep(WAIT_TIME)
+    time.sleep(WAIT_TIME)
 
 
 def hang_partial_stream_stream(request_iterator, servicer_context):
-  for _ in range(test_constants.STREAM_LENGTH // 2):
-    yield next(request_iterator)
-  time.sleep(WAIT_TIME)
+    for _ in range(test_constants.STREAM_LENGTH // 2):
+        yield next(request_iterator)
+    time.sleep(WAIT_TIME)
 
 
 class MethodHandler(grpc.RpcMethodHandler):
 
-  def __init__(self, request_streaming, response_streaming, partial_hang):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = None
-    self.response_serializer = None
-    self.unary_unary = None
-    self.unary_stream = None
-    self.stream_unary = None
-    self.stream_stream = None
-    if self.request_streaming and self.response_streaming:
-      if partial_hang:
-        self.stream_stream = hang_partial_stream_stream
-      else:
-        self.stream_stream = hang_stream_stream
-    elif self.request_streaming:
-      if partial_hang:
-        self.stream_unary = hang_partial_stream_unary
-      else:
-        self.stream_unary = hang_stream_unary
-    elif self.response_streaming:
-      if partial_hang:
-        self.unary_stream = hang_partial_unary_stream
-      else:
-        self.unary_stream = hang_unary_stream
-    else:
-      self.unary_unary = hang_unary_unary
+    def __init__(self, request_streaming, response_streaming, partial_hang):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = None
+        self.response_serializer = None
+        self.unary_unary = None
+        self.unary_stream = None
+        self.stream_unary = None
+        self.stream_stream = None
+        if self.request_streaming and self.response_streaming:
+            if partial_hang:
+                self.stream_stream = hang_partial_stream_stream
+            else:
+                self.stream_stream = hang_stream_stream
+        elif self.request_streaming:
+            if partial_hang:
+                self.stream_unary = hang_partial_stream_unary
+            else:
+                self.stream_unary = hang_stream_unary
+        elif self.response_streaming:
+            if partial_hang:
+                self.unary_stream = hang_partial_unary_stream
+            else:
+                self.unary_stream = hang_unary_stream
+        else:
+            self.unary_unary = hang_unary_unary
 
 
 class GenericHandler(grpc.GenericRpcHandler):
 
-  def service(self, handler_call_details):
-    if handler_call_details.method == UNARY_UNARY:
-      return MethodHandler(False, False, False)
-    elif handler_call_details.method == UNARY_STREAM:
-      return MethodHandler(False, True, False)
-    elif handler_call_details.method == STREAM_UNARY:
-      return MethodHandler(True, False, False)
-    elif handler_call_details.method == STREAM_STREAM:
-      return MethodHandler(True, True, False)
-    elif handler_call_details.method == PARTIAL_UNARY_STREAM:
-      return MethodHandler(False, True, True)
-    elif handler_call_details.method == PARTIAL_STREAM_UNARY:
-      return MethodHandler(True, False, True)
-    elif handler_call_details.method == PARTIAL_STREAM_STREAM:
-      return MethodHandler(True, True, True)
-    else:
-      return None
+    def service(self, handler_call_details):
+        if handler_call_details.method == UNARY_UNARY:
+            return MethodHandler(False, False, False)
+        elif handler_call_details.method == UNARY_STREAM:
+            return MethodHandler(False, True, False)
+        elif handler_call_details.method == STREAM_UNARY:
+            return MethodHandler(True, False, False)
+        elif handler_call_details.method == STREAM_STREAM:
+            return MethodHandler(True, True, False)
+        elif handler_call_details.method == PARTIAL_UNARY_STREAM:
+            return MethodHandler(False, True, True)
+        elif handler_call_details.method == PARTIAL_STREAM_UNARY:
+            return MethodHandler(True, False, True)
+        elif handler_call_details.method == PARTIAL_STREAM_STREAM:
+            return MethodHandler(True, True, True)
+        else:
+            return None
 
 
 # Traditional executors will not exit until all their
@@ -162,88 +161,88 @@ class GenericHandler(grpc.GenericRpcHandler):
 # never finish, we don't want to block exit on these jobs.
 class DaemonPool(object):
 
-  def submit(self, fn, *args, **kwargs):
-    thread = threading.Thread(target=fn, args=args, kwargs=kwargs)
-    thread.daemon = True
-    thread.start()
+    def submit(self, fn, *args, **kwargs):
+        thread = threading.Thread(target=fn, args=args, kwargs=kwargs)
+        thread.daemon = True
+        thread.start()
 
-  def shutdown(self, wait=True):
-    pass
+    def shutdown(self, wait=True):
+        pass
 
 
 def infinite_request_iterator():
-  while True:
-    yield REQUEST
+    while True:
+        yield REQUEST
 
 
 if __name__ == '__main__':
-  parser = argparse.ArgumentParser()
-  parser.add_argument('scenario', type=str)
-  parser.add_argument(
-      '--wait_for_interrupt', dest='wait_for_interrupt', action='store_true')
-  args = parser.parse_args()
-
-  if args.scenario == UNSTARTED_SERVER:
-    server = grpc.server(DaemonPool())
-    if args.wait_for_interrupt:
-      time.sleep(WAIT_TIME)
-  elif args.scenario == RUNNING_SERVER:
-    server = grpc.server(DaemonPool())
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    if args.wait_for_interrupt:
-      time.sleep(WAIT_TIME)
-  elif args.scenario == POLL_CONNECTIVITY_NO_SERVER:
-    channel = grpc.insecure_channel('localhost:12345')
-
-    def connectivity_callback(connectivity):
-      pass
-
-    channel.subscribe(connectivity_callback, try_to_connect=True)
-    if args.wait_for_interrupt:
-      time.sleep(WAIT_TIME)
-  elif args.scenario == POLL_CONNECTIVITY:
-    server = grpc.server(DaemonPool())
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    channel = grpc.insecure_channel('localhost:%d' % port)
-
-    def connectivity_callback(connectivity):
-      pass
-
-    channel.subscribe(connectivity_callback, try_to_connect=True)
-    if args.wait_for_interrupt:
-      time.sleep(WAIT_TIME)
-
-  else:
-    handler = GenericHandler()
-    server = grpc.server(DaemonPool())
-    port = server.add_insecure_port('[::]:0')
-    server.add_generic_rpc_handlers((handler,))
-    server.start()
-    channel = grpc.insecure_channel('localhost:%d' % port)
-
-    method = TEST_TO_METHOD[args.scenario]
-
-    if args.scenario == IN_FLIGHT_UNARY_UNARY_CALL:
-      multi_callable = channel.unary_unary(method)
-      future = multi_callable.future(REQUEST)
-      result, call = multi_callable.with_call(REQUEST)
-    elif (args.scenario == IN_FLIGHT_UNARY_STREAM_CALL or
-          args.scenario == IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL):
-      multi_callable = channel.unary_stream(method)
-      response_iterator = multi_callable(REQUEST)
-      for response in response_iterator:
-        pass
-    elif (args.scenario == IN_FLIGHT_STREAM_UNARY_CALL or
-          args.scenario == IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL):
-      multi_callable = channel.stream_unary(method)
-      future = multi_callable.future(infinite_request_iterator())
-      result, call = multi_callable.with_call(
-          iter([REQUEST] * test_constants.STREAM_LENGTH))
-    elif (args.scenario == IN_FLIGHT_STREAM_STREAM_CALL or
-          args.scenario == IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL):
-      multi_callable = channel.stream_stream(method)
-      response_iterator = multi_callable(infinite_request_iterator())
-      for response in response_iterator:
-        pass
+    parser = argparse.ArgumentParser()
+    parser.add_argument('scenario', type=str)
+    parser.add_argument(
+        '--wait_for_interrupt', dest='wait_for_interrupt', action='store_true')
+    args = parser.parse_args()
+
+    if args.scenario == UNSTARTED_SERVER:
+        server = grpc.server(DaemonPool())
+        if args.wait_for_interrupt:
+            time.sleep(WAIT_TIME)
+    elif args.scenario == RUNNING_SERVER:
+        server = grpc.server(DaemonPool())
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        if args.wait_for_interrupt:
+            time.sleep(WAIT_TIME)
+    elif args.scenario == POLL_CONNECTIVITY_NO_SERVER:
+        channel = grpc.insecure_channel('localhost:12345')
+
+        def connectivity_callback(connectivity):
+            pass
+
+        channel.subscribe(connectivity_callback, try_to_connect=True)
+        if args.wait_for_interrupt:
+            time.sleep(WAIT_TIME)
+    elif args.scenario == POLL_CONNECTIVITY:
+        server = grpc.server(DaemonPool())
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        channel = grpc.insecure_channel('localhost:%d' % port)
+
+        def connectivity_callback(connectivity):
+            pass
+
+        channel.subscribe(connectivity_callback, try_to_connect=True)
+        if args.wait_for_interrupt:
+            time.sleep(WAIT_TIME)
+
+    else:
+        handler = GenericHandler()
+        server = grpc.server(DaemonPool())
+        port = server.add_insecure_port('[::]:0')
+        server.add_generic_rpc_handlers((handler,))
+        server.start()
+        channel = grpc.insecure_channel('localhost:%d' % port)
+
+        method = TEST_TO_METHOD[args.scenario]
+
+        if args.scenario == IN_FLIGHT_UNARY_UNARY_CALL:
+            multi_callable = channel.unary_unary(method)
+            future = multi_callable.future(REQUEST)
+            result, call = multi_callable.with_call(REQUEST)
+        elif (args.scenario == IN_FLIGHT_UNARY_STREAM_CALL or
+              args.scenario == IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL):
+            multi_callable = channel.unary_stream(method)
+            response_iterator = multi_callable(REQUEST)
+            for response in response_iterator:
+                pass
+        elif (args.scenario == IN_FLIGHT_STREAM_UNARY_CALL or
+              args.scenario == IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL):
+            multi_callable = channel.stream_unary(method)
+            future = multi_callable.future(infinite_request_iterator())
+            result, call = multi_callable.with_call(
+                iter([REQUEST] * test_constants.STREAM_LENGTH))
+        elif (args.scenario == IN_FLIGHT_STREAM_STREAM_CALL or
+              args.scenario == IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL):
+            multi_callable = channel.stream_stream(method)
+            response_iterator = multi_callable(infinite_request_iterator())
+            for response in response_iterator:
+                pass
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index 5a4a32887c..b99605dcb8 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests clean exit of server/client on Python Interpreter exit/sigint.
 
 The tests in this module spawn a subprocess for each test case, the
@@ -45,15 +44,15 @@ import unittest
 
 from tests.unit import _exit_scenarios
 
-SCENARIO_FILE = os.path.abspath(os.path.join(
-    os.path.dirname(os.path.realpath(__file__)), '_exit_scenarios.py'))
+SCENARIO_FILE = os.path.abspath(
+    os.path.join(
+        os.path.dirname(os.path.realpath(__file__)), '_exit_scenarios.py'))
 INTERPRETER = sys.executable
 BASE_COMMAND = [INTERPRETER, SCENARIO_FILE]
 BASE_SIGTERM_COMMAND = BASE_COMMAND + ['--wait_for_interrupt']
 
 INIT_TIME = 1.0
 
-
 processes = []
 process_lock = threading.Lock()
 
@@ -61,126 +60,146 @@ process_lock = threading.Lock()
 # Make sure we attempt to clean up any
 # processes we may have left running
 def cleanup_processes():
-  with process_lock:
-    for process in processes:
-      try:
-        process.kill()
-      except Exception:
-        pass
+    with process_lock:
+        for process in processes:
+            try:
+                process.kill()
+            except Exception:
+                pass
+
+
 atexit.register(cleanup_processes)
 
 
 def interrupt_and_wait(process):
-  with process_lock:
-    processes.append(process)
-  time.sleep(INIT_TIME)
-  os.kill(process.pid, signal.SIGINT)
-  process.wait()
+    with process_lock:
+        processes.append(process)
+    time.sleep(INIT_TIME)
+    os.kill(process.pid, signal.SIGINT)
+    process.wait()
 
 
 def wait(process):
-  with process_lock:
-    processes.append(process)
-  process.wait()
+    with process_lock:
+        processes.append(process)
+    process.wait()
 
 
 @unittest.skip('https://github.com/grpc/grpc/issues/7311')
 class ExitTest(unittest.TestCase):
 
-  def test_unstarted_server(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
-        stdout=sys.stdout, stderr=sys.stderr)
-    wait(process)
-
-  def test_unstarted_server_terminate(self):
-    process = subprocess.Popen(
-        BASE_SIGTERM_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
-        stdout=sys.stdout)
-    interrupt_and_wait(process)
-
-  def test_running_server(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.RUNNING_SERVER],
-        stdout=sys.stdout, stderr=sys.stderr)
-    wait(process)
-
-  def test_running_server_terminate(self):
-    process = subprocess.Popen(
-        BASE_SIGTERM_COMMAND + [_exit_scenarios.RUNNING_SERVER],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  def test_poll_connectivity_no_server(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
-        stdout=sys.stdout, stderr=sys.stderr)
-    wait(process)
-
-  def test_poll_connectivity_no_server_terminate(self):
-    process = subprocess.Popen(
-        BASE_SIGTERM_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  def test_poll_connectivity(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
-        stdout=sys.stdout, stderr=sys.stderr)
-    wait(process)
-
-  def test_poll_connectivity_terminate(self):
-    process = subprocess.Popen(
-        BASE_SIGTERM_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  def test_in_flight_unary_unary_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
-  def test_in_flight_unary_stream_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  def test_in_flight_stream_unary_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
-  def test_in_flight_stream_stream_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
-  def test_in_flight_partial_unary_stream_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  def test_in_flight_partial_stream_unary_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
-
-  @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
-  def test_in_flight_partial_stream_stream_call(self):
-    process = subprocess.Popen(
-        BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL],
-        stdout=sys.stdout, stderr=sys.stderr)
-    interrupt_and_wait(process)
+    def test_unstarted_server(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        wait(process)
+
+    def test_unstarted_server_terminate(self):
+        process = subprocess.Popen(
+            BASE_SIGTERM_COMMAND + [_exit_scenarios.UNSTARTED_SERVER],
+            stdout=sys.stdout)
+        interrupt_and_wait(process)
+
+    def test_running_server(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.RUNNING_SERVER],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        wait(process)
+
+    def test_running_server_terminate(self):
+        process = subprocess.Popen(
+            BASE_SIGTERM_COMMAND + [_exit_scenarios.RUNNING_SERVER],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    def test_poll_connectivity_no_server(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        wait(process)
+
+    def test_poll_connectivity_no_server_terminate(self):
+        process = subprocess.Popen(
+            BASE_SIGTERM_COMMAND +
+            [_exit_scenarios.POLL_CONNECTIVITY_NO_SERVER],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    def test_poll_connectivity(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        wait(process)
+
+    def test_poll_connectivity_terminate(self):
+        process = subprocess.Popen(
+            BASE_SIGTERM_COMMAND + [_exit_scenarios.POLL_CONNECTIVITY],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    def test_in_flight_unary_unary_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+    def test_in_flight_unary_stream_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    def test_in_flight_stream_unary_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+    def test_in_flight_stream_stream_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+    def test_in_flight_partial_unary_stream_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND +
+            [_exit_scenarios.IN_FLIGHT_PARTIAL_UNARY_STREAM_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    def test_in_flight_partial_stream_unary_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND +
+            [_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_UNARY_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
+
+    @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+    def test_in_flight_partial_stream_stream_call(self):
+        process = subprocess.Popen(
+            BASE_COMMAND +
+            [_exit_scenarios.IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL],
+            stdout=sys.stdout,
+            stderr=sys.stderr)
+        interrupt_and_wait(process)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
index 2dc225de29..1b1b1bd598 100644
--- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -26,7 +26,6 @@
 # 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 of RPCs made against gRPC Python's application-layer API."""
 
 import unittest
@@ -47,129 +46,131 @@ _STREAM_STREAM = '/test/StreamStream'
 
 
 def _unary_unary_multi_callable(channel):
-  return channel.unary_unary(_UNARY_UNARY)
+    return channel.unary_unary(_UNARY_UNARY)
 
 
 def _unary_stream_multi_callable(channel):
-  return channel.unary_stream(
-      _UNARY_STREAM,
-      request_serializer=_SERIALIZE_REQUEST,
-      response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.unary_stream(
+        _UNARY_STREAM,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_unary_multi_callable(channel):
-  return channel.stream_unary(
-      _STREAM_UNARY,
-      request_serializer=_SERIALIZE_REQUEST,
-      response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.stream_unary(
+        _STREAM_UNARY,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_stream_multi_callable(channel):
-  return channel.stream_stream(_STREAM_STREAM)
+    return channel.stream_stream(_STREAM_STREAM)
 
 
 class InvalidMetadataTest(unittest.TestCase):
 
-  def setUp(self):
-    self._channel = grpc.insecure_channel('localhost:8080')
-    self._unary_unary = _unary_unary_multi_callable(self._channel)
-    self._unary_stream = _unary_stream_multi_callable(self._channel)
-    self._stream_unary = _stream_unary_multi_callable(self._channel)
-    self._stream_stream = _stream_stream_multi_callable(self._channel)
-
-  def testUnaryRequestBlockingUnaryResponse(self):
-    request = b'\x07\x08'
-    metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    with self.assertRaises(ValueError) as exception_context:
-      self._unary_unary(request, metadata=metadata)
-    self.assertIn(expected_error_details, str(exception_context.exception))
-
-  def testUnaryRequestBlockingUnaryResponseWithCall(self):
-    request = b'\x07\x08'
-    metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponseWithCall'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    with self.assertRaises(ValueError) as exception_context:
-      self._unary_unary.with_call(request, metadata=metadata)
-    self.assertIn(expected_error_details, str(exception_context.exception))
-
-  def testUnaryRequestFutureUnaryResponse(self):
-    request = b'\x07\x08'
-    metadata = (('InVaLiD', 'UnaryRequestFutureUnaryResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    response_future = self._unary_unary.future(request, metadata=metadata)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertEqual(
-        exception_context.exception.details(), expected_error_details)
-    self.assertEqual(
-        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
-    self.assertEqual(response_future.details(), expected_error_details)
-    self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
-
-  def testUnaryRequestStreamResponse(self):
-    request = b'\x37\x58'
-    metadata = (('InVaLiD', 'UnaryRequestStreamResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    response_iterator = self._unary_stream(request, metadata=metadata)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      next(response_iterator)
-    self.assertEqual(
-        exception_context.exception.details(), expected_error_details)
-    self.assertEqual(
-        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
-    self.assertEqual(response_iterator.details(), expected_error_details)
-    self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
-
-  def testStreamRequestBlockingUnaryResponse(self):
-    request_iterator = (b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    with self.assertRaises(ValueError) as exception_context:
-      self._stream_unary(request_iterator, metadata=metadata)
-    self.assertIn(expected_error_details, str(exception_context.exception))
-
-  def testStreamRequestBlockingUnaryResponseWithCall(self):
-    request_iterator = (
-        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponseWithCall'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self.assertRaises(ValueError) as exception_context:
-      multi_callable.with_call(request_iterator, metadata=metadata)
-    self.assertIn(expected_error_details, str(exception_context.exception))
-
-  def testStreamRequestFutureUnaryResponse(self):
-    request_iterator = (
-        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    metadata = (('InVaLiD', 'StreamRequestFutureUnaryResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    response_future = self._stream_unary.future(
-        request_iterator, metadata=metadata)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertEqual(
-        exception_context.exception.details(), expected_error_details)
-    self.assertEqual(
-        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
-    self.assertEqual(response_future.details(), expected_error_details)
-    self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
-
-  def testStreamRequestStreamResponse(self):
-    request_iterator = (
-        b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    metadata = (('InVaLiD', 'StreamRequestStreamResponse'),)
-    expected_error_details = "metadata was invalid: %s" % metadata
-    response_iterator = self._stream_stream(request_iterator, metadata=metadata)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      next(response_iterator)
-    self.assertEqual(
-        exception_context.exception.details(), expected_error_details)
-    self.assertEqual(
-        exception_context.exception.code(), grpc.StatusCode.INTERNAL)
-    self.assertEqual(response_iterator.details(), expected_error_details)
-    self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+    def setUp(self):
+        self._channel = grpc.insecure_channel('localhost:8080')
+        self._unary_unary = _unary_unary_multi_callable(self._channel)
+        self._unary_stream = _unary_stream_multi_callable(self._channel)
+        self._stream_unary = _stream_unary_multi_callable(self._channel)
+        self._stream_stream = _stream_stream_multi_callable(self._channel)
+
+    def testUnaryRequestBlockingUnaryResponse(self):
+        request = b'\x07\x08'
+        metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        with self.assertRaises(ValueError) as exception_context:
+            self._unary_unary(request, metadata=metadata)
+        self.assertIn(expected_error_details, str(exception_context.exception))
+
+    def testUnaryRequestBlockingUnaryResponseWithCall(self):
+        request = b'\x07\x08'
+        metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponseWithCall'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        with self.assertRaises(ValueError) as exception_context:
+            self._unary_unary.with_call(request, metadata=metadata)
+        self.assertIn(expected_error_details, str(exception_context.exception))
+
+    def testUnaryRequestFutureUnaryResponse(self):
+        request = b'\x07\x08'
+        metadata = (('InVaLiD', 'UnaryRequestFutureUnaryResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        response_future = self._unary_unary.future(request, metadata=metadata)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertEqual(exception_context.exception.details(),
+                         expected_error_details)
+        self.assertEqual(exception_context.exception.code(),
+                         grpc.StatusCode.INTERNAL)
+        self.assertEqual(response_future.details(), expected_error_details)
+        self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+
+    def testUnaryRequestStreamResponse(self):
+        request = b'\x37\x58'
+        metadata = (('InVaLiD', 'UnaryRequestStreamResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        response_iterator = self._unary_stream(request, metadata=metadata)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(response_iterator)
+        self.assertEqual(exception_context.exception.details(),
+                         expected_error_details)
+        self.assertEqual(exception_context.exception.code(),
+                         grpc.StatusCode.INTERNAL)
+        self.assertEqual(response_iterator.details(), expected_error_details)
+        self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
+
+    def testStreamRequestBlockingUnaryResponse(self):
+        request_iterator = (b'\x07\x08'
+                            for _ in range(test_constants.STREAM_LENGTH))
+        metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        with self.assertRaises(ValueError) as exception_context:
+            self._stream_unary(request_iterator, metadata=metadata)
+        self.assertIn(expected_error_details, str(exception_context.exception))
+
+    def testStreamRequestBlockingUnaryResponseWithCall(self):
+        request_iterator = (b'\x07\x08'
+                            for _ in range(test_constants.STREAM_LENGTH))
+        metadata = (('InVaLiD', 'StreamRequestBlockingUnaryResponseWithCall'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self.assertRaises(ValueError) as exception_context:
+            multi_callable.with_call(request_iterator, metadata=metadata)
+        self.assertIn(expected_error_details, str(exception_context.exception))
+
+    def testStreamRequestFutureUnaryResponse(self):
+        request_iterator = (b'\x07\x08'
+                            for _ in range(test_constants.STREAM_LENGTH))
+        metadata = (('InVaLiD', 'StreamRequestFutureUnaryResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        response_future = self._stream_unary.future(
+            request_iterator, metadata=metadata)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertEqual(exception_context.exception.details(),
+                         expected_error_details)
+        self.assertEqual(exception_context.exception.code(),
+                         grpc.StatusCode.INTERNAL)
+        self.assertEqual(response_future.details(), expected_error_details)
+        self.assertEqual(response_future.code(), grpc.StatusCode.INTERNAL)
+
+    def testStreamRequestStreamResponse(self):
+        request_iterator = (b'\x07\x08'
+                            for _ in range(test_constants.STREAM_LENGTH))
+        metadata = (('InVaLiD', 'StreamRequestStreamResponse'),)
+        expected_error_details = "metadata was invalid: %s" % metadata
+        response_iterator = self._stream_stream(
+            request_iterator, metadata=metadata)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(response_iterator)
+        self.assertEqual(exception_context.exception.details(),
+                         expected_error_details)
+        self.assertEqual(exception_context.exception.code(),
+                         grpc.StatusCode.INTERNAL)
+        self.assertEqual(response_iterator.details(), expected_error_details)
+        self.assertEqual(response_iterator.code(), grpc.StatusCode.INTERNAL)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
index 4312679bb9..efeb237874 100644
--- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
@@ -50,106 +50,117 @@ _STREAM_STREAM = '/test/StreamStream'
 
 
 class _Callback(object):
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._value = None
-    self._called = False
 
-  def __call__(self, value):
-    with self._condition:
-      self._value = value
-      self._called = True
-      self._condition.notify_all()
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._value = None
+        self._called = False
 
-  def value(self):
-    with self._condition:
-      while not self._called:
-        self._condition.wait()
-      return self._value
+    def __call__(self, value):
+        with self._condition:
+            self._value = value
+            self._called = True
+            self._condition.notify_all()
+
+    def value(self):
+        with self._condition:
+            while not self._called:
+                self._condition.wait()
+            return self._value
 
 
 class _Handler(object):
-  def __init__(self, control):
-    self._control = control
-
-  def handle_unary_unary(self, request, servicer_context):
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    return request
-
-  def handle_unary_stream(self, request, servicer_context):
-    for _ in range(test_constants.STREAM_LENGTH):
-      self._control.control()
-      yield request
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-
-  def handle_stream_unary(self, request_iterator, servicer_context):
-    if servicer_context is not None:
-      servicer_context.invocation_metadata()
-    self._control.control()
-    response_elements = []
-    for request in request_iterator:
-      self._control.control()
-      response_elements.append(request)
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    return b''.join(response_elements)
-
-  def handle_stream_stream(self, request_iterator, servicer_context):
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    for request in request_iterator:
-      self._control.control()
-      yield request
-    self._control.control()
+
+    def __init__(self, control):
+        self._control = control
+
+    def handle_unary_unary(self, request, servicer_context):
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        return request
+
+    def handle_unary_stream(self, request, servicer_context):
+        for _ in range(test_constants.STREAM_LENGTH):
+            self._control.control()
+            yield request
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+
+    def handle_stream_unary(self, request_iterator, servicer_context):
+        if servicer_context is not None:
+            servicer_context.invocation_metadata()
+        self._control.control()
+        response_elements = []
+        for request in request_iterator:
+            self._control.control()
+            response_elements.append(request)
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        return b''.join(response_elements)
+
+    def handle_stream_stream(self, request_iterator, servicer_context):
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        for request in request_iterator:
+            self._control.control()
+            yield request
+        self._control.control()
 
 
 class _MethodHandler(grpc.RpcMethodHandler):
-  def __init__(
-    self, request_streaming, response_streaming, request_deserializer,
-    response_serializer, unary_unary, unary_stream, stream_unary,
-    stream_stream):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = request_deserializer
-    self.response_serializer = response_serializer
-    self.unary_unary = unary_unary
-    self.unary_stream = unary_stream
-    self.stream_unary = stream_unary
-    self.stream_stream = stream_stream
+
+    def __init__(self, request_streaming, response_streaming,
+                 request_deserializer, response_serializer, unary_unary,
+                 unary_stream, stream_unary, stream_stream):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = request_deserializer
+        self.response_serializer = response_serializer
+        self.unary_unary = unary_unary
+        self.unary_stream = unary_stream
+        self.stream_unary = stream_unary
+        self.stream_stream = stream_stream
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
-  def __init__(self, handler):
-    self._handler = handler
-
-  def service(self, handler_call_details):
-    if handler_call_details.method == _UNARY_UNARY:
-      return _MethodHandler(
-        False, False, None, None, self._handler.handle_unary_unary, None,
-        None, None)
-    elif handler_call_details.method == _UNARY_STREAM:
-      return _MethodHandler(
-        False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None,
-        self._handler.handle_unary_stream, None, None)
-    elif handler_call_details.method == _STREAM_UNARY:
-      return _MethodHandler(
-        True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None,
-        self._handler.handle_stream_unary, None)
-    elif handler_call_details.method == _STREAM_STREAM:
-      return _MethodHandler(
-        True, True, None, None, None, None, None,
-        self._handler.handle_stream_stream)
-    else:
-      return None
+
+    def __init__(self, handler):
+        self._handler = handler
+
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(False, False, None, None,
+                                  self._handler.handle_unary_unary, None, None,
+                                  None)
+        elif handler_call_details.method == _UNARY_STREAM:
+            return _MethodHandler(False, True, _DESERIALIZE_REQUEST,
+                                  _SERIALIZE_RESPONSE, None,
+                                  self._handler.handle_unary_stream, None, None)
+        elif handler_call_details.method == _STREAM_UNARY:
+            return _MethodHandler(True, False, _DESERIALIZE_REQUEST,
+                                  _SERIALIZE_RESPONSE, None, None,
+                                  self._handler.handle_stream_unary, None)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(True, True, None, None, None, None, None,
+                                  self._handler.handle_stream_stream)
+        else:
+            return None
 
 
 class FailAfterFewIterationsCounter(object):
+
     def __init__(self, high, bytestring):
         self._current = 0
         self._high = high
@@ -167,81 +178,82 @@ class FailAfterFewIterationsCounter(object):
 
 
 def _unary_unary_multi_callable(channel):
-  return channel.unary_unary(_UNARY_UNARY)
+    return channel.unary_unary(_UNARY_UNARY)
 
 
 def _unary_stream_multi_callable(channel):
-  return channel.unary_stream(
-    _UNARY_STREAM,
-    request_serializer=_SERIALIZE_REQUEST,
-    response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.unary_stream(
+        _UNARY_STREAM,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_unary_multi_callable(channel):
-  return channel.stream_unary(
-    _STREAM_UNARY,
-    request_serializer=_SERIALIZE_REQUEST,
-    response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.stream_unary(
+        _STREAM_UNARY,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_stream_multi_callable(channel):
-  return channel.stream_stream(_STREAM_STREAM)
+    return channel.stream_stream(_STREAM_STREAM)
 
 
 class InvocationDefectsTest(unittest.TestCase):
-  def setUp(self):
-    self._control = test_control.PauseFailControl()
-    self._handler = _Handler(self._control)
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-
-    self._server = grpc.server(self._server_pool)
-    port = self._server.add_insecure_port('[::]:0')
-    self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
-    self._server.start()
-
-    self._channel = grpc.insecure_channel('localhost:%d' % port)
-
-  def tearDown(self):
-    self._server.stop(0)
-
-  def testIterableStreamRequestBlockingUnaryResponse(self):
-    requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
-    multi_callable = _stream_unary_multi_callable(self._channel)
-
-    with self.assertRaises(grpc.RpcError):
-      response = multi_callable(
-        requests,
-        metadata=(('test', 'IterableStreamRequestBlockingUnaryResponse'),))
-
-  def testIterableStreamRequestFutureUnaryResponse(self):
-    requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    response_future = multi_callable.future(
-      requests,
-      metadata=(
-        ('test', 'IterableStreamRequestFutureUnaryResponse'),))
-
-    with self.assertRaises(grpc.RpcError):
-      response = response_future.result()
-
-  def testIterableStreamRequestStreamResponse(self):
-    requests = [b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)]
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-      requests,
-      metadata=(('test', 'IterableStreamRequestStreamResponse'),))
-
-    with self.assertRaises(grpc.RpcError):
-      next(response_iterator)
-
-  def testIteratorStreamRequestStreamResponse(self):
-    requests_iterator = FailAfterFewIterationsCounter(
-      test_constants.STREAM_LENGTH // 2, b'\x07\x08')
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-      requests_iterator,
-      metadata=(('test', 'IteratorStreamRequestStreamResponse'),))
-
-    with self.assertRaises(grpc.RpcError):
-      for _ in range(test_constants.STREAM_LENGTH // 2 + 1):
-        next(response_iterator)
+
+    def setUp(self):
+        self._control = test_control.PauseFailControl()
+        self._handler = _Handler(self._control)
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+
+        self._server = grpc.server(self._server_pool)
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
+        self._server.start()
+
+        self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+    def tearDown(self):
+        self._server.stop(0)
+
+    def testIterableStreamRequestBlockingUnaryResponse(self):
+        requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
+        multi_callable = _stream_unary_multi_callable(self._channel)
+
+        with self.assertRaises(grpc.RpcError):
+            response = multi_callable(
+                requests,
+                metadata=(
+                    ('test', 'IterableStreamRequestBlockingUnaryResponse'),))
+
+    def testIterableStreamRequestFutureUnaryResponse(self):
+        requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        response_future = multi_callable.future(
+            requests,
+            metadata=(('test', 'IterableStreamRequestFutureUnaryResponse'),))
+
+        with self.assertRaises(grpc.RpcError):
+            response = response_future.result()
+
+    def testIterableStreamRequestStreamResponse(self):
+        requests = [b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)]
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            requests,
+            metadata=(('test', 'IterableStreamRequestStreamResponse'),))
+
+        with self.assertRaises(grpc.RpcError):
+            next(response_iterator)
+
+    def testIteratorStreamRequestStreamResponse(self):
+        requests_iterator = FailAfterFewIterationsCounter(
+            test_constants.STREAM_LENGTH // 2, b'\x07\x08')
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            requests_iterator,
+            metadata=(('test', 'IteratorStreamRequestStreamResponse'),))
+
+        with self.assertRaises(grpc.RpcError):
+            for _ in range(test_constants.STREAM_LENGTH // 2 + 1):
+                next(response_iterator)
diff --git a/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py b/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py b/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py
index eef18f82d6..70f437bc83 100644
--- a/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py
+++ b/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py
@@ -35,7 +35,7 @@
 # source: stock.proto
 
 import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode('latin1'))
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
 from google.protobuf import reflection as _reflection
@@ -45,108 +45,135 @@ from google.protobuf import descriptor_pb2
 
 _sym_db = _symbol_database.Default()
 
-
-
-
 DESCRIPTOR = _descriptor.FileDescriptor(
-  name='stock.proto',
-  package='stock',
-  serialized_pb=_b('\n\x0bstock.proto\x12\x05stock\">\n\x0cStockRequest\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x1e\n\x13num_trades_to_watch\x18\x02 \x01(\x05:\x01\x30\"+\n\nStockReply\x12\r\n\x05price\x18\x01 \x01(\x02\x12\x0e\n\x06symbol\x18\x02 \x01(\t2\x96\x02\n\x05Stock\x12=\n\x11GetLastTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x12I\n\x19GetLastTradePriceMultiple\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01\x30\x01\x12?\n\x11WatchFutureTrades\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x30\x01\x12\x42\n\x14GetHighestTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01')
-)
+    name='stock.proto',
+    package='stock',
+    serialized_pb=_b(
+        '\n\x0bstock.proto\x12\x05stock\">\n\x0cStockRequest\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x1e\n\x13num_trades_to_watch\x18\x02 \x01(\x05:\x01\x30\"+\n\nStockReply\x12\r\n\x05price\x18\x01 \x01(\x02\x12\x0e\n\x06symbol\x18\x02 \x01(\t2\x96\x02\n\x05Stock\x12=\n\x11GetLastTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x12I\n\x19GetLastTradePriceMultiple\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01\x30\x01\x12?\n\x11WatchFutureTrades\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x30\x01\x12\x42\n\x14GetHighestTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01'
+    ))
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-
-
-
 _STOCKREQUEST = _descriptor.Descriptor(
-  name='StockRequest',
-  full_name='stock.StockRequest',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='symbol', full_name='stock.StockRequest.symbol', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='num_trades_to_watch', full_name='stock.StockRequest.num_trades_to_watch', index=1,
-      number=2, type=5, cpp_type=1, label=1,
-      has_default_value=True, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=22,
-  serialized_end=84,
-)
-
+    name='StockRequest',
+    full_name='stock.StockRequest',
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name='symbol',
+            full_name='stock.StockRequest.symbol',
+            index=0,
+            number=1,
+            type=9,
+            cpp_type=9,
+            label=1,
+            has_default_value=False,
+            default_value=_b("").decode('utf-8'),
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='num_trades_to_watch',
+            full_name='stock.StockRequest.num_trades_to_watch',
+            index=1,
+            number=2,
+            type=5,
+            cpp_type=1,
+            label=1,
+            has_default_value=True,
+            default_value=0,
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            options=None),
+    ],
+    extensions=[],
+    nested_types=[],
+    enum_types=[],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    oneofs=[],
+    serialized_start=22,
+    serialized_end=84,)
 
 _STOCKREPLY = _descriptor.Descriptor(
-  name='StockReply',
-  full_name='stock.StockReply',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='price', full_name='stock.StockReply.price', index=0,
-      number=1, type=2, cpp_type=6, label=1,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='symbol', full_name='stock.StockReply.symbol', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=86,
-  serialized_end=129,
-)
+    name='StockReply',
+    full_name='stock.StockReply',
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name='price',
+            full_name='stock.StockReply.price',
+            index=0,
+            number=1,
+            type=2,
+            cpp_type=6,
+            label=1,
+            has_default_value=False,
+            default_value=0,
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            options=None),
+        _descriptor.FieldDescriptor(
+            name='symbol',
+            full_name='stock.StockReply.symbol',
+            index=1,
+            number=2,
+            type=9,
+            cpp_type=9,
+            label=1,
+            has_default_value=False,
+            default_value=_b("").decode('utf-8'),
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            options=None),
+    ],
+    extensions=[],
+    nested_types=[],
+    enum_types=[],
+    options=None,
+    is_extendable=False,
+    extension_ranges=[],
+    oneofs=[],
+    serialized_start=86,
+    serialized_end=129,)
 
 DESCRIPTOR.message_types_by_name['StockRequest'] = _STOCKREQUEST
 DESCRIPTOR.message_types_by_name['StockReply'] = _STOCKREPLY
 
-StockRequest = _reflection.GeneratedProtocolMessageType('StockRequest', (_message.Message,), dict(
-  DESCRIPTOR = _STOCKREQUEST,
-  __module__ = 'stock_pb2'
-  # @@protoc_insertion_point(class_scope:stock.StockRequest)
-  ))
+StockRequest = _reflection.GeneratedProtocolMessageType(
+    'StockRequest',
+    (_message.Message,),
+    dict(
+        DESCRIPTOR=_STOCKREQUEST,
+        __module__='stock_pb2'
+        # @@protoc_insertion_point(class_scope:stock.StockRequest)
+    ))
 _sym_db.RegisterMessage(StockRequest)
 
-StockReply = _reflection.GeneratedProtocolMessageType('StockReply', (_message.Message,), dict(
-  DESCRIPTOR = _STOCKREPLY,
-  __module__ = 'stock_pb2'
-  # @@protoc_insertion_point(class_scope:stock.StockReply)
-  ))
+StockReply = _reflection.GeneratedProtocolMessageType(
+    'StockReply',
+    (_message.Message,),
+    dict(
+        DESCRIPTOR=_STOCKREPLY,
+        __module__='stock_pb2'
+        # @@protoc_insertion_point(class_scope:stock.StockReply)
+    ))
 _sym_db.RegisterMessage(StockReply)
 
-
 # @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
index fb3e547781..af2ce64dce 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests application-provided metadata, status code, and details."""
 
 import threading
@@ -53,20 +52,16 @@ _UNARY_STREAM = 'UnaryStream'
 _STREAM_UNARY = 'StreamUnary'
 _STREAM_STREAM = 'StreamStream'
 
-_CLIENT_METADATA = (
-    ('client-md-key', 'client-md-key'),
-    ('client-md-key-bin', b'\x00\x01')
-)
+_CLIENT_METADATA = (('client-md-key', 'client-md-key'),
+                    ('client-md-key-bin', b'\x00\x01'))
 
 _SERVER_INITIAL_METADATA = (
     ('server-initial-md-key', 'server-initial-md-value'),
-    ('server-initial-md-key-bin', b'\x00\x02')
-)
+    ('server-initial-md-key-bin', b'\x00\x02'))
 
 _SERVER_TRAILING_METADATA = (
     ('server-trailing-md-key', 'server-trailing-md-value'),
-    ('server-trailing-md-key-bin', b'\x00\x03')
-)
+    ('server-trailing-md-key-bin', b'\x00\x03'))
 
 _NON_OK_CODE = grpc.StatusCode.NOT_FOUND
 _DETAILS = 'Test details!'
@@ -74,450 +69,464 @@ _DETAILS = 'Test details!'
 
 class _Servicer(object):
 
-  def __init__(self):
-    self._lock = threading.Lock()
-    self._code = None
-    self._details = None
-    self._exception = False
-    self._return_none = False
-    self._received_client_metadata = None
-
-  def unary_unary(self, request, context):
-    with self._lock:
-      self._received_client_metadata = context.invocation_metadata()
-      context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-      context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-      if self._code is not None:
-        context.set_code(self._code)
-      if self._details is not None:
-        context.set_details(self._details)
-      if self._exception:
-        raise test_control.Defect()
-      else:
-        return None if self._return_none else object()
-
-  def unary_stream(self, request, context):
-    with self._lock:
-      self._received_client_metadata = context.invocation_metadata()
-      context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-      context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-      if self._code is not None:
-        context.set_code(self._code)
-      if self._details is not None:
-        context.set_details(self._details)
-      for _ in range(test_constants.STREAM_LENGTH // 2):
-        yield _SERIALIZED_RESPONSE
-      if self._exception:
-        raise test_control.Defect()
-
-  def stream_unary(self, request_iterator, context):
-    with self._lock:
-      self._received_client_metadata = context.invocation_metadata()
-      context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-      context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-      if self._code is not None:
-        context.set_code(self._code)
-      if self._details is not None:
-        context.set_details(self._details)
-      # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the
-      # request iterator.
-      for ignored_request in request_iterator:
-        pass
-      if self._exception:
-        raise test_control.Defect()
-      else:
-        return None if self._return_none else _SERIALIZED_RESPONSE
-
-  def stream_stream(self, request_iterator, context):
-    with self._lock:
-      self._received_client_metadata = context.invocation_metadata()
-      context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-      context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-      if self._code is not None:
-        context.set_code(self._code)
-      if self._details is not None:
-        context.set_details(self._details)
-      # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the
-      # request iterator.
-      for ignored_request in request_iterator:
-        pass
-      for _ in range(test_constants.STREAM_LENGTH // 3):
-        yield object()
-      if self._exception:
-        raise test_control.Defect()
-
-  def set_code(self, code):
-    with self._lock:
-      self._code = code
-
-  def set_details(self, details):
-    with self._lock:
-      self._details = details
-
-  def set_exception(self):
-    with self._lock:
-      self._exception = True
-
-  def set_return_none(self):
-    with self._lock:
-      self._return_none = True
-
-  def received_client_metadata(self):
-    with self._lock:
-      return self._received_client_metadata
+    def __init__(self):
+        self._lock = threading.Lock()
+        self._code = None
+        self._details = None
+        self._exception = False
+        self._return_none = False
+        self._received_client_metadata = None
+
+    def unary_unary(self, request, context):
+        with self._lock:
+            self._received_client_metadata = context.invocation_metadata()
+            context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+            context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+            if self._code is not None:
+                context.set_code(self._code)
+            if self._details is not None:
+                context.set_details(self._details)
+            if self._exception:
+                raise test_control.Defect()
+            else:
+                return None if self._return_none else object()
+
+    def unary_stream(self, request, context):
+        with self._lock:
+            self._received_client_metadata = context.invocation_metadata()
+            context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+            context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+            if self._code is not None:
+                context.set_code(self._code)
+            if self._details is not None:
+                context.set_details(self._details)
+            for _ in range(test_constants.STREAM_LENGTH // 2):
+                yield _SERIALIZED_RESPONSE
+            if self._exception:
+                raise test_control.Defect()
+
+    def stream_unary(self, request_iterator, context):
+        with self._lock:
+            self._received_client_metadata = context.invocation_metadata()
+            context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+            context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+            if self._code is not None:
+                context.set_code(self._code)
+            if self._details is not None:
+                context.set_details(self._details)
+            # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the
+            # request iterator.
+            for ignored_request in request_iterator:
+                pass
+            if self._exception:
+                raise test_control.Defect()
+            else:
+                return None if self._return_none else _SERIALIZED_RESPONSE
+
+    def stream_stream(self, request_iterator, context):
+        with self._lock:
+            self._received_client_metadata = context.invocation_metadata()
+            context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+            context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+            if self._code is not None:
+                context.set_code(self._code)
+            if self._details is not None:
+                context.set_details(self._details)
+            # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the
+            # request iterator.
+            for ignored_request in request_iterator:
+                pass
+            for _ in range(test_constants.STREAM_LENGTH // 3):
+                yield object()
+            if self._exception:
+                raise test_control.Defect()
+
+    def set_code(self, code):
+        with self._lock:
+            self._code = code
+
+    def set_details(self, details):
+        with self._lock:
+            self._details = details
+
+    def set_exception(self):
+        with self._lock:
+            self._exception = True
+
+    def set_return_none(self):
+        with self._lock:
+            self._return_none = True
+
+    def received_client_metadata(self):
+        with self._lock:
+            return self._received_client_metadata
 
 
 def _generic_handler(servicer):
-  method_handlers = {
-      _UNARY_UNARY: grpc.unary_unary_rpc_method_handler(
-          servicer.unary_unary, request_deserializer=_REQUEST_DESERIALIZER,
-          response_serializer=_RESPONSE_SERIALIZER),
-      _UNARY_STREAM: grpc.unary_stream_rpc_method_handler(
-          servicer.unary_stream),
-      _STREAM_UNARY: grpc.stream_unary_rpc_method_handler(
-          servicer.stream_unary),
-      _STREAM_STREAM: grpc.stream_stream_rpc_method_handler(
-          servicer.stream_stream, request_deserializer=_REQUEST_DESERIALIZER,
-          response_serializer=_RESPONSE_SERIALIZER),
-  }
-  return grpc.method_handlers_generic_handler(_SERVICE, method_handlers)
+    method_handlers = {
+        _UNARY_UNARY: grpc.unary_unary_rpc_method_handler(
+            servicer.unary_unary,
+            request_deserializer=_REQUEST_DESERIALIZER,
+            response_serializer=_RESPONSE_SERIALIZER),
+        _UNARY_STREAM:
+        grpc.unary_stream_rpc_method_handler(servicer.unary_stream),
+        _STREAM_UNARY:
+        grpc.stream_unary_rpc_method_handler(servicer.stream_unary),
+        _STREAM_STREAM: grpc.stream_stream_rpc_method_handler(
+            servicer.stream_stream,
+            request_deserializer=_REQUEST_DESERIALIZER,
+            response_serializer=_RESPONSE_SERIALIZER),
+    }
+    return grpc.method_handlers_generic_handler(_SERVICE, method_handlers)
 
 
 class MetadataCodeDetailsTest(unittest.TestCase):
 
-  def setUp(self):
-    self._servicer = _Servicer()
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(
-        self._server_pool, handlers=(_generic_handler(self._servicer),))
-    port = self._server.add_insecure_port('[::]:0')
-    self._server.start()
-
-    channel = grpc.insecure_channel('localhost:{}'.format(port))
-    self._unary_unary = channel.unary_unary(
-        '/'.join(('', _SERVICE, _UNARY_UNARY,)),
-        request_serializer=_REQUEST_SERIALIZER,
-        response_deserializer=_RESPONSE_DESERIALIZER,)
-    self._unary_stream = channel.unary_stream(
-        '/'.join(('', _SERVICE, _UNARY_STREAM,)),)
-    self._stream_unary = channel.stream_unary(
-        '/'.join(('', _SERVICE, _STREAM_UNARY,)),)
-    self._stream_stream = channel.stream_stream(
-        '/'.join(('', _SERVICE, _STREAM_STREAM,)),
-        request_serializer=_REQUEST_SERIALIZER,
-        response_deserializer=_RESPONSE_DESERIALIZER,)
-
-
-  def testSuccessfulUnaryUnary(self):
-    self._servicer.set_details(_DETAILS)
-
-    unused_response, call = self._unary_unary.with_call(
-        object(), metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(grpc.StatusCode.OK, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testSuccessfulUnaryStream(self):
-    self._servicer.set_details(_DETAILS)
-
-    call = self._unary_stream(_SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    for _ in call:
-      pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(grpc.StatusCode.OK, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testSuccessfulStreamUnary(self):
-    self._servicer.set_details(_DETAILS)
-
-    unused_response, call = self._stream_unary.with_call(
-        iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
-        metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(grpc.StatusCode.OK, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testSuccessfulStreamStream(self):
-    self._servicer.set_details(_DETAILS)
-
-    call = self._stream_stream(
-        iter([object()] * test_constants.STREAM_LENGTH),
-        metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    for _ in call:
-      pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(grpc.StatusCode.OK, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testCustomCodeUnaryUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA,
-            exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeUnaryStream(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-
-    call = self._unary_stream(_SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    with self.assertRaises(grpc.RpcError):
-      for _ in call:
-        pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testCustomCodeStreamUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._stream_unary.with_call(
-          iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
-          metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-          _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-          _SERVER_INITIAL_METADATA,
-          exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-          _SERVER_TRAILING_METADATA,
-          exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeStreamStream(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-
-    call = self._stream_stream(
-        iter([object()] * test_constants.STREAM_LENGTH),
-        metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      for _ in call:
-        pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-          _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeExceptionUnaryUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_exception()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-     self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA,
-            exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeExceptionUnaryStream(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_exception()
-
-    call = self._unary_stream(_SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    with self.assertRaises(grpc.RpcError):
-      for _ in call:
-        pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testCustomCodeExceptionStreamUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_exception()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._stream_unary.with_call(
-          iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
-          metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA,
-            exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeExceptionStreamStream(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_exception()
-
-    call = self._stream_stream(
-        iter([object()] * test_constants.STREAM_LENGTH),
-        metadata=_CLIENT_METADATA)
-    received_initial_metadata = call.initial_metadata()
-    with self.assertRaises(grpc.RpcError):
-      for _ in call:
-        pass
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA, received_initial_metadata))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, call.code())
-    self.assertEqual(_DETAILS, call.details())
-
-  def testCustomCodeReturnNoneUnaryUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_return_none()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA,
-            exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
-
-  def testCustomCodeReturnNoneStreamUnary(self):
-    self._servicer.set_code(_NON_OK_CODE)
-    self._servicer.set_details(_DETAILS)
-    self._servicer.set_return_none()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._stream_unary.with_call(
-          iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
-          metadata=_CLIENT_METADATA)
-
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _CLIENT_METADATA, self._servicer.received_client_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_INITIAL_METADATA,
-            exception_context.exception.initial_metadata()))
-    self.assertTrue(
-        test_common.metadata_transmitted(
-            _SERVER_TRAILING_METADATA,
-            exception_context.exception.trailing_metadata()))
-    self.assertIs(_NON_OK_CODE, exception_context.exception.code())
-    self.assertEqual(_DETAILS, exception_context.exception.details())
+    def setUp(self):
+        self._servicer = _Servicer()
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(
+            self._server_pool, handlers=(_generic_handler(self._servicer),))
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.start()
+
+        channel = grpc.insecure_channel('localhost:{}'.format(port))
+        self._unary_unary = channel.unary_unary(
+            '/'.join((
+                '',
+                _SERVICE,
+                _UNARY_UNARY,)),
+            request_serializer=_REQUEST_SERIALIZER,
+            response_deserializer=_RESPONSE_DESERIALIZER,)
+        self._unary_stream = channel.unary_stream('/'.join((
+            '',
+            _SERVICE,
+            _UNARY_STREAM,)),)
+        self._stream_unary = channel.stream_unary('/'.join((
+            '',
+            _SERVICE,
+            _STREAM_UNARY,)),)
+        self._stream_stream = channel.stream_stream(
+            '/'.join((
+                '',
+                _SERVICE,
+                _STREAM_STREAM,)),
+            request_serializer=_REQUEST_SERIALIZER,
+            response_deserializer=_RESPONSE_DESERIALIZER,)
+
+    def testSuccessfulUnaryUnary(self):
+        self._servicer.set_details(_DETAILS)
+
+        unused_response, call = self._unary_unary.with_call(
+            object(), metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(grpc.StatusCode.OK, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testSuccessfulUnaryStream(self):
+        self._servicer.set_details(_DETAILS)
+
+        call = self._unary_stream(
+            _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        for _ in call:
+            pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(grpc.StatusCode.OK, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testSuccessfulStreamUnary(self):
+        self._servicer.set_details(_DETAILS)
+
+        unused_response, call = self._stream_unary.with_call(
+            iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(grpc.StatusCode.OK, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testSuccessfulStreamStream(self):
+        self._servicer.set_details(_DETAILS)
+
+        call = self._stream_stream(
+            iter([object()] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        for _ in call:
+            pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(grpc.StatusCode.OK, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testCustomCodeUnaryUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeUnaryStream(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+
+        call = self._unary_stream(
+            _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        with self.assertRaises(grpc.RpcError):
+            for _ in call:
+                pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testCustomCodeStreamUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._stream_unary.with_call(
+                iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
+                metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeStreamStream(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+
+        call = self._stream_stream(
+            iter([object()] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            for _ in call:
+                pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeExceptionUnaryUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_exception()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeExceptionUnaryStream(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_exception()
+
+        call = self._unary_stream(
+            _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        with self.assertRaises(grpc.RpcError):
+            for _ in call:
+                pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testCustomCodeExceptionStreamUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_exception()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._stream_unary.with_call(
+                iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
+                metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeExceptionStreamStream(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_exception()
+
+        call = self._stream_stream(
+            iter([object()] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+        received_initial_metadata = call.initial_metadata()
+        with self.assertRaises(grpc.RpcError):
+            for _ in call:
+                pass
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             received_initial_metadata))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, call.code())
+        self.assertEqual(_DETAILS, call.details())
+
+    def testCustomCodeReturnNoneUnaryUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_return_none()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
+
+    def testCustomCodeReturnNoneStreamUnary(self):
+        self._servicer.set_code(_NON_OK_CODE)
+        self._servicer.set_details(_DETAILS)
+        self._servicer.set_return_none()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._stream_unary.with_call(
+                iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH),
+                metadata=_CLIENT_METADATA)
+
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _CLIENT_METADATA, self._servicer.received_client_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_INITIAL_METADATA,
+                exception_context.exception.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(
+                _SERVER_TRAILING_METADATA,
+                exception_context.exception.trailing_metadata()))
+        self.assertIs(_NON_OK_CODE, exception_context.exception.code())
+        self.assertEqual(_DETAILS, exception_context.exception.details())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py
index caba53ffcc..53fe7ba8aa 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py
@@ -51,166 +51,174 @@ _STREAM_STREAM = '/test/StreamStream'
 
 _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
 
-_CLIENT_METADATA = (
-    ('client-md-key', 'client-md-key'),
-    ('client-md-key-bin', b'\x00\x01')
-)
+_CLIENT_METADATA = (('client-md-key', 'client-md-key'),
+                    ('client-md-key-bin', b'\x00\x01'))
 
 _SERVER_INITIAL_METADATA = (
     ('server-initial-md-key', 'server-initial-md-value'),
-    ('server-initial-md-key-bin', b'\x00\x02')
-)
+    ('server-initial-md-key-bin', b'\x00\x02'))
 
 _SERVER_TRAILING_METADATA = (
     ('server-trailing-md-key', 'server-trailing-md-value'),
-    ('server-trailing-md-key-bin', b'\x00\x03')
-)
+    ('server-trailing-md-key-bin', b'\x00\x03'))
 
 
 def user_agent(metadata):
-  for key, val in metadata:
-    if key == 'user-agent':
-      return val
-  raise KeyError('No user agent!')
+    for key, val in metadata:
+        if key == 'user-agent':
+            return val
+    raise KeyError('No user agent!')
 
 
 def validate_client_metadata(test, servicer_context):
-  test.assertTrue(test_common.metadata_transmitted(
-      _CLIENT_METADATA, servicer_context.invocation_metadata()))
-  test.assertTrue(user_agent(servicer_context.invocation_metadata())
-                  .startswith('primary-agent ' + _USER_AGENT))
-  test.assertTrue(user_agent(servicer_context.invocation_metadata())
-                  .endswith('secondary-agent'))
+    test.assertTrue(
+        test_common.metadata_transmitted(
+            _CLIENT_METADATA, servicer_context.invocation_metadata()))
+    test.assertTrue(
+        user_agent(servicer_context.invocation_metadata())
+        .startswith('primary-agent ' + _USER_AGENT))
+    test.assertTrue(
+        user_agent(servicer_context.invocation_metadata())
+        .endswith('secondary-agent'))
 
 
 def handle_unary_unary(test, request, servicer_context):
-  validate_client_metadata(test, servicer_context)
-  servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-  servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-  return _RESPONSE
+    validate_client_metadata(test, servicer_context)
+    servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+    servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+    return _RESPONSE
 
 
 def handle_unary_stream(test, request, servicer_context):
-  validate_client_metadata(test, servicer_context)
-  servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-  servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-  for _ in range(test_constants.STREAM_LENGTH):
-    yield _RESPONSE
+    validate_client_metadata(test, servicer_context)
+    servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+    servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+    for _ in range(test_constants.STREAM_LENGTH):
+        yield _RESPONSE
 
 
 def handle_stream_unary(test, request_iterator, servicer_context):
-  validate_client_metadata(test, servicer_context)
-  servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-  servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-  # TODO(issue:#6891) We should be able to remove this loop
-  for request in request_iterator:
-    pass
-  return _RESPONSE
+    validate_client_metadata(test, servicer_context)
+    servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+    servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+    # TODO(issue:#6891) We should be able to remove this loop
+    for request in request_iterator:
+        pass
+    return _RESPONSE
 
 
 def handle_stream_stream(test, request_iterator, servicer_context):
-  validate_client_metadata(test, servicer_context)
-  servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
-  servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
-  # TODO(issue:#6891) We should be able to remove this loop,
-  # and replace with return; yield
-  for request in request_iterator:
-    yield _RESPONSE
+    validate_client_metadata(test, servicer_context)
+    servicer_context.send_initial_metadata(_SERVER_INITIAL_METADATA)
+    servicer_context.set_trailing_metadata(_SERVER_TRAILING_METADATA)
+    # TODO(issue:#6891) We should be able to remove this loop,
+    # and replace with return; yield
+    for request in request_iterator:
+        yield _RESPONSE
 
 
 class _MethodHandler(grpc.RpcMethodHandler):
 
-  def __init__(self, test, request_streaming, response_streaming):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = None
-    self.response_serializer = None
-    self.unary_unary = None
-    self.unary_stream = None
-    self.stream_unary = None
-    self.stream_stream = None
-    if self.request_streaming and self.response_streaming:
-      self.stream_stream = lambda x, y: handle_stream_stream(test, x, y)
-    elif self.request_streaming:
-      self.stream_unary = lambda x, y: handle_stream_unary(test, x, y)
-    elif self.response_streaming:
-      self.unary_stream = lambda x, y: handle_unary_stream(test, x, y)
-    else:
-      self.unary_unary = lambda x, y: handle_unary_unary(test, x, y)
+    def __init__(self, test, request_streaming, response_streaming):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = None
+        self.response_serializer = None
+        self.unary_unary = None
+        self.unary_stream = None
+        self.stream_unary = None
+        self.stream_stream = None
+        if self.request_streaming and self.response_streaming:
+            self.stream_stream = lambda x, y: handle_stream_stream(test, x, y)
+        elif self.request_streaming:
+            self.stream_unary = lambda x, y: handle_stream_unary(test, x, y)
+        elif self.response_streaming:
+            self.unary_stream = lambda x, y: handle_unary_stream(test, x, y)
+        else:
+            self.unary_unary = lambda x, y: handle_unary_unary(test, x, y)
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
 
-  def __init__(self, test):
-    self._test = test
+    def __init__(self, test):
+        self._test = test
 
-  def service(self, handler_call_details):
-    if handler_call_details.method == _UNARY_UNARY:
-      return _MethodHandler(self._test, False, False)
-    elif handler_call_details.method == _UNARY_STREAM:
-      return _MethodHandler(self._test, False, True)
-    elif handler_call_details.method == _STREAM_UNARY:
-      return _MethodHandler(self._test, True, False)
-    elif handler_call_details.method == _STREAM_STREAM:
-      return _MethodHandler(self._test, True, True)
-    else:
-      return None
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(self._test, False, False)
+        elif handler_call_details.method == _UNARY_STREAM:
+            return _MethodHandler(self._test, False, True)
+        elif handler_call_details.method == _STREAM_UNARY:
+            return _MethodHandler(self._test, True, False)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(self._test, True, True)
+        else:
+            return None
 
 
 class MetadataTest(unittest.TestCase):
 
-  def setUp(self):
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    self._server = grpc.server(
-        self._server_pool, handlers=(_GenericHandler(weakref.proxy(self)),))
-    port = self._server.add_insecure_port('[::]:0')
-    self._server.start()
-    self._channel = grpc.insecure_channel('localhost:%d' % port,
-                                          options=_CHANNEL_ARGS)
-
-  def tearDown(self):
-    self._server.stop(0)
-
-  def testUnaryUnary(self):
-    multi_callable = self._channel.unary_unary(_UNARY_UNARY)
-    unused_response, call = multi_callable.with_call(
-        _REQUEST, metadata=_CLIENT_METADATA)
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-
-  def testUnaryStream(self):
-    multi_callable = self._channel.unary_stream(_UNARY_STREAM)
-    call = multi_callable(_REQUEST, metadata=_CLIENT_METADATA)
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    for _ in call:
-      pass
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-
-  def testStreamUnary(self):
-    multi_callable = self._channel.stream_unary(_STREAM_UNARY)
-    unused_response, call = multi_callable.with_call(
-        iter([_REQUEST] * test_constants.STREAM_LENGTH),
-        metadata=_CLIENT_METADATA)
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_TRAILING_METADATA, call.trailing_metadata()))
-
-  def testStreamStream(self):
-    multi_callable = self._channel.stream_stream(_STREAM_STREAM)
-    call = multi_callable(iter([_REQUEST] * test_constants.STREAM_LENGTH),
-                          metadata=_CLIENT_METADATA)
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_INITIAL_METADATA, call.initial_metadata()))
-    for _ in call:
-      pass
-    self.assertTrue(test_common.metadata_transmitted(
-        _SERVER_TRAILING_METADATA, call.trailing_metadata()))
+    def setUp(self):
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        self._server = grpc.server(
+            self._server_pool, handlers=(_GenericHandler(weakref.proxy(self)),))
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.start()
+        self._channel = grpc.insecure_channel(
+            'localhost:%d' % port, options=_CHANNEL_ARGS)
+
+    def tearDown(self):
+        self._server.stop(0)
+
+    def testUnaryUnary(self):
+        multi_callable = self._channel.unary_unary(_UNARY_UNARY)
+        unused_response, call = multi_callable.with_call(
+            _REQUEST, metadata=_CLIENT_METADATA)
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+
+    def testUnaryStream(self):
+        multi_callable = self._channel.unary_stream(_UNARY_STREAM)
+        call = multi_callable(_REQUEST, metadata=_CLIENT_METADATA)
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        for _ in call:
+            pass
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+
+    def testStreamUnary(self):
+        multi_callable = self._channel.stream_unary(_STREAM_UNARY)
+        unused_response, call = multi_callable.with_call(
+            iter([_REQUEST] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
+
+    def testStreamStream(self):
+        multi_callable = self._channel.stream_stream(_STREAM_STREAM)
+        call = multi_callable(
+            iter([_REQUEST] * test_constants.STREAM_LENGTH),
+            metadata=_CLIENT_METADATA)
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_INITIAL_METADATA,
+                                             call.initial_metadata()))
+        for _ in call:
+            pass
+        self.assertTrue(
+            test_common.metadata_transmitted(_SERVER_TRAILING_METADATA,
+                                             call.trailing_metadata()))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py
index eb00156da5..2cf6dfea62 100644
--- a/src/python/grpcio_tests/tests/unit/_rpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py
@@ -26,7 +26,6 @@
 # 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 of RPCs made against gRPC Python's application-layer API."""
 
 import itertools
@@ -53,742 +52,797 @@ _STREAM_STREAM = '/test/StreamStream'
 
 class _Callback(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._value = None
-    self._called = False
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._value = None
+        self._called = False
 
-  def __call__(self, value):
-    with self._condition:
-      self._value = value
-      self._called = True
-      self._condition.notify_all()
+    def __call__(self, value):
+        with self._condition:
+            self._value = value
+            self._called = True
+            self._condition.notify_all()
 
-  def value(self):
-    with self._condition:
-      while not self._called:
-        self._condition.wait()
-      return self._value
+    def value(self):
+        with self._condition:
+            while not self._called:
+                self._condition.wait()
+            return self._value
 
 
 class _Handler(object):
 
-  def __init__(self, control):
-    self._control = control
-
-  def handle_unary_unary(self, request, servicer_context):
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    return request
-
-  def handle_unary_stream(self, request, servicer_context):
-    for _ in range(test_constants.STREAM_LENGTH):
-      self._control.control()
-      yield request
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-
-  def handle_stream_unary(self, request_iterator, servicer_context):
-    if servicer_context is not None:
-      servicer_context.invocation_metadata()
-    self._control.control()
-    response_elements = []
-    for request in request_iterator:
-      self._control.control()
-      response_elements.append(request)
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    return b''.join(response_elements)
-
-  def handle_stream_stream(self, request_iterator, servicer_context):
-    self._control.control()
-    if servicer_context is not None:
-      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
-    for request in request_iterator:
-      self._control.control()
-      yield request
-    self._control.control()
+    def __init__(self, control):
+        self._control = control
+
+    def handle_unary_unary(self, request, servicer_context):
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        return request
+
+    def handle_unary_stream(self, request, servicer_context):
+        for _ in range(test_constants.STREAM_LENGTH):
+            self._control.control()
+            yield request
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+
+    def handle_stream_unary(self, request_iterator, servicer_context):
+        if servicer_context is not None:
+            servicer_context.invocation_metadata()
+        self._control.control()
+        response_elements = []
+        for request in request_iterator:
+            self._control.control()
+            response_elements.append(request)
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        return b''.join(response_elements)
+
+    def handle_stream_stream(self, request_iterator, servicer_context):
+        self._control.control()
+        if servicer_context is not None:
+            servicer_context.set_trailing_metadata(((
+                'testkey',
+                'testvalue',),))
+        for request in request_iterator:
+            self._control.control()
+            yield request
+        self._control.control()
 
 
 class _MethodHandler(grpc.RpcMethodHandler):
 
-  def __init__(
-      self, request_streaming, response_streaming, request_deserializer,
-      response_serializer, unary_unary, unary_stream, stream_unary,
-      stream_stream):
-    self.request_streaming = request_streaming
-    self.response_streaming = response_streaming
-    self.request_deserializer = request_deserializer
-    self.response_serializer = response_serializer
-    self.unary_unary = unary_unary
-    self.unary_stream = unary_stream
-    self.stream_unary = stream_unary
-    self.stream_stream = stream_stream
+    def __init__(self, request_streaming, response_streaming,
+                 request_deserializer, response_serializer, unary_unary,
+                 unary_stream, stream_unary, stream_stream):
+        self.request_streaming = request_streaming
+        self.response_streaming = response_streaming
+        self.request_deserializer = request_deserializer
+        self.response_serializer = response_serializer
+        self.unary_unary = unary_unary
+        self.unary_stream = unary_stream
+        self.stream_unary = stream_unary
+        self.stream_stream = stream_stream
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
 
-  def __init__(self, handler):
-    self._handler = handler
-
-  def service(self, handler_call_details):
-    if handler_call_details.method == _UNARY_UNARY:
-      return _MethodHandler(
-          False, False, None, None, self._handler.handle_unary_unary, None,
-          None, None)
-    elif handler_call_details.method == _UNARY_STREAM:
-      return _MethodHandler(
-        False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None,
-        self._handler.handle_unary_stream, None, None)
-    elif handler_call_details.method == _STREAM_UNARY:
-      return _MethodHandler(
-          True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None,
-          self._handler.handle_stream_unary, None)
-    elif handler_call_details.method == _STREAM_STREAM:
-      return _MethodHandler(
-          True, True, None, None, None, None, None,
-          self._handler.handle_stream_stream)
-    else:
-      return None
+    def __init__(self, handler):
+        self._handler = handler
+
+    def service(self, handler_call_details):
+        if handler_call_details.method == _UNARY_UNARY:
+            return _MethodHandler(False, False, None, None,
+                                  self._handler.handle_unary_unary, None, None,
+                                  None)
+        elif handler_call_details.method == _UNARY_STREAM:
+            return _MethodHandler(False, True, _DESERIALIZE_REQUEST,
+                                  _SERIALIZE_RESPONSE, None,
+                                  self._handler.handle_unary_stream, None, None)
+        elif handler_call_details.method == _STREAM_UNARY:
+            return _MethodHandler(True, False, _DESERIALIZE_REQUEST,
+                                  _SERIALIZE_RESPONSE, None, None,
+                                  self._handler.handle_stream_unary, None)
+        elif handler_call_details.method == _STREAM_STREAM:
+            return _MethodHandler(True, True, None, None, None, None, None,
+                                  self._handler.handle_stream_stream)
+        else:
+            return None
 
 
 def _unary_unary_multi_callable(channel):
-  return channel.unary_unary(_UNARY_UNARY)
+    return channel.unary_unary(_UNARY_UNARY)
 
 
 def _unary_stream_multi_callable(channel):
-  return channel.unary_stream(
-      _UNARY_STREAM,
-      request_serializer=_SERIALIZE_REQUEST,
-      response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.unary_stream(
+        _UNARY_STREAM,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_unary_multi_callable(channel):
-  return channel.stream_unary(
-      _STREAM_UNARY,
-      request_serializer=_SERIALIZE_REQUEST,
-      response_deserializer=_DESERIALIZE_RESPONSE)
+    return channel.stream_unary(
+        _STREAM_UNARY,
+        request_serializer=_SERIALIZE_REQUEST,
+        response_deserializer=_DESERIALIZE_RESPONSE)
 
 
 def _stream_stream_multi_callable(channel):
-  return channel.stream_stream(_STREAM_STREAM)
+    return channel.stream_stream(_STREAM_STREAM)
 
 
 class RPCTest(unittest.TestCase):
 
-  def setUp(self):
-    self._control = test_control.PauseFailControl()
-    self._handler = _Handler(self._control)
-    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    def setUp(self):
+        self._control = test_control.PauseFailControl()
+        self._handler = _Handler(self._control)
+        self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
 
-    self._server = grpc.server(self._server_pool)
-    port = self._server.add_insecure_port('[::]:0')
-    self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
-    self._server.start()
+        self._server = grpc.server(self._server_pool)
+        port = self._server.add_insecure_port('[::]:0')
+        self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
+        self._server.start()
 
-    self._channel = grpc.insecure_channel('localhost:%d' % port)
-
-  def tearDown(self):
-    self._server.stop(None)
-    self._server_pool.shutdown(wait=True)
-
-  def testUnrecognizedMethod(self):
-    request = b'abc'
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      self._channel.unary_unary('NoSuchMethod')(request)
-
-    self.assertEqual(
-        grpc.StatusCode.UNIMPLEMENTED, exception_context.exception.code())
-
-  def testSuccessfulUnaryRequestBlockingUnaryResponse(self):
-    request = b'\x07\x08'
-    expected_response = self._handler.handle_unary_unary(request, None)
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    response = multi_callable(
-        request, metadata=(
-            ('test', 'SuccessfulUnaryRequestBlockingUnaryResponse'),))
-
-    self.assertEqual(expected_response, response)
-
-  def testSuccessfulUnaryRequestBlockingUnaryResponseWithCall(self):
-    request = b'\x07\x08'
-    expected_response = self._handler.handle_unary_unary(request, None)
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    response, call = multi_callable.with_call(
-        request, metadata=(
-            ('test', 'SuccessfulUnaryRequestBlockingUnaryResponseWithCall'),))
-
-    self.assertEqual(expected_response, response)
-    self.assertIs(grpc.StatusCode.OK, call.code())
-
-  def testSuccessfulUnaryRequestFutureUnaryResponse(self):
-    request = b'\x07\x08'
-    expected_response = self._handler.handle_unary_unary(request, None)
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    response_future = multi_callable.future(
-        request, metadata=(
-            ('test', 'SuccessfulUnaryRequestFutureUnaryResponse'),))
-    response = response_future.result()
-
-    self.assertIsInstance(response_future, grpc.Future)
-    self.assertIsInstance(response_future, grpc.Call)
-    self.assertEqual(expected_response, response)
-    self.assertIsNone(response_future.exception())
-    self.assertIsNone(response_future.traceback())
-
-  def testSuccessfulUnaryRequestStreamResponse(self):
-    request = b'\x37\x58'
-    expected_responses = tuple(self._handler.handle_unary_stream(request, None))
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request,
-        metadata=(('test', 'SuccessfulUnaryRequestStreamResponse'),))
-    responses = tuple(response_iterator)
-
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testSuccessfulStreamRequestBlockingUnaryResponse(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    expected_response = self._handler.handle_stream_unary(iter(requests), None)
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    response = multi_callable(
-        request_iterator,
-        metadata=(('test', 'SuccessfulStreamRequestBlockingUnaryResponse'),))
-
-    self.assertEqual(expected_response, response)
-
-  def testSuccessfulStreamRequestBlockingUnaryResponseWithCall(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    expected_response = self._handler.handle_stream_unary(iter(requests), None)
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    response, call = multi_callable.with_call(
-        request_iterator,
-        metadata=(
-            ('test', 'SuccessfulStreamRequestBlockingUnaryResponseWithCall'),
-        ))
-
-    self.assertEqual(expected_response, response)
-    self.assertIs(grpc.StatusCode.OK, call.code())
-
-  def testSuccessfulStreamRequestFutureUnaryResponse(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    expected_response = self._handler.handle_stream_unary(iter(requests), None)
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    response_future = multi_callable.future(
-        request_iterator,
-        metadata=(
-            ('test', 'SuccessfulStreamRequestFutureUnaryResponse'),))
-    response = response_future.result()
-
-    self.assertEqual(expected_response, response)
-    self.assertIsNone(response_future.exception())
-    self.assertIsNone(response_future.traceback())
-
-  def testSuccessfulStreamRequestStreamResponse(self):
-    requests = tuple(b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH))
-    expected_responses = tuple(
-        self._handler.handle_stream_stream(iter(requests), None))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request_iterator,
-        metadata=(('test', 'SuccessfulStreamRequestStreamResponse'),))
-    responses = tuple(response_iterator)
-
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testSequentialInvocations(self):
-    first_request = b'\x07\x08'
-    second_request = b'\x0809'
-    expected_first_response = self._handler.handle_unary_unary(
-        first_request, None)
-    expected_second_response = self._handler.handle_unary_unary(
-        second_request, None)
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    first_response = multi_callable(
-        first_request, metadata=(('test', 'SequentialInvocations'),))
-    second_response = multi_callable(
-        second_request, metadata=(('test', 'SequentialInvocations'),))
-
-    self.assertEqual(expected_first_response, first_response)
-    self.assertEqual(expected_second_response, second_response)
-
-  def testConcurrentBlockingInvocations(self):
-    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    expected_response = self._handler.handle_stream_unary(iter(requests), None)
-    expected_responses = [expected_response] * test_constants.THREAD_CONCURRENCY
-    response_futures = [None] * test_constants.THREAD_CONCURRENCY
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    for index in range(test_constants.THREAD_CONCURRENCY):
-      request_iterator = iter(requests)
-      response_future = pool.submit(
-          multi_callable, request_iterator,
-          metadata=(('test', 'ConcurrentBlockingInvocations'),))
-      response_futures[index] = response_future
-    responses = tuple(
-        response_future.result() for response_future in response_futures)
-
-    pool.shutdown(wait=True)
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testConcurrentFutureInvocations(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    expected_response = self._handler.handle_stream_unary(iter(requests), None)
-    expected_responses = [expected_response] * test_constants.THREAD_CONCURRENCY
-    response_futures = [None] * test_constants.THREAD_CONCURRENCY
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    for index in range(test_constants.THREAD_CONCURRENCY):
-      request_iterator = iter(requests)
-      response_future = multi_callable.future(
-          request_iterator,
-          metadata=(('test', 'ConcurrentFutureInvocations'),))
-      response_futures[index] = response_future
-    responses = tuple(
-        response_future.result() for response_future in response_futures)
-
-    self.assertSequenceEqual(expected_responses, responses)
-
-  def testWaitingForSomeButNotAllConcurrentFutureInvocations(self):
-    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    request = b'\x67\x68'
-    expected_response = self._handler.handle_unary_unary(request, None)
-    response_futures = [None] * test_constants.THREAD_CONCURRENCY
-    lock = threading.Lock()
-    test_is_running_cell = [True]
-    def wrap_future(future):
-      def wrap():
-        try:
-          return future.result()
-        except grpc.RpcError:
-          with lock:
-            if test_is_running_cell[0]:
-              raise
-          return None
-      return wrap
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    for index in range(test_constants.THREAD_CONCURRENCY):
-      inner_response_future = multi_callable.future(
-          request,
-          metadata=(
-              ('test',
-               'WaitingForSomeButNotAllConcurrentFutureInvocations'),))
-      outer_response_future = pool.submit(wrap_future(inner_response_future))
-      response_futures[index] = outer_response_future
-
-    some_completed_response_futures_iterator = itertools.islice(
-        futures.as_completed(response_futures),
-        test_constants.THREAD_CONCURRENCY // 2)
-    for response_future in some_completed_response_futures_iterator:
-      self.assertEqual(expected_response, response_future.result())
-    with lock:
-      test_is_running_cell[0] = False
-
-  def testConsumingOneStreamResponseUnaryRequest(self):
-    request = b'\x57\x38'
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request,
-        metadata=(
-            ('test', 'ConsumingOneStreamResponseUnaryRequest'),))
-    next(response_iterator)
-
-  def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self):
-    request = b'\x57\x38'
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request,
-        metadata=(
-            ('test', 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),))
-    for _ in range(test_constants.STREAM_LENGTH // 2):
-      next(response_iterator)
-
-  def testConsumingSomeButNotAllStreamResponsesStreamRequest(self):
-    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request_iterator,
-        metadata=(
-            ('test', 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),))
-    for _ in range(test_constants.STREAM_LENGTH // 2):
-      next(response_iterator)
-
-  def testConsumingTooManyStreamResponsesStreamRequest(self):
-    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    response_iterator = multi_callable(
-        request_iterator,
-        metadata=(
-            ('test', 'ConsumingTooManyStreamResponsesStreamRequest'),))
-    for _ in range(test_constants.STREAM_LENGTH):
-      next(response_iterator)
-    for _ in range(test_constants.STREAM_LENGTH):
-      with self.assertRaises(StopIteration):
-        next(response_iterator)
+        self._channel = grpc.insecure_channel('localhost:%d' % port)
 
-    self.assertIsNotNone(response_iterator.initial_metadata())
-    self.assertIs(grpc.StatusCode.OK, response_iterator.code())
-    self.assertIsNotNone(response_iterator.details())
-    self.assertIsNotNone(response_iterator.trailing_metadata())
-
-  def testCancelledUnaryRequestUnaryResponse(self):
-    request = b'\x07\x17'
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    with self._control.pause():
-      response_future = multi_callable.future(
-          request,
-          metadata=(('test', 'CancelledUnaryRequestUnaryResponse'),))
-      response_future.cancel()
-
-    self.assertTrue(response_future.cancelled())
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.result()
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.exception()
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.traceback()
-    self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
-
-  def testCancelledUnaryRequestStreamResponse(self):
-    request = b'\x07\x19'
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    with self._control.pause():
-      response_iterator = multi_callable(
-          request,
-          metadata=(('test', 'CancelledUnaryRequestStreamResponse'),))
-      self._control.block_until_paused()
-      response_iterator.cancel()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      next(response_iterator)
-    self.assertIs(grpc.StatusCode.CANCELLED, exception_context.exception.code())
-    self.assertIsNotNone(response_iterator.initial_metadata())
-    self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
-    self.assertIsNotNone(response_iterator.details())
-    self.assertIsNotNone(response_iterator.trailing_metadata())
-
-  def testCancelledStreamRequestUnaryResponse(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self._control.pause():
-      response_future = multi_callable.future(
-          request_iterator,
-          metadata=(('test', 'CancelledStreamRequestUnaryResponse'),))
-      self._control.block_until_paused()
-      response_future.cancel()
-
-    self.assertTrue(response_future.cancelled())
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.result()
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.exception()
-    with self.assertRaises(grpc.FutureCancelledError):
-      response_future.traceback()
-    self.assertIsNotNone(response_future.initial_metadata())
-    self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
-    self.assertIsNotNone(response_future.details())
-    self.assertIsNotNone(response_future.trailing_metadata())
-
-  def testCancelledStreamRequestStreamResponse(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    with self._control.pause():
-      response_iterator = multi_callable(
-          request_iterator,
-          metadata=(('test', 'CancelledStreamRequestStreamResponse'),))
-      response_iterator.cancel()
-
-    with self.assertRaises(grpc.RpcError):
-      next(response_iterator)
-    self.assertIsNotNone(response_iterator.initial_metadata())
-    self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
-    self.assertIsNotNone(response_iterator.details())
-    self.assertIsNotNone(response_iterator.trailing_metadata())
-
-  def testExpiredUnaryRequestBlockingUnaryResponse(self):
-    request = b'\x07\x17'
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    with self._control.pause():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        multi_callable.with_call(
-            request, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=(('test', 'ExpiredUnaryRequestBlockingUnaryResponse'),))
-
-    self.assertIsInstance(exception_context.exception, grpc.Call)
-    self.assertIsNotNone(exception_context.exception.initial_metadata())
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIsNotNone(exception_context.exception.details())
-    self.assertIsNotNone(exception_context.exception.trailing_metadata())
-
-  def testExpiredUnaryRequestFutureUnaryResponse(self):
-    request = b'\x07\x17'
-    callback = _Callback()
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    with self._control.pause():
-      response_future = multi_callable.future(
-          request, timeout=test_constants.SHORT_TIMEOUT,
-          metadata=(('test', 'ExpiredUnaryRequestFutureUnaryResponse'),))
-      response_future.add_done_callback(callback)
-      value_passed_to_callback = callback.value()
-
-    self.assertIs(response_future, value_passed_to_callback)
-    self.assertIsNotNone(response_future.initial_metadata())
-    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
-    self.assertIsNotNone(response_future.details())
-    self.assertIsNotNone(response_future.trailing_metadata())
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIsInstance(response_future.exception(), grpc.RpcError)
-    self.assertIsNotNone(response_future.traceback())
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, response_future.exception().code())
-
-  def testExpiredUnaryRequestStreamResponse(self):
-    request = b'\x07\x19'
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    with self._control.pause():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        response_iterator = multi_callable(
-            request, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),))
-        next(response_iterator)
+    def tearDown(self):
+        self._server.stop(None)
+        self._server_pool.shutdown(wait=True)
 
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_iterator.code())
+    def testUnrecognizedMethod(self):
+        request = b'abc'
 
-  def testExpiredStreamRequestBlockingUnaryResponse(self):
-    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            self._channel.unary_unary('NoSuchMethod')(request)
 
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self._control.pause():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        multi_callable(
-            request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=(('test', 'ExpiredStreamRequestBlockingUnaryResponse'),))
-
-    self.assertIsInstance(exception_context.exception, grpc.RpcError)
-    self.assertIsInstance(exception_context.exception, grpc.Call)
-    self.assertIsNotNone(exception_context.exception.initial_metadata())
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIsNotNone(exception_context.exception.details())
-    self.assertIsNotNone(exception_context.exception.trailing_metadata())
-
-  def testExpiredStreamRequestFutureUnaryResponse(self):
-    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-    callback = _Callback()
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self._control.pause():
-      response_future = multi_callable.future(
-          request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-          metadata=(('test', 'ExpiredStreamRequestFutureUnaryResponse'),))
-      with self.assertRaises(grpc.FutureTimeoutError):
-        response_future.result(timeout=test_constants.SHORT_TIMEOUT / 2.0)
-      response_future.add_done_callback(callback)
-      value_passed_to_callback = callback.value()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIsInstance(response_future.exception(), grpc.RpcError)
-    self.assertIsNotNone(response_future.traceback())
-    self.assertIs(response_future, value_passed_to_callback)
-    self.assertIsNotNone(response_future.initial_metadata())
-    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
-    self.assertIsNotNone(response_future.details())
-    self.assertIsNotNone(response_future.trailing_metadata())
-
-  def testExpiredStreamRequestStreamResponse(self):
-    requests = tuple(b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    with self._control.pause():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        response_iterator = multi_callable(
-            request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=(('test', 'ExpiredStreamRequestStreamResponse'),))
-        next(response_iterator)
+        self.assertEqual(grpc.StatusCode.UNIMPLEMENTED,
+                         exception_context.exception.code())
+
+    def testSuccessfulUnaryRequestBlockingUnaryResponse(self):
+        request = b'\x07\x08'
+        expected_response = self._handler.handle_unary_unary(request, None)
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        response = multi_callable(
+            request,
+            metadata=(('test', 'SuccessfulUnaryRequestBlockingUnaryResponse'),))
+
+        self.assertEqual(expected_response, response)
 
-    self.assertIs(
-        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
-    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_iterator.code())
+    def testSuccessfulUnaryRequestBlockingUnaryResponseWithCall(self):
+        request = b'\x07\x08'
+        expected_response = self._handler.handle_unary_unary(request, None)
 
-  def testFailedUnaryRequestBlockingUnaryResponse(self):
-    request = b'\x37\x17'
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        response, call = multi_callable.with_call(
+            request,
+            metadata=(('test',
+                       'SuccessfulUnaryRequestBlockingUnaryResponseWithCall'),))
+
+        self.assertEqual(expected_response, response)
+        self.assertIs(grpc.StatusCode.OK, call.code())
+
+    def testSuccessfulUnaryRequestFutureUnaryResponse(self):
+        request = b'\x07\x08'
+        expected_response = self._handler.handle_unary_unary(request, None)
 
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    with self._control.fail():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        multi_callable.with_call(
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        response_future = multi_callable.future(
             request,
-            metadata=(('test', 'FailedUnaryRequestBlockingUnaryResponse'),))
-
-    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
-
-  def testFailedUnaryRequestFutureUnaryResponse(self):
-    request = b'\x37\x17'
-    callback = _Callback()
-
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    with self._control.fail():
-      response_future = multi_callable.future(
-          request,
-          metadata=(('test', 'FailedUnaryRequestFutureUnaryResponse'),))
-      response_future.add_done_callback(callback)
-      value_passed_to_callback = callback.value()
-
-    self.assertIsInstance(response_future, grpc.Future)
-    self.assertIsInstance(response_future, grpc.Call)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertIs(
-        grpc.StatusCode.UNKNOWN, exception_context.exception.code())
-    self.assertIsInstance(response_future.exception(), grpc.RpcError)
-    self.assertIsNotNone(response_future.traceback())
-    self.assertIs(grpc.StatusCode.UNKNOWN, response_future.exception().code())
-    self.assertIs(response_future, value_passed_to_callback)
-
-  def testFailedUnaryRequestStreamResponse(self):
-    request = b'\x37\x17'
-
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      with self._control.fail():
+            metadata=(('test', 'SuccessfulUnaryRequestFutureUnaryResponse'),))
+        response = response_future.result()
+
+        self.assertIsInstance(response_future, grpc.Future)
+        self.assertIsInstance(response_future, grpc.Call)
+        self.assertEqual(expected_response, response)
+        self.assertIsNone(response_future.exception())
+        self.assertIsNone(response_future.traceback())
+
+    def testSuccessfulUnaryRequestStreamResponse(self):
+        request = b'\x37\x58'
+        expected_responses = tuple(
+            self._handler.handle_unary_stream(request, None))
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
         response_iterator = multi_callable(
             request,
-            metadata=(('test', 'FailedUnaryRequestStreamResponse'),))
-        next(response_iterator)
+            metadata=(('test', 'SuccessfulUnaryRequestStreamResponse'),))
+        responses = tuple(response_iterator)
 
-    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+        self.assertSequenceEqual(expected_responses, responses)
 
-  def testFailedStreamRequestBlockingUnaryResponse(self):
-    requests = tuple(b'\x47\x58' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
+    def testSuccessfulStreamRequestBlockingUnaryResponse(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_response = self._handler.handle_stream_unary(
+            iter(requests), None)
+        request_iterator = iter(requests)
 
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self._control.fail():
-      with self.assertRaises(grpc.RpcError) as exception_context:
-        multi_callable(
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        response = multi_callable(
+            request_iterator,
+            metadata=(
+                ('test', 'SuccessfulStreamRequestBlockingUnaryResponse'),))
+
+        self.assertEqual(expected_response, response)
+
+    def testSuccessfulStreamRequestBlockingUnaryResponseWithCall(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_response = self._handler.handle_stream_unary(
+            iter(requests), None)
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        response, call = multi_callable.with_call(
+            request_iterator,
+            metadata=(
+                ('test',
+                 'SuccessfulStreamRequestBlockingUnaryResponseWithCall'),))
+
+        self.assertEqual(expected_response, response)
+        self.assertIs(grpc.StatusCode.OK, call.code())
+
+    def testSuccessfulStreamRequestFutureUnaryResponse(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_response = self._handler.handle_stream_unary(
+            iter(requests), None)
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        response_future = multi_callable.future(
             request_iterator,
-            metadata=(('test', 'FailedStreamRequestBlockingUnaryResponse'),))
-
-    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
-
-  def testFailedStreamRequestFutureUnaryResponse(self):
-    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-    callback = _Callback()
-
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    with self._control.fail():
-      response_future = multi_callable.future(
-          request_iterator,
-          metadata=(('test', 'FailedStreamRequestFutureUnaryResponse'),))
-      response_future.add_done_callback(callback)
-      value_passed_to_callback = callback.value()
-
-    with self.assertRaises(grpc.RpcError) as exception_context:
-      response_future.result()
-    self.assertIs(grpc.StatusCode.UNKNOWN, response_future.code())
-    self.assertIs(
-        grpc.StatusCode.UNKNOWN, exception_context.exception.code())
-    self.assertIsInstance(response_future.exception(), grpc.RpcError)
-    self.assertIsNotNone(response_future.traceback())
-    self.assertIs(response_future, value_passed_to_callback)
-
-  def testFailedStreamRequestStreamResponse(self):
-    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
-
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    with self._control.fail():
-      with self.assertRaises(grpc.RpcError) as exception_context:
+            metadata=(('test', 'SuccessfulStreamRequestFutureUnaryResponse'),))
+        response = response_future.result()
+
+        self.assertEqual(expected_response, response)
+        self.assertIsNone(response_future.exception())
+        self.assertIsNone(response_future.traceback())
+
+    def testSuccessfulStreamRequestStreamResponse(self):
+        requests = tuple(b'\x77\x58'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_responses = tuple(
+            self._handler.handle_stream_stream(iter(requests), None))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_stream_multi_callable(self._channel)
         response_iterator = multi_callable(
             request_iterator,
-            metadata=(('test', 'FailedStreamRequestStreamResponse'),))
-        tuple(response_iterator)
+            metadata=(('test', 'SuccessfulStreamRequestStreamResponse'),))
+        responses = tuple(response_iterator)
+
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testSequentialInvocations(self):
+        first_request = b'\x07\x08'
+        second_request = b'\x0809'
+        expected_first_response = self._handler.handle_unary_unary(
+            first_request, None)
+        expected_second_response = self._handler.handle_unary_unary(
+            second_request, None)
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        first_response = multi_callable(
+            first_request, metadata=(('test', 'SequentialInvocations'),))
+        second_response = multi_callable(
+            second_request, metadata=(('test', 'SequentialInvocations'),))
+
+        self.assertEqual(expected_first_response, first_response)
+        self.assertEqual(expected_second_response, second_response)
+
+    def testConcurrentBlockingInvocations(self):
+        pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_response = self._handler.handle_stream_unary(
+            iter(requests), None)
+        expected_responses = [expected_response
+                             ] * test_constants.THREAD_CONCURRENCY
+        response_futures = [None] * test_constants.THREAD_CONCURRENCY
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        for index in range(test_constants.THREAD_CONCURRENCY):
+            request_iterator = iter(requests)
+            response_future = pool.submit(
+                multi_callable,
+                request_iterator,
+                metadata=(('test', 'ConcurrentBlockingInvocations'),))
+            response_futures[index] = response_future
+        responses = tuple(response_future.result()
+                          for response_future in response_futures)
+
+        pool.shutdown(wait=True)
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testConcurrentFutureInvocations(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        expected_response = self._handler.handle_stream_unary(
+            iter(requests), None)
+        expected_responses = [expected_response
+                             ] * test_constants.THREAD_CONCURRENCY
+        response_futures = [None] * test_constants.THREAD_CONCURRENCY
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        for index in range(test_constants.THREAD_CONCURRENCY):
+            request_iterator = iter(requests)
+            response_future = multi_callable.future(
+                request_iterator,
+                metadata=(('test', 'ConcurrentFutureInvocations'),))
+            response_futures[index] = response_future
+        responses = tuple(response_future.result()
+                          for response_future in response_futures)
+
+        self.assertSequenceEqual(expected_responses, responses)
+
+    def testWaitingForSomeButNotAllConcurrentFutureInvocations(self):
+        pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        request = b'\x67\x68'
+        expected_response = self._handler.handle_unary_unary(request, None)
+        response_futures = [None] * test_constants.THREAD_CONCURRENCY
+        lock = threading.Lock()
+        test_is_running_cell = [True]
+
+        def wrap_future(future):
+
+            def wrap():
+                try:
+                    return future.result()
+                except grpc.RpcError:
+                    with lock:
+                        if test_is_running_cell[0]:
+                            raise
+                    return None
+
+            return wrap
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        for index in range(test_constants.THREAD_CONCURRENCY):
+            inner_response_future = multi_callable.future(
+                request,
+                metadata=(
+                    ('test',
+                     'WaitingForSomeButNotAllConcurrentFutureInvocations'),))
+            outer_response_future = pool.submit(
+                wrap_future(inner_response_future))
+            response_futures[index] = outer_response_future
+
+        some_completed_response_futures_iterator = itertools.islice(
+            futures.as_completed(response_futures),
+            test_constants.THREAD_CONCURRENCY // 2)
+        for response_future in some_completed_response_futures_iterator:
+            self.assertEqual(expected_response, response_future.result())
+        with lock:
+            test_is_running_cell[0] = False
+
+    def testConsumingOneStreamResponseUnaryRequest(self):
+        request = b'\x57\x38'
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            request,
+            metadata=(('test', 'ConsumingOneStreamResponseUnaryRequest'),))
+        next(response_iterator)
+
+    def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self):
+        request = b'\x57\x38'
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            request,
+            metadata=(
+                ('test', 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),))
+        for _ in range(test_constants.STREAM_LENGTH // 2):
+            next(response_iterator)
 
-    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
-    self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code())
+    def testConsumingSomeButNotAllStreamResponsesStreamRequest(self):
+        requests = tuple(b'\x67\x88'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
 
-  def testIgnoredUnaryRequestFutureUnaryResponse(self):
-    request = b'\x37\x17'
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            request_iterator,
+            metadata=(('test',
+                       'ConsumingSomeButNotAllStreamResponsesStreamRequest'),))
+        for _ in range(test_constants.STREAM_LENGTH // 2):
+            next(response_iterator)
 
-    multi_callable = _unary_unary_multi_callable(self._channel)
-    multi_callable.future(
-        request,
-        metadata=(('test', 'IgnoredUnaryRequestFutureUnaryResponse'),))
+    def testConsumingTooManyStreamResponsesStreamRequest(self):
+        requests = tuple(b'\x67\x88'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
 
-  def testIgnoredUnaryRequestStreamResponse(self):
-    request = b'\x37\x17'
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        response_iterator = multi_callable(
+            request_iterator,
+            metadata=(
+                ('test', 'ConsumingTooManyStreamResponsesStreamRequest'),))
+        for _ in range(test_constants.STREAM_LENGTH):
+            next(response_iterator)
+        for _ in range(test_constants.STREAM_LENGTH):
+            with self.assertRaises(StopIteration):
+                next(response_iterator)
+
+        self.assertIsNotNone(response_iterator.initial_metadata())
+        self.assertIs(grpc.StatusCode.OK, response_iterator.code())
+        self.assertIsNotNone(response_iterator.details())
+        self.assertIsNotNone(response_iterator.trailing_metadata())
+
+    def testCancelledUnaryRequestUnaryResponse(self):
+        request = b'\x07\x17'
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        with self._control.pause():
+            response_future = multi_callable.future(
+                request,
+                metadata=(('test', 'CancelledUnaryRequestUnaryResponse'),))
+            response_future.cancel()
+
+        self.assertTrue(response_future.cancelled())
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.result()
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.exception()
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.traceback()
+        self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
+
+    def testCancelledUnaryRequestStreamResponse(self):
+        request = b'\x07\x19'
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        with self._control.pause():
+            response_iterator = multi_callable(
+                request,
+                metadata=(('test', 'CancelledUnaryRequestStreamResponse'),))
+            self._control.block_until_paused()
+            response_iterator.cancel()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            next(response_iterator)
+        self.assertIs(grpc.StatusCode.CANCELLED,
+                      exception_context.exception.code())
+        self.assertIsNotNone(response_iterator.initial_metadata())
+        self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
+        self.assertIsNotNone(response_iterator.details())
+        self.assertIsNotNone(response_iterator.trailing_metadata())
+
+    def testCancelledStreamRequestUnaryResponse(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self._control.pause():
+            response_future = multi_callable.future(
+                request_iterator,
+                metadata=(('test', 'CancelledStreamRequestUnaryResponse'),))
+            self._control.block_until_paused()
+            response_future.cancel()
+
+        self.assertTrue(response_future.cancelled())
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.result()
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.exception()
+        with self.assertRaises(grpc.FutureCancelledError):
+            response_future.traceback()
+        self.assertIsNotNone(response_future.initial_metadata())
+        self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
+        self.assertIsNotNone(response_future.details())
+        self.assertIsNotNone(response_future.trailing_metadata())
+
+    def testCancelledStreamRequestStreamResponse(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        with self._control.pause():
+            response_iterator = multi_callable(
+                request_iterator,
+                metadata=(('test', 'CancelledStreamRequestStreamResponse'),))
+            response_iterator.cancel()
+
+        with self.assertRaises(grpc.RpcError):
+            next(response_iterator)
+        self.assertIsNotNone(response_iterator.initial_metadata())
+        self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
+        self.assertIsNotNone(response_iterator.details())
+        self.assertIsNotNone(response_iterator.trailing_metadata())
+
+    def testExpiredUnaryRequestBlockingUnaryResponse(self):
+        request = b'\x07\x17'
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        with self._control.pause():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                multi_callable.with_call(
+                    request,
+                    timeout=test_constants.SHORT_TIMEOUT,
+                    metadata=(
+                        ('test', 'ExpiredUnaryRequestBlockingUnaryResponse'),))
+
+        self.assertIsInstance(exception_context.exception, grpc.Call)
+        self.assertIsNotNone(exception_context.exception.initial_metadata())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIsNotNone(exception_context.exception.details())
+        self.assertIsNotNone(exception_context.exception.trailing_metadata())
+
+    def testExpiredUnaryRequestFutureUnaryResponse(self):
+        request = b'\x07\x17'
+        callback = _Callback()
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        with self._control.pause():
+            response_future = multi_callable.future(
+                request,
+                timeout=test_constants.SHORT_TIMEOUT,
+                metadata=(('test', 'ExpiredUnaryRequestFutureUnaryResponse'),))
+            response_future.add_done_callback(callback)
+            value_passed_to_callback = callback.value()
+
+        self.assertIs(response_future, value_passed_to_callback)
+        self.assertIsNotNone(response_future.initial_metadata())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+        self.assertIsNotNone(response_future.details())
+        self.assertIsNotNone(response_future.trailing_metadata())
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIsInstance(response_future.exception(), grpc.RpcError)
+        self.assertIsNotNone(response_future.traceback())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      response_future.exception().code())
+
+    def testExpiredUnaryRequestStreamResponse(self):
+        request = b'\x07\x19'
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        with self._control.pause():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                response_iterator = multi_callable(
+                    request,
+                    timeout=test_constants.SHORT_TIMEOUT,
+                    metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),))
+                next(response_iterator)
+
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      response_iterator.code())
+
+    def testExpiredStreamRequestBlockingUnaryResponse(self):
+        requests = tuple(b'\x07\x08'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self._control.pause():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                multi_callable(
+                    request_iterator,
+                    timeout=test_constants.SHORT_TIMEOUT,
+                    metadata=(
+                        ('test', 'ExpiredStreamRequestBlockingUnaryResponse'),))
+
+        self.assertIsInstance(exception_context.exception, grpc.RpcError)
+        self.assertIsInstance(exception_context.exception, grpc.Call)
+        self.assertIsNotNone(exception_context.exception.initial_metadata())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIsNotNone(exception_context.exception.details())
+        self.assertIsNotNone(exception_context.exception.trailing_metadata())
+
+    def testExpiredStreamRequestFutureUnaryResponse(self):
+        requests = tuple(b'\x07\x18'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+        callback = _Callback()
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self._control.pause():
+            response_future = multi_callable.future(
+                request_iterator,
+                timeout=test_constants.SHORT_TIMEOUT,
+                metadata=(('test', 'ExpiredStreamRequestFutureUnaryResponse'),))
+            with self.assertRaises(grpc.FutureTimeoutError):
+                response_future.result(timeout=test_constants.SHORT_TIMEOUT /
+                                       2.0)
+            response_future.add_done_callback(callback)
+            value_passed_to_callback = callback.value()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIsInstance(response_future.exception(), grpc.RpcError)
+        self.assertIsNotNone(response_future.traceback())
+        self.assertIs(response_future, value_passed_to_callback)
+        self.assertIsNotNone(response_future.initial_metadata())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+        self.assertIsNotNone(response_future.details())
+        self.assertIsNotNone(response_future.trailing_metadata())
+
+    def testExpiredStreamRequestStreamResponse(self):
+        requests = tuple(b'\x67\x18'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        with self._control.pause():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                response_iterator = multi_callable(
+                    request_iterator,
+                    timeout=test_constants.SHORT_TIMEOUT,
+                    metadata=(('test', 'ExpiredStreamRequestStreamResponse'),))
+                next(response_iterator)
+
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      exception_context.exception.code())
+        self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED,
+                      response_iterator.code())
+
+    def testFailedUnaryRequestBlockingUnaryResponse(self):
+        request = b'\x37\x17'
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        with self._control.fail():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                multi_callable.with_call(
+                    request,
+                    metadata=(
+                        ('test', 'FailedUnaryRequestBlockingUnaryResponse'),))
+
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+
+    def testFailedUnaryRequestFutureUnaryResponse(self):
+        request = b'\x37\x17'
+        callback = _Callback()
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        with self._control.fail():
+            response_future = multi_callable.future(
+                request,
+                metadata=(('test', 'FailedUnaryRequestFutureUnaryResponse'),))
+            response_future.add_done_callback(callback)
+            value_passed_to_callback = callback.value()
+
+        self.assertIsInstance(response_future, grpc.Future)
+        self.assertIsInstance(response_future, grpc.Call)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+        self.assertIsInstance(response_future.exception(), grpc.RpcError)
+        self.assertIsNotNone(response_future.traceback())
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      response_future.exception().code())
+        self.assertIs(response_future, value_passed_to_callback)
+
+    def testFailedUnaryRequestStreamResponse(self):
+        request = b'\x37\x17'
+
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            with self._control.fail():
+                response_iterator = multi_callable(
+                    request,
+                    metadata=(('test', 'FailedUnaryRequestStreamResponse'),))
+                next(response_iterator)
+
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+
+    def testFailedStreamRequestBlockingUnaryResponse(self):
+        requests = tuple(b'\x47\x58'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self._control.fail():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                multi_callable(
+                    request_iterator,
+                    metadata=(
+                        ('test', 'FailedStreamRequestBlockingUnaryResponse'),))
+
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+
+    def testFailedStreamRequestFutureUnaryResponse(self):
+        requests = tuple(b'\x07\x18'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+        callback = _Callback()
+
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        with self._control.fail():
+            response_future = multi_callable.future(
+                request_iterator,
+                metadata=(('test', 'FailedStreamRequestFutureUnaryResponse'),))
+            response_future.add_done_callback(callback)
+            value_passed_to_callback = callback.value()
+
+        with self.assertRaises(grpc.RpcError) as exception_context:
+            response_future.result()
+        self.assertIs(grpc.StatusCode.UNKNOWN, response_future.code())
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+        self.assertIsInstance(response_future.exception(), grpc.RpcError)
+        self.assertIsNotNone(response_future.traceback())
+        self.assertIs(response_future, value_passed_to_callback)
+
+    def testFailedStreamRequestStreamResponse(self):
+        requests = tuple(b'\x67\x88'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
+
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        with self._control.fail():
+            with self.assertRaises(grpc.RpcError) as exception_context:
+                response_iterator = multi_callable(
+                    request_iterator,
+                    metadata=(('test', 'FailedStreamRequestStreamResponse'),))
+                tuple(response_iterator)
+
+        self.assertIs(grpc.StatusCode.UNKNOWN,
+                      exception_context.exception.code())
+        self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code())
+
+    def testIgnoredUnaryRequestFutureUnaryResponse(self):
+        request = b'\x37\x17'
+
+        multi_callable = _unary_unary_multi_callable(self._channel)
+        multi_callable.future(
+            request,
+            metadata=(('test', 'IgnoredUnaryRequestFutureUnaryResponse'),))
 
-    multi_callable = _unary_stream_multi_callable(self._channel)
-    multi_callable(
-        request,
-        metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),))
+    def testIgnoredUnaryRequestStreamResponse(self):
+        request = b'\x37\x17'
 
-  def testIgnoredStreamRequestFutureUnaryResponse(self):
-    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
+        multi_callable = _unary_stream_multi_callable(self._channel)
+        multi_callable(
+            request, metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),))
+
+    def testIgnoredStreamRequestFutureUnaryResponse(self):
+        requests = tuple(b'\x07\x18'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
 
-    multi_callable = _stream_unary_multi_callable(self._channel)
-    multi_callable.future(
-        request_iterator,
-        metadata=(('test', 'IgnoredStreamRequestFutureUnaryResponse'),))
+        multi_callable = _stream_unary_multi_callable(self._channel)
+        multi_callable.future(
+            request_iterator,
+            metadata=(('test', 'IgnoredStreamRequestFutureUnaryResponse'),))
 
-  def testIgnoredStreamRequestStreamResponse(self):
-    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
-    request_iterator = iter(requests)
+    def testIgnoredStreamRequestStreamResponse(self):
+        requests = tuple(b'\x67\x88'
+                         for _ in range(test_constants.STREAM_LENGTH))
+        request_iterator = iter(requests)
 
-    multi_callable = _stream_stream_multi_callable(self._channel)
-    multi_callable(
-        request_iterator,
-        metadata=(('test', 'IgnoredStreamRequestStreamResponse'),))
+        multi_callable = _stream_stream_multi_callable(self._channel)
+        multi_callable(
+            request_iterator,
+            metadata=(('test', 'IgnoredStreamRequestStreamResponse'),))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_sanity/__init__.py b/src/python/grpcio_tests/tests/unit/_sanity/__init__.py
index 2f88fa0412..100a624dc9 100644
--- a/src/python/grpcio_tests/tests/unit/_sanity/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/_sanity/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/_sanity/_sanity_test.py b/src/python/grpcio_tests/tests/unit/_sanity/_sanity_test.py
index e9fdf217ae..0fbe6a2b5d 100644
--- a/src/python/grpcio_tests/tests/unit/_sanity/_sanity_test.py
+++ b/src/python/grpcio_tests/tests/unit/_sanity/_sanity_test.py
@@ -38,21 +38,23 @@ import tests
 
 class Sanity(unittest.TestCase):
 
-  def testTestsJsonUpToDate(self):
-    """Autodiscovers all test suites and checks that tests.json is up to date"""
-    loader = tests.Loader()
-    loader.loadTestsFromNames(['tests'])
-    test_suite_names = [
-        test_case_class.id().rsplit('.', 1)[0]
-        for test_case_class in tests._loader.iterate_suite_cases(loader.suite)]
-    test_suite_names = sorted(set(test_suite_names))
-
-    tests_json_string = pkg_resources.resource_string('tests', 'tests.json')
-    if six.PY3:
-      tests_json_string = tests_json_string.decode()
-    tests_json = json.loads(tests_json_string)
-    self.assertListEqual(test_suite_names, tests_json)
+    def testTestsJsonUpToDate(self):
+        """Autodiscovers all test suites and checks that tests.json is up to date"""
+        loader = tests.Loader()
+        loader.loadTestsFromNames(['tests'])
+        test_suite_names = [
+            test_case_class.id().rsplit('.', 1)[0]
+            for test_case_class in tests._loader.iterate_suite_cases(
+                loader.suite)
+        ]
+        test_suite_names = sorted(set(test_suite_names))
+
+        tests_json_string = pkg_resources.resource_string('tests', 'tests.json')
+        if six.PY3:
+            tests_json_string = tests_json_string.decode()
+        tests_json = json.loads(tests_json_string)
+        self.assertListEqual(test_suite_names, tests_json)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py
index 3e4f317edc..be3522f46f 100644
--- a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py
+++ b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py
@@ -40,78 +40,89 @@ _EPSILON = 0.1
 
 
 def cleanup(timeout):
-  if timeout is not None:
-    time.sleep(timeout)
-  else:
-    time.sleep(_LONG_TIME)
+    if timeout is not None:
+        time.sleep(timeout)
+    else:
+        time.sleep(_LONG_TIME)
 
 
 def slow_cleanup(timeout):
-  # Don't respect timeout
-  time.sleep(_LONG_TIME)
+    # Don't respect timeout
+    time.sleep(_LONG_TIME)
 
 
 class CleanupThreadTest(unittest.TestCase):
 
-  def testTargetInvocation(self):
-    event = threading.Event()
-    def target(arg1, arg2, arg3=None):
-      self.assertEqual('arg1', arg1)
-      self.assertEqual('arg2', arg2)
-      self.assertEqual('arg3', arg3)
-      event.set()
-
-    cleanup_thread = _common.CleanupThread(behavior=lambda x: None,
-                              target=target, name='test-name',
-                              args=('arg1', 'arg2'), kwargs={'arg3': 'arg3'})
-    cleanup_thread.start()
-    cleanup_thread.join()
-    self.assertEqual(cleanup_thread.name, 'test-name')
-    self.assertTrue(event.is_set())
-
-  def testJoinNoTimeout(self):
-    cleanup_thread = _common.CleanupThread(behavior=cleanup)
-    cleanup_thread.start()
-    start_time = time.time()
-    cleanup_thread.join()
-    end_time = time.time()
-    self.assertAlmostEqual(_LONG_TIME, end_time - start_time, delta=_EPSILON)
-
-  def testJoinTimeout(self):
-    cleanup_thread = _common.CleanupThread(behavior=cleanup)
-    cleanup_thread.start()
-    start_time = time.time()
-    cleanup_thread.join(_SHORT_TIME)
-    end_time = time.time()
-    self.assertAlmostEqual(_SHORT_TIME, end_time - start_time, delta=_EPSILON)
-
-  def testJoinTimeoutSlowBehavior(self):
-    cleanup_thread = _common.CleanupThread(behavior=slow_cleanup)
-    cleanup_thread.start()
-    start_time = time.time()
-    cleanup_thread.join(_SHORT_TIME)
-    end_time = time.time()
-    self.assertAlmostEqual(_LONG_TIME, end_time - start_time, delta=_EPSILON)
-
-  def testJoinTimeoutSlowTarget(self):
-    event = threading.Event()
-    def target():
-      event.wait(_LONG_TIME)
-    cleanup_thread = _common.CleanupThread(behavior=cleanup, target=target)
-    cleanup_thread.start()
-    start_time = time.time()
-    cleanup_thread.join(_SHORT_TIME)
-    end_time = time.time()
-    self.assertAlmostEqual(_SHORT_TIME, end_time - start_time, delta=_EPSILON)
-    event.set()
-
-  def testJoinZeroTimeout(self):
-    cleanup_thread = _common.CleanupThread(behavior=cleanup)
-    cleanup_thread.start()
-    start_time = time.time()
-    cleanup_thread.join(0)
-    end_time = time.time()
-    self.assertAlmostEqual(0, end_time - start_time, delta=_EPSILON)
+    def testTargetInvocation(self):
+        event = threading.Event()
+
+        def target(arg1, arg2, arg3=None):
+            self.assertEqual('arg1', arg1)
+            self.assertEqual('arg2', arg2)
+            self.assertEqual('arg3', arg3)
+            event.set()
+
+        cleanup_thread = _common.CleanupThread(
+            behavior=lambda x: None,
+            target=target,
+            name='test-name',
+            args=('arg1', 'arg2'),
+            kwargs={'arg3': 'arg3'})
+        cleanup_thread.start()
+        cleanup_thread.join()
+        self.assertEqual(cleanup_thread.name, 'test-name')
+        self.assertTrue(event.is_set())
+
+    def testJoinNoTimeout(self):
+        cleanup_thread = _common.CleanupThread(behavior=cleanup)
+        cleanup_thread.start()
+        start_time = time.time()
+        cleanup_thread.join()
+        end_time = time.time()
+        self.assertAlmostEqual(
+            _LONG_TIME, end_time - start_time, delta=_EPSILON)
+
+    def testJoinTimeout(self):
+        cleanup_thread = _common.CleanupThread(behavior=cleanup)
+        cleanup_thread.start()
+        start_time = time.time()
+        cleanup_thread.join(_SHORT_TIME)
+        end_time = time.time()
+        self.assertAlmostEqual(
+            _SHORT_TIME, end_time - start_time, delta=_EPSILON)
+
+    def testJoinTimeoutSlowBehavior(self):
+        cleanup_thread = _common.CleanupThread(behavior=slow_cleanup)
+        cleanup_thread.start()
+        start_time = time.time()
+        cleanup_thread.join(_SHORT_TIME)
+        end_time = time.time()
+        self.assertAlmostEqual(
+            _LONG_TIME, end_time - start_time, delta=_EPSILON)
+
+    def testJoinTimeoutSlowTarget(self):
+        event = threading.Event()
+
+        def target():
+            event.wait(_LONG_TIME)
+
+        cleanup_thread = _common.CleanupThread(behavior=cleanup, target=target)
+        cleanup_thread.start()
+        start_time = time.time()
+        cleanup_thread.join(_SHORT_TIME)
+        end_time = time.time()
+        self.assertAlmostEqual(
+            _SHORT_TIME, end_time - start_time, delta=_EPSILON)
+        event.set()
+
+    def testJoinZeroTimeout(self):
+        cleanup_thread = _common.CleanupThread(behavior=cleanup)
+        cleanup_thread.start()
+        start_time = time.time()
+        cleanup_thread.join(0)
+        end_time = time.time()
+        self.assertAlmostEqual(0, end_time - start_time, delta=_EPSILON)
+
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/_thread_pool.py
index f13cc2f86f..fad2e1c8f6 100644
--- a/src/python/grpcio_tests/tests/unit/_thread_pool.py
+++ b/src/python/grpcio_tests/tests/unit/_thread_pool.py
@@ -32,17 +32,18 @@ from concurrent import futures
 
 
 class RecordingThreadPool(futures.Executor):
-  """A thread pool that records if used."""
-  def __init__(self, max_workers):
-    self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers)
-    self._lock = threading.Lock()
-    self._was_used = False
+    """A thread pool that records if used."""
 
-  def submit(self, fn, *args, **kwargs):
-    with self._lock:
-      self._was_used = True
-    self._tp_executor.submit(fn, *args, **kwargs)
+    def __init__(self, max_workers):
+        self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers)
+        self._lock = threading.Lock()
+        self._was_used = False
 
-  def was_used(self):
-    with self._lock:
-      return self._was_used
+    def submit(self, fn, *args, **kwargs):
+        with self._lock:
+            self._was_used = True
+        self._tp_executor.submit(fn, *args, **kwargs)
+
+    def was_used(self):
+        with self._lock:
+            return self._was_used
diff --git a/src/python/grpcio_tests/tests/unit/beta/__init__.py b/src/python/grpcio_tests/tests/unit/beta/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/beta/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/beta/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
index 3a9701b8eb..b5fdac26c1 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_beta_features_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests Face interface compliance of the gRPC Python Beta API."""
 
 import threading
@@ -57,290 +56,303 @@ _RESPONSE = b'123'
 
 class _Servicer(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._peer = None
-    self._serviced = False
-
-  def unary_unary(self, request, context):
-    with self._condition:
-      self._request = request
-      self._peer = context.protocol_context().peer()
-      self._invocation_metadata = context.invocation_metadata()
-      context.protocol_context().disable_next_response_compression()
-      self._serviced = True
-      self._condition.notify_all()
-      return _RESPONSE
-
-  def unary_stream(self, request, context):
-    with self._condition:
-      self._request = request
-      self._peer = context.protocol_context().peer()
-      self._invocation_metadata = context.invocation_metadata()
-      context.protocol_context().disable_next_response_compression()
-      self._serviced = True
-      self._condition.notify_all()
-      return
-      yield
-
-  def stream_unary(self, request_iterator, context):
-    for request in request_iterator:
-      self._request = request
-    with self._condition:
-      self._peer = context.protocol_context().peer()
-      self._invocation_metadata = context.invocation_metadata()
-      context.protocol_context().disable_next_response_compression()
-      self._serviced = True
-      self._condition.notify_all()
-      return _RESPONSE
-
-  def stream_stream(self, request_iterator, context):
-    for request in request_iterator:
-      with self._condition:
-        self._peer = context.protocol_context().peer()
-        context.protocol_context().disable_next_response_compression()
-        yield _RESPONSE
-    with self._condition:
-      self._invocation_metadata = context.invocation_metadata()
-      self._serviced = True
-      self._condition.notify_all()
-
-  def peer(self):
-    with self._condition:
-      return self._peer
-
-  def block_until_serviced(self):
-    with self._condition:
-      while not self._serviced:
-        self._condition.wait()
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._peer = None
+        self._serviced = False
+
+    def unary_unary(self, request, context):
+        with self._condition:
+            self._request = request
+            self._peer = context.protocol_context().peer()
+            self._invocation_metadata = context.invocation_metadata()
+            context.protocol_context().disable_next_response_compression()
+            self._serviced = True
+            self._condition.notify_all()
+            return _RESPONSE
+
+    def unary_stream(self, request, context):
+        with self._condition:
+            self._request = request
+            self._peer = context.protocol_context().peer()
+            self._invocation_metadata = context.invocation_metadata()
+            context.protocol_context().disable_next_response_compression()
+            self._serviced = True
+            self._condition.notify_all()
+            return
+            yield
+
+    def stream_unary(self, request_iterator, context):
+        for request in request_iterator:
+            self._request = request
+        with self._condition:
+            self._peer = context.protocol_context().peer()
+            self._invocation_metadata = context.invocation_metadata()
+            context.protocol_context().disable_next_response_compression()
+            self._serviced = True
+            self._condition.notify_all()
+            return _RESPONSE
+
+    def stream_stream(self, request_iterator, context):
+        for request in request_iterator:
+            with self._condition:
+                self._peer = context.protocol_context().peer()
+                context.protocol_context().disable_next_response_compression()
+                yield _RESPONSE
+        with self._condition:
+            self._invocation_metadata = context.invocation_metadata()
+            self._serviced = True
+            self._condition.notify_all()
+
+    def peer(self):
+        with self._condition:
+            return self._peer
+
+    def block_until_serviced(self):
+        with self._condition:
+            while not self._serviced:
+                self._condition.wait()
 
 
 class _BlockingIterator(object):
 
-  def __init__(self, upstream):
-    self._condition = threading.Condition()
-    self._upstream = upstream
-    self._allowed = []
+    def __init__(self, upstream):
+        self._condition = threading.Condition()
+        self._upstream = upstream
+        self._allowed = []
 
-  def __iter__(self):
-    return self
+    def __iter__(self):
+        return self
 
-  def __next__(self):
-    return self.next()
+    def __next__(self):
+        return self.next()
 
-  def next(self):
-    with self._condition:
-      while True:
-        if self._allowed is None:
-          raise StopIteration()
-        elif self._allowed:
-          return self._allowed.pop(0)
-        else:
-          self._condition.wait()
+    def next(self):
+        with self._condition:
+            while True:
+                if self._allowed is None:
+                    raise StopIteration()
+                elif self._allowed:
+                    return self._allowed.pop(0)
+                else:
+                    self._condition.wait()
 
-  def allow(self):
-    with self._condition:
-      try:
-        self._allowed.append(next(self._upstream))
-      except StopIteration:
-        self._allowed = None
-      self._condition.notify_all()
+    def allow(self):
+        with self._condition:
+            try:
+                self._allowed.append(next(self._upstream))
+            except StopIteration:
+                self._allowed = None
+            self._condition.notify_all()
 
 
 def _metadata_plugin(context, callback):
-  callback([(_PER_RPC_CREDENTIALS_METADATA_KEY,
-             _PER_RPC_CREDENTIALS_METADATA_VALUE)], None)
+    callback([(_PER_RPC_CREDENTIALS_METADATA_KEY,
+               _PER_RPC_CREDENTIALS_METADATA_VALUE)], None)
 
 
 class BetaFeaturesTest(unittest.TestCase):
 
-  def setUp(self):
-    self._servicer = _Servicer()
-    method_implementations = {
-        (_GROUP, _UNARY_UNARY):
+    def setUp(self):
+        self._servicer = _Servicer()
+        method_implementations = {
+            (_GROUP, _UNARY_UNARY):
             utilities.unary_unary_inline(self._servicer.unary_unary),
-        (_GROUP, _UNARY_STREAM):
+            (_GROUP, _UNARY_STREAM):
             utilities.unary_stream_inline(self._servicer.unary_stream),
-        (_GROUP, _STREAM_UNARY):
+            (_GROUP, _STREAM_UNARY):
             utilities.stream_unary_inline(self._servicer.stream_unary),
-        (_GROUP, _STREAM_STREAM):
+            (_GROUP, _STREAM_STREAM):
             utilities.stream_stream_inline(self._servicer.stream_stream),
-    }
-
-    cardinalities = {
-        _UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
-        _UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
-        _STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
-        _STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
-    }
-
-    server_options = implementations.server_options(
-        thread_pool_size=test_constants.POOL_SIZE)
-    self._server = implementations.server(
-        method_implementations, options=server_options)
-    server_credentials = implementations.ssl_server_credentials(
-        [(resources.private_key(), resources.certificate_chain(),),])
-    port = self._server.add_secure_port('[::]:0', server_credentials)
-    self._server.start()
-    self._channel_credentials = implementations.ssl_channel_credentials(
-        resources.test_root_certificates())
-    self._call_credentials = implementations.metadata_call_credentials(
-        _metadata_plugin)
-    channel = test_utilities.not_really_secure_channel(
-        'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
-    stub_options = implementations.stub_options(
-        thread_pool_size=test_constants.POOL_SIZE)
-    self._dynamic_stub = implementations.dynamic_stub(
-        channel, _GROUP, cardinalities, options=stub_options)
-
-  def tearDown(self):
-    self._dynamic_stub = None
-    self._server.stop(test_constants.SHORT_TIMEOUT).wait()
-
-  def test_unary_unary(self):
-    call_options = interfaces.grpc_call_options(
-        disable_compression=True, credentials=self._call_credentials)
-    response = getattr(self._dynamic_stub, _UNARY_UNARY)(
-        _REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
-    self.assertEqual(_RESPONSE, response)
-    self.assertIsNotNone(self._servicer.peer())
-    invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
-                           self._servicer._invocation_metadata]
-    self.assertIn(
-        (_PER_RPC_CREDENTIALS_METADATA_KEY,
-         _PER_RPC_CREDENTIALS_METADATA_VALUE),
-        invocation_metadata)
-
-  def test_unary_stream(self):
-    call_options = interfaces.grpc_call_options(
-        disable_compression=True, credentials=self._call_credentials)
-    response_iterator = getattr(self._dynamic_stub, _UNARY_STREAM)(
-        _REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
-    self._servicer.block_until_serviced()
-    self.assertIsNotNone(self._servicer.peer())
-    invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
-                           self._servicer._invocation_metadata]
-    self.assertIn(
-        (_PER_RPC_CREDENTIALS_METADATA_KEY,
-         _PER_RPC_CREDENTIALS_METADATA_VALUE),
-        invocation_metadata)
-
-  def test_stream_unary(self):
-    call_options = interfaces.grpc_call_options(
-        credentials=self._call_credentials)
-    request_iterator = _BlockingIterator(iter((_REQUEST,)))
-    response_future = getattr(self._dynamic_stub, _STREAM_UNARY).future(
-        request_iterator, test_constants.LONG_TIMEOUT,
-        protocol_options=call_options)
-    response_future.protocol_context().disable_next_request_compression()
-    request_iterator.allow()
-    response_future.protocol_context().disable_next_request_compression()
-    request_iterator.allow()
-    self._servicer.block_until_serviced()
-    self.assertIsNotNone(self._servicer.peer())
-    self.assertEqual(_RESPONSE, response_future.result())
-    invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
-                           self._servicer._invocation_metadata]
-    self.assertIn(
-        (_PER_RPC_CREDENTIALS_METADATA_KEY,
-         _PER_RPC_CREDENTIALS_METADATA_VALUE),
-        invocation_metadata)
-
-  def test_stream_stream(self):
-    call_options = interfaces.grpc_call_options(
-        credentials=self._call_credentials)
-    request_iterator = _BlockingIterator(iter((_REQUEST,)))
-    response_iterator = getattr(self._dynamic_stub, _STREAM_STREAM)(
-        request_iterator, test_constants.SHORT_TIMEOUT,
-        protocol_options=call_options)
-    response_iterator.protocol_context().disable_next_request_compression()
-    request_iterator.allow()
-    response = next(response_iterator)
-    response_iterator.protocol_context().disable_next_request_compression()
-    request_iterator.allow()
-    self._servicer.block_until_serviced()
-    self.assertIsNotNone(self._servicer.peer())
-    self.assertEqual(_RESPONSE, response)
-    invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
-                           self._servicer._invocation_metadata]
-    self.assertIn(
-        (_PER_RPC_CREDENTIALS_METADATA_KEY,
-         _PER_RPC_CREDENTIALS_METADATA_VALUE),
-        invocation_metadata)
+        }
+
+        cardinalities = {
+            _UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
+            _UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
+            _STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
+            _STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
+        }
+
+        server_options = implementations.server_options(
+            thread_pool_size=test_constants.POOL_SIZE)
+        self._server = implementations.server(
+            method_implementations, options=server_options)
+        server_credentials = implementations.ssl_server_credentials([(
+            resources.private_key(),
+            resources.certificate_chain(),),])
+        port = self._server.add_secure_port('[::]:0', server_credentials)
+        self._server.start()
+        self._channel_credentials = implementations.ssl_channel_credentials(
+            resources.test_root_certificates())
+        self._call_credentials = implementations.metadata_call_credentials(
+            _metadata_plugin)
+        channel = test_utilities.not_really_secure_channel(
+            'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
+        stub_options = implementations.stub_options(
+            thread_pool_size=test_constants.POOL_SIZE)
+        self._dynamic_stub = implementations.dynamic_stub(
+            channel, _GROUP, cardinalities, options=stub_options)
+
+    def tearDown(self):
+        self._dynamic_stub = None
+        self._server.stop(test_constants.SHORT_TIMEOUT).wait()
+
+    def test_unary_unary(self):
+        call_options = interfaces.grpc_call_options(
+            disable_compression=True, credentials=self._call_credentials)
+        response = getattr(self._dynamic_stub, _UNARY_UNARY)(
+            _REQUEST,
+            test_constants.LONG_TIMEOUT,
+            protocol_options=call_options)
+        self.assertEqual(_RESPONSE, response)
+        self.assertIsNotNone(self._servicer.peer())
+        invocation_metadata = [
+            (metadatum.key, metadatum.value)
+            for metadatum in self._servicer._invocation_metadata
+        ]
+        self.assertIn((_PER_RPC_CREDENTIALS_METADATA_KEY,
+                       _PER_RPC_CREDENTIALS_METADATA_VALUE),
+                      invocation_metadata)
+
+    def test_unary_stream(self):
+        call_options = interfaces.grpc_call_options(
+            disable_compression=True, credentials=self._call_credentials)
+        response_iterator = getattr(self._dynamic_stub, _UNARY_STREAM)(
+            _REQUEST,
+            test_constants.LONG_TIMEOUT,
+            protocol_options=call_options)
+        self._servicer.block_until_serviced()
+        self.assertIsNotNone(self._servicer.peer())
+        invocation_metadata = [
+            (metadatum.key, metadatum.value)
+            for metadatum in self._servicer._invocation_metadata
+        ]
+        self.assertIn((_PER_RPC_CREDENTIALS_METADATA_KEY,
+                       _PER_RPC_CREDENTIALS_METADATA_VALUE),
+                      invocation_metadata)
+
+    def test_stream_unary(self):
+        call_options = interfaces.grpc_call_options(
+            credentials=self._call_credentials)
+        request_iterator = _BlockingIterator(iter((_REQUEST,)))
+        response_future = getattr(self._dynamic_stub, _STREAM_UNARY).future(
+            request_iterator,
+            test_constants.LONG_TIMEOUT,
+            protocol_options=call_options)
+        response_future.protocol_context().disable_next_request_compression()
+        request_iterator.allow()
+        response_future.protocol_context().disable_next_request_compression()
+        request_iterator.allow()
+        self._servicer.block_until_serviced()
+        self.assertIsNotNone(self._servicer.peer())
+        self.assertEqual(_RESPONSE, response_future.result())
+        invocation_metadata = [
+            (metadatum.key, metadatum.value)
+            for metadatum in self._servicer._invocation_metadata
+        ]
+        self.assertIn((_PER_RPC_CREDENTIALS_METADATA_KEY,
+                       _PER_RPC_CREDENTIALS_METADATA_VALUE),
+                      invocation_metadata)
+
+    def test_stream_stream(self):
+        call_options = interfaces.grpc_call_options(
+            credentials=self._call_credentials)
+        request_iterator = _BlockingIterator(iter((_REQUEST,)))
+        response_iterator = getattr(self._dynamic_stub, _STREAM_STREAM)(
+            request_iterator,
+            test_constants.SHORT_TIMEOUT,
+            protocol_options=call_options)
+        response_iterator.protocol_context().disable_next_request_compression()
+        request_iterator.allow()
+        response = next(response_iterator)
+        response_iterator.protocol_context().disable_next_request_compression()
+        request_iterator.allow()
+        self._servicer.block_until_serviced()
+        self.assertIsNotNone(self._servicer.peer())
+        self.assertEqual(_RESPONSE, response)
+        invocation_metadata = [
+            (metadatum.key, metadatum.value)
+            for metadatum in self._servicer._invocation_metadata
+        ]
+        self.assertIn((_PER_RPC_CREDENTIALS_METADATA_KEY,
+                       _PER_RPC_CREDENTIALS_METADATA_VALUE),
+                      invocation_metadata)
 
 
 class ContextManagementAndLifecycleTest(unittest.TestCase):
 
-  def setUp(self):
-    self._servicer = _Servicer()
-    self._method_implementations = {
-        (_GROUP, _UNARY_UNARY):
+    def setUp(self):
+        self._servicer = _Servicer()
+        self._method_implementations = {
+            (_GROUP, _UNARY_UNARY):
             utilities.unary_unary_inline(self._servicer.unary_unary),
-        (_GROUP, _UNARY_STREAM):
+            (_GROUP, _UNARY_STREAM):
             utilities.unary_stream_inline(self._servicer.unary_stream),
-        (_GROUP, _STREAM_UNARY):
+            (_GROUP, _STREAM_UNARY):
             utilities.stream_unary_inline(self._servicer.stream_unary),
-        (_GROUP, _STREAM_STREAM):
+            (_GROUP, _STREAM_STREAM):
             utilities.stream_stream_inline(self._servicer.stream_stream),
-    }
-
-    self._cardinalities = {
-        _UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
-        _UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
-        _STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
-        _STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
-    }
-
-    self._server_options = implementations.server_options(
-        thread_pool_size=test_constants.POOL_SIZE)
-    self._server_credentials = implementations.ssl_server_credentials(
-        [(resources.private_key(), resources.certificate_chain(),),])
-    self._channel_credentials = implementations.ssl_channel_credentials(
-        resources.test_root_certificates())
-    self._stub_options = implementations.stub_options(
-        thread_pool_size=test_constants.POOL_SIZE)
-
-  def test_stub_context(self):
-    server = implementations.server(
-        self._method_implementations, options=self._server_options)
-    port = server.add_secure_port('[::]:0', self._server_credentials)
-    server.start()
-
-    channel = test_utilities.not_really_secure_channel(
-        'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
-    dynamic_stub = implementations.dynamic_stub(
-        channel, _GROUP, self._cardinalities, options=self._stub_options)
-    for _ in range(100):
-      with dynamic_stub:
-        pass
-    for _ in range(10):
-      with dynamic_stub:
-        call_options = interfaces.grpc_call_options(
-            disable_compression=True)
-        response = getattr(dynamic_stub, _UNARY_UNARY)(
-            _REQUEST, test_constants.LONG_TIMEOUT,
-            protocol_options=call_options)
-        self.assertEqual(_RESPONSE, response)
-        self.assertIsNotNone(self._servicer.peer())
-
-    server.stop(test_constants.SHORT_TIMEOUT).wait()
-
-  def test_server_lifecycle(self):
-    for _ in range(100):
-      server = implementations.server(
-          self._method_implementations, options=self._server_options)
-      port = server.add_secure_port('[::]:0', self._server_credentials)
-      server.start()
-      server.stop(test_constants.SHORT_TIMEOUT).wait()
-    for _ in range(100):
-      server = implementations.server(
-          self._method_implementations, options=self._server_options)
-      server.add_secure_port('[::]:0', self._server_credentials)
-      server.add_insecure_port('[::]:0')
-      with server:
-        server.stop(test_constants.SHORT_TIMEOUT)
-      server.stop(test_constants.SHORT_TIMEOUT)
+        }
+
+        self._cardinalities = {
+            _UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
+            _UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
+            _STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
+            _STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
+        }
+
+        self._server_options = implementations.server_options(
+            thread_pool_size=test_constants.POOL_SIZE)
+        self._server_credentials = implementations.ssl_server_credentials([(
+            resources.private_key(),
+            resources.certificate_chain(),),])
+        self._channel_credentials = implementations.ssl_channel_credentials(
+            resources.test_root_certificates())
+        self._stub_options = implementations.stub_options(
+            thread_pool_size=test_constants.POOL_SIZE)
+
+    def test_stub_context(self):
+        server = implementations.server(
+            self._method_implementations, options=self._server_options)
+        port = server.add_secure_port('[::]:0', self._server_credentials)
+        server.start()
+
+        channel = test_utilities.not_really_secure_channel(
+            'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
+        dynamic_stub = implementations.dynamic_stub(
+            channel, _GROUP, self._cardinalities, options=self._stub_options)
+        for _ in range(100):
+            with dynamic_stub:
+                pass
+        for _ in range(10):
+            with dynamic_stub:
+                call_options = interfaces.grpc_call_options(
+                    disable_compression=True)
+                response = getattr(dynamic_stub, _UNARY_UNARY)(
+                    _REQUEST,
+                    test_constants.LONG_TIMEOUT,
+                    protocol_options=call_options)
+                self.assertEqual(_RESPONSE, response)
+                self.assertIsNotNone(self._servicer.peer())
+
+        server.stop(test_constants.SHORT_TIMEOUT).wait()
+
+    def test_server_lifecycle(self):
+        for _ in range(100):
+            server = implementations.server(
+                self._method_implementations, options=self._server_options)
+            port = server.add_secure_port('[::]:0', self._server_credentials)
+            server.start()
+            server.stop(test_constants.SHORT_TIMEOUT).wait()
+        for _ in range(100):
+            server = implementations.server(
+                self._method_implementations, options=self._server_options)
+            server.add_secure_port('[::]:0', self._server_credentials)
+            server.add_insecure_port('[::]:0')
+            with server:
+                server.stop(test_constants.SHORT_TIMEOUT)
+            server.stop(test_constants.SHORT_TIMEOUT)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_connectivity_channel_test.py b/src/python/grpcio_tests/tests/unit/beta/_connectivity_channel_test.py
index 5d826a269d..49d683b8a6 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_connectivity_channel_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_connectivity_channel_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc.beta._connectivity_channel."""
 
 import unittest
@@ -36,13 +35,13 @@ from grpc.beta import interfaces
 
 class ConnectivityStatesTest(unittest.TestCase):
 
-  def testBetaConnectivityStates(self):
-    self.assertIsNotNone(interfaces.ChannelConnectivity.IDLE)
-    self.assertIsNotNone(interfaces.ChannelConnectivity.CONNECTING)
-    self.assertIsNotNone(interfaces.ChannelConnectivity.READY)
-    self.assertIsNotNone(interfaces.ChannelConnectivity.TRANSIENT_FAILURE)
-    self.assertIsNotNone(interfaces.ChannelConnectivity.FATAL_FAILURE)
+    def testBetaConnectivityStates(self):
+        self.assertIsNotNone(interfaces.ChannelConnectivity.IDLE)
+        self.assertIsNotNone(interfaces.ChannelConnectivity.CONNECTING)
+        self.assertIsNotNone(interfaces.ChannelConnectivity.READY)
+        self.assertIsNotNone(interfaces.ChannelConnectivity.TRANSIENT_FAILURE)
+        self.assertIsNotNone(interfaces.ChannelConnectivity.FATAL_FAILURE)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_face_interface_test.py b/src/python/grpcio_tests/tests/unit/beta/_face_interface_test.py
index 3a67516906..f421442624 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_face_interface_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_face_interface_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests Face interface compliance of the gRPC Python Beta API."""
 
 import collections
@@ -47,94 +46,97 @@ _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
 
 class _SerializationBehaviors(
-    collections.namedtuple(
-        '_SerializationBehaviors',
-        ('request_serializers', 'request_deserializers', 'response_serializers',
-         'response_deserializers',))):
-  pass
+        collections.namedtuple('_SerializationBehaviors', (
+            'request_serializers',
+            'request_deserializers',
+            'response_serializers',
+            'response_deserializers',))):
+    pass
 
 
 def _serialization_behaviors_from_test_methods(test_methods):
-  request_serializers = {}
-  request_deserializers = {}
-  response_serializers = {}
-  response_deserializers = {}
-  for (group, method), test_method in six.iteritems(test_methods):
-    request_serializers[group, method] = test_method.serialize_request
-    request_deserializers[group, method] = test_method.deserialize_request
-    response_serializers[group, method] = test_method.serialize_response
-    response_deserializers[group, method] = test_method.deserialize_response
-  return _SerializationBehaviors(
-      request_serializers, request_deserializers, response_serializers,
-      response_deserializers)
+    request_serializers = {}
+    request_deserializers = {}
+    response_serializers = {}
+    response_deserializers = {}
+    for (group, method), test_method in six.iteritems(test_methods):
+        request_serializers[group, method] = test_method.serialize_request
+        request_deserializers[group, method] = test_method.deserialize_request
+        response_serializers[group, method] = test_method.serialize_response
+        response_deserializers[group, method] = test_method.deserialize_response
+    return _SerializationBehaviors(request_serializers, request_deserializers,
+                                   response_serializers, response_deserializers)
 
 
 class _Implementation(test_interfaces.Implementation):
 
-  def instantiate(
-      self, methods, method_implementations, multi_method_implementation):
-    serialization_behaviors = _serialization_behaviors_from_test_methods(
-        methods)
-    # TODO(nathaniel): Add a "groups" attribute to _digest.TestServiceDigest.
-    service = next(iter(methods))[0]
-    # TODO(nathaniel): Add a "cardinalities_by_group" attribute to
-    # _digest.TestServiceDigest.
-    cardinalities = {
-        method: method_object.cardinality()
-        for (group, method), method_object in six.iteritems(methods)}
-
-    server_options = implementations.server_options(
-        request_deserializers=serialization_behaviors.request_deserializers,
-        response_serializers=serialization_behaviors.response_serializers,
-        thread_pool_size=test_constants.POOL_SIZE)
-    server = implementations.server(
-        method_implementations, options=server_options)
-    server_credentials = implementations.ssl_server_credentials(
-        [(resources.private_key(), resources.certificate_chain(),),])
-    port = server.add_secure_port('[::]:0', server_credentials)
-    server.start()
-    channel_credentials = implementations.ssl_channel_credentials(
-        resources.test_root_certificates())
-    channel = test_utilities.not_really_secure_channel(
-        'localhost', port, channel_credentials, _SERVER_HOST_OVERRIDE)
-    stub_options = implementations.stub_options(
-        request_serializers=serialization_behaviors.request_serializers,
-        response_deserializers=serialization_behaviors.response_deserializers,
-        thread_pool_size=test_constants.POOL_SIZE)
-    generic_stub = implementations.generic_stub(channel, options=stub_options)
-    dynamic_stub = implementations.dynamic_stub(
-        channel, service, cardinalities, options=stub_options)
-    return generic_stub, {service: dynamic_stub}, server
-
-  def destantiate(self, memo):
-    memo.stop(test_constants.SHORT_TIMEOUT).wait()
-
-  def invocation_metadata(self):
-    return grpc_test_common.INVOCATION_INITIAL_METADATA
-
-  def initial_metadata(self):
-    return grpc_test_common.SERVICE_INITIAL_METADATA
-
-  def terminal_metadata(self):
-    return grpc_test_common.SERVICE_TERMINAL_METADATA
-
-  def code(self):
-    return interfaces.StatusCode.OK
-
-  def details(self):
-    return grpc_test_common.DETAILS
-
-  def metadata_transmitted(self, original_metadata, transmitted_metadata):
-    return original_metadata is None or grpc_test_common.metadata_transmitted(
-        original_metadata, transmitted_metadata)
+    def instantiate(self, methods, method_implementations,
+                    multi_method_implementation):
+        serialization_behaviors = _serialization_behaviors_from_test_methods(
+            methods)
+        # TODO(nathaniel): Add a "groups" attribute to _digest.TestServiceDigest.
+        service = next(iter(methods))[0]
+        # TODO(nathaniel): Add a "cardinalities_by_group" attribute to
+        # _digest.TestServiceDigest.
+        cardinalities = {
+            method: method_object.cardinality()
+            for (group, method), method_object in six.iteritems(methods)
+        }
+
+        server_options = implementations.server_options(
+            request_deserializers=serialization_behaviors.request_deserializers,
+            response_serializers=serialization_behaviors.response_serializers,
+            thread_pool_size=test_constants.POOL_SIZE)
+        server = implementations.server(
+            method_implementations, options=server_options)
+        server_credentials = implementations.ssl_server_credentials([(
+            resources.private_key(),
+            resources.certificate_chain(),),])
+        port = server.add_secure_port('[::]:0', server_credentials)
+        server.start()
+        channel_credentials = implementations.ssl_channel_credentials(
+            resources.test_root_certificates())
+        channel = test_utilities.not_really_secure_channel(
+            'localhost', port, channel_credentials, _SERVER_HOST_OVERRIDE)
+        stub_options = implementations.stub_options(
+            request_serializers=serialization_behaviors.request_serializers,
+            response_deserializers=serialization_behaviors.
+            response_deserializers,
+            thread_pool_size=test_constants.POOL_SIZE)
+        generic_stub = implementations.generic_stub(
+            channel, options=stub_options)
+        dynamic_stub = implementations.dynamic_stub(
+            channel, service, cardinalities, options=stub_options)
+        return generic_stub, {service: dynamic_stub}, server
+
+    def destantiate(self, memo):
+        memo.stop(test_constants.SHORT_TIMEOUT).wait()
+
+    def invocation_metadata(self):
+        return grpc_test_common.INVOCATION_INITIAL_METADATA
+
+    def initial_metadata(self):
+        return grpc_test_common.SERVICE_INITIAL_METADATA
+
+    def terminal_metadata(self):
+        return grpc_test_common.SERVICE_TERMINAL_METADATA
+
+    def code(self):
+        return interfaces.StatusCode.OK
+
+    def details(self):
+        return grpc_test_common.DETAILS
+
+    def metadata_transmitted(self, original_metadata, transmitted_metadata):
+        return original_metadata is None or grpc_test_common.metadata_transmitted(
+            original_metadata, transmitted_metadata)
 
 
 def load_tests(loader, tests, pattern):
-  return unittest.TestSuite(
-      tests=tuple(
-          loader.loadTestsFromTestCase(test_case_class)
-          for test_case_class in test_cases.test_cases(_Implementation())))
+    return unittest.TestSuite(tests=tuple(
+        loader.loadTestsFromTestCase(test_case_class)
+        for test_case_class in test_cases.test_cases(_Implementation())))
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_implementations_test.py b/src/python/grpcio_tests/tests/unit/beta/_implementations_test.py
index 127f93e9bb..69bb5cc2a5 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_implementations_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_implementations_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests the implementations module of the gRPC Python Beta API."""
 
 import datetime
@@ -40,31 +39,32 @@ from tests.unit import resources
 
 class ChannelCredentialsTest(unittest.TestCase):
 
-  def test_runtime_provided_root_certificates(self):
-    channel_credentials = implementations.ssl_channel_credentials()
-    self.assertIsInstance(
-        channel_credentials, implementations.ChannelCredentials)
-  
-  def test_application_provided_root_certificates(self):
-    channel_credentials = implementations.ssl_channel_credentials(
-        resources.test_root_certificates())
-    self.assertIsInstance(
-        channel_credentials, implementations.ChannelCredentials)
+    def test_runtime_provided_root_certificates(self):
+        channel_credentials = implementations.ssl_channel_credentials()
+        self.assertIsInstance(channel_credentials,
+                              implementations.ChannelCredentials)
+
+    def test_application_provided_root_certificates(self):
+        channel_credentials = implementations.ssl_channel_credentials(
+            resources.test_root_certificates())
+        self.assertIsInstance(channel_credentials,
+                              implementations.ChannelCredentials)
 
 
 class CallCredentialsTest(unittest.TestCase):
 
-  def test_google_call_credentials(self):
-    creds = oauth2client_client.GoogleCredentials(
-        'token', 'client_id', 'secret', 'refresh_token',
-        datetime.datetime(2008, 6, 24), 'https://refresh.uri.com/',
-        'user_agent')
-    call_creds = implementations.google_call_credentials(creds)
-    self.assertIsInstance(call_creds, implementations.CallCredentials)
+    def test_google_call_credentials(self):
+        creds = oauth2client_client.GoogleCredentials(
+            'token', 'client_id', 'secret', 'refresh_token',
+            datetime.datetime(2008, 6, 24), 'https://refresh.uri.com/',
+            'user_agent')
+        call_creds = implementations.google_call_credentials(creds)
+        self.assertIsInstance(call_creds, implementations.CallCredentials)
+
+    def test_access_token_call_credentials(self):
+        call_creds = implementations.access_token_call_credentials('token')
+        self.assertIsInstance(call_creds, implementations.CallCredentials)
 
-  def test_access_token_call_credentials(self):
-    call_creds = implementations.access_token_call_credentials('token')
-    self.assertIsInstance(call_creds, implementations.CallCredentials)
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py b/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
index 37b8c49120..664e47c769 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of RPC-method-not-found behavior."""
 
 import unittest
@@ -39,37 +38,38 @@ from tests.unit.framework.common import test_constants
 
 class NotFoundTest(unittest.TestCase):
 
-  def setUp(self):
-    self._server = implementations.server({})
-    port = self._server.add_insecure_port('[::]:0')
-    channel = implementations.insecure_channel('localhost', port)
-    self._generic_stub = implementations.generic_stub(channel)
-    self._server.start()
+    def setUp(self):
+        self._server = implementations.server({})
+        port = self._server.add_insecure_port('[::]:0')
+        channel = implementations.insecure_channel('localhost', port)
+        self._generic_stub = implementations.generic_stub(channel)
+        self._server.start()
 
-  def tearDown(self):
-    self._server.stop(0).wait()
-    self._generic_stub = None
+    def tearDown(self):
+        self._server.stop(0).wait()
+        self._generic_stub = None
 
-  def test_blocking_unary_unary_not_found(self):
-    with self.assertRaises(face.LocalError) as exception_assertion_context:
-      self._generic_stub.blocking_unary_unary(
-          'groop', 'meffod', b'abc', test_constants.LONG_TIMEOUT,
-          with_call=True)
-    self.assertIs(
-        exception_assertion_context.exception.code,
-        interfaces.StatusCode.UNIMPLEMENTED)
+    def test_blocking_unary_unary_not_found(self):
+        with self.assertRaises(face.LocalError) as exception_assertion_context:
+            self._generic_stub.blocking_unary_unary(
+                'groop',
+                'meffod',
+                b'abc',
+                test_constants.LONG_TIMEOUT,
+                with_call=True)
+        self.assertIs(exception_assertion_context.exception.code,
+                      interfaces.StatusCode.UNIMPLEMENTED)
 
-  def test_future_stream_unary_not_found(self):
-    rpc_future = self._generic_stub.future_stream_unary(
-        'grupe', 'mevvod', [b'def'], test_constants.LONG_TIMEOUT)
-    with self.assertRaises(face.LocalError) as exception_assertion_context:
-      rpc_future.result()
-    self.assertIs(
-        exception_assertion_context.exception.code,
-        interfaces.StatusCode.UNIMPLEMENTED)
-    self.assertIs(
-        rpc_future.exception().code, interfaces.StatusCode.UNIMPLEMENTED)
+    def test_future_stream_unary_not_found(self):
+        rpc_future = self._generic_stub.future_stream_unary(
+            'grupe', 'mevvod', [b'def'], test_constants.LONG_TIMEOUT)
+        with self.assertRaises(face.LocalError) as exception_assertion_context:
+            rpc_future.result()
+        self.assertIs(exception_assertion_context.exception.code,
+                      interfaces.StatusCode.UNIMPLEMENTED)
+        self.assertIs(rpc_future.exception().code,
+                      interfaces.StatusCode.UNIMPLEMENTED)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
index 9cce96cc85..e8e62c322a 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests of grpc.beta.utilities."""
 
 import threading
@@ -41,68 +40,68 @@ from tests.unit.framework.common import test_constants
 
 class _Callback(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._value = None
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._value = None
 
-  def accept_value(self, value):
-    with self._condition:
-      self._value = value
-      self._condition.notify_all()
+    def accept_value(self, value):
+        with self._condition:
+            self._value = value
+            self._condition.notify_all()
 
-  def block_until_called(self):
-    with self._condition:
-      while self._value is None:
-        self._condition.wait()
-      return self._value
+    def block_until_called(self):
+        with self._condition:
+            while self._value is None:
+                self._condition.wait()
+            return self._value
 
 
 class ChannelConnectivityTest(unittest.TestCase):
 
-  def test_lonely_channel_connectivity(self):
-    channel = implementations.insecure_channel('localhost', 12345)
-    callback = _Callback()
-
-    ready_future = utilities.channel_ready_future(channel)
-    ready_future.add_done_callback(callback.accept_value)
-    with self.assertRaises(future.TimeoutError):
-      ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
-    self.assertFalse(ready_future.cancelled())
-    self.assertFalse(ready_future.done())
-    self.assertTrue(ready_future.running())
-    ready_future.cancel()
-    value_passed_to_callback = callback.block_until_called()
-    self.assertIs(ready_future, value_passed_to_callback)
-    self.assertTrue(ready_future.cancelled())
-    self.assertTrue(ready_future.done())
-    self.assertFalse(ready_future.running())
-
-  def test_immediately_connectable_channel_connectivity(self):
-    server = implementations.server({})
-    port = server.add_insecure_port('[::]:0')
-    server.start()
-    channel = implementations.insecure_channel('localhost', port)
-    callback = _Callback()
-
-    try:
-      ready_future = utilities.channel_ready_future(channel)
-      ready_future.add_done_callback(callback.accept_value)
-      self.assertIsNone(
-          ready_future.result(timeout=test_constants.LONG_TIMEOUT))
-      value_passed_to_callback = callback.block_until_called()
-      self.assertIs(ready_future, value_passed_to_callback)
-      self.assertFalse(ready_future.cancelled())
-      self.assertTrue(ready_future.done())
-      self.assertFalse(ready_future.running())
-      # Cancellation after maturity has no effect.
-      ready_future.cancel()
-      self.assertFalse(ready_future.cancelled())
-      self.assertTrue(ready_future.done())
-      self.assertFalse(ready_future.running())
-    finally:
-      ready_future.cancel()
-      server.stop(0)
+    def test_lonely_channel_connectivity(self):
+        channel = implementations.insecure_channel('localhost', 12345)
+        callback = _Callback()
+
+        ready_future = utilities.channel_ready_future(channel)
+        ready_future.add_done_callback(callback.accept_value)
+        with self.assertRaises(future.TimeoutError):
+            ready_future.result(timeout=test_constants.SHORT_TIMEOUT)
+        self.assertFalse(ready_future.cancelled())
+        self.assertFalse(ready_future.done())
+        self.assertTrue(ready_future.running())
+        ready_future.cancel()
+        value_passed_to_callback = callback.block_until_called()
+        self.assertIs(ready_future, value_passed_to_callback)
+        self.assertTrue(ready_future.cancelled())
+        self.assertTrue(ready_future.done())
+        self.assertFalse(ready_future.running())
+
+    def test_immediately_connectable_channel_connectivity(self):
+        server = implementations.server({})
+        port = server.add_insecure_port('[::]:0')
+        server.start()
+        channel = implementations.insecure_channel('localhost', port)
+        callback = _Callback()
+
+        try:
+            ready_future = utilities.channel_ready_future(channel)
+            ready_future.add_done_callback(callback.accept_value)
+            self.assertIsNone(
+                ready_future.result(timeout=test_constants.LONG_TIMEOUT))
+            value_passed_to_callback = callback.block_until_called()
+            self.assertIs(ready_future, value_passed_to_callback)
+            self.assertFalse(ready_future.cancelled())
+            self.assertTrue(ready_future.done())
+            self.assertFalse(ready_future.running())
+            # Cancellation after maturity has no effect.
+            ready_future.cancel()
+            self.assertFalse(ready_future.cancelled())
+            self.assertTrue(ready_future.done())
+            self.assertFalse(ready_future.running())
+        finally:
+            ready_future.cancel()
+            server.stop(0)
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/beta/test_utilities.py b/src/python/grpcio_tests/tests/unit/beta/test_utilities.py
index 692da9c97d..f542420683 100644
--- a/src/python/grpcio_tests/tests/unit/beta/test_utilities.py
+++ b/src/python/grpcio_tests/tests/unit/beta/test_utilities.py
@@ -26,16 +26,15 @@
 # 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-appropriate entry points into the gRPC Python Beta API."""
 
 import grpc
 from grpc.beta import implementations
 
 
-def not_really_secure_channel(
-    host, port, channel_credentials, server_host_override):
-  """Creates an insecure Channel to a remote host.
+def not_really_secure_channel(host, port, channel_credentials,
+                              server_host_override):
+    """Creates an insecure Channel to a remote host.
 
   Args:
     host: The name of the remote host to which to connect.
@@ -48,8 +47,8 @@ def not_really_secure_channel(
     An implementations.Channel to the remote host through which RPCs may be
       conducted.
   """
-  target = '%s:%d' % (host, port)
-  channel = grpc.secure_channel(
-      target, channel_credentials,
-      (('grpc.ssl_target_name_override', server_host_override,),))
-  return implementations.Channel(channel)
+    target = '%s:%d' % (host, port)
+    channel = grpc.secure_channel(target, channel_credentials, ((
+        'grpc.ssl_target_name_override',
+        server_host_override,),))
+    return implementations.Channel(channel)
diff --git a/src/python/grpcio_tests/tests/unit/framework/__init__.py b/src/python/grpcio_tests/tests/unit/framework/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/framework/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/common/__init__.py b/src/python/grpcio_tests/tests/unit/framework/common/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/common/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/framework/common/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/common/test_constants.py b/src/python/grpcio_tests/tests/unit/framework/common/test_constants.py
index b6682d396c..905483c08d 100644
--- a/src/python/grpcio_tests/tests/unit/framework/common/test_constants.py
+++ b/src/python/grpcio_tests/tests/unit/framework/common/test_constants.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Constants shared among tests throughout RPC Framework."""
 
 # Value for maximum duration in seconds that a test is allowed for its actual
diff --git a/src/python/grpcio_tests/tests/unit/framework/common/test_control.py b/src/python/grpcio_tests/tests/unit/framework/common/test_control.py
index 088e2f8b88..af08731b1e 100644
--- a/src/python/grpcio_tests/tests/unit/framework/common/test_control.py
+++ b/src/python/grpcio_tests/tests/unit/framework/common/test_control.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Code for instructing systems under test to block or fail."""
 
 import abc
@@ -37,7 +36,7 @@ import six
 
 
 class Defect(Exception):
-  """Simulates a programming defect raised into in a system under test.
+    """Simulates a programming defect raised into in a system under test.
 
   Use of a standard exception type is too easily misconstrued as an actual
   defect in either the test infrastructure or the system under test.
@@ -45,7 +44,7 @@ class Defect(Exception):
 
 
 class Control(six.with_metaclass(abc.ABCMeta)):
-  """An object that accepts program control from a system under test.
+    """An object that accepts program control from a system under test.
 
   Systems under test passed a Control should call its control() method
   frequently during execution. The control() method may block, raise an
@@ -53,61 +52,61 @@ class Control(six.with_metaclass(abc.ABCMeta)):
   the system under test to simulate hanging, failing, or functioning.
   """
 
-  @abc.abstractmethod
-  def control(self):
-    """Potentially does anything."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def control(self):
+        """Potentially does anything."""
+        raise NotImplementedError()
 
 
 class PauseFailControl(Control):
-  """A Control that can be used to pause or fail code under control.
+    """A Control that can be used to pause or fail code under control.
 
   This object is only safe for use from two threads: one of the system under
   test calling control and the other from the test system calling pause,
   block_until_paused, and fail.
   """
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._pause = False
-    self._paused = False
-    self._fail = False
-
-  def control(self):
-    with self._condition:
-      if self._fail:
-        raise Defect()
-
-      while self._pause:
-        self._paused = True
-        self._condition.notify_all()
-        self._condition.wait()
-      self._paused = False
-
-  @contextlib.contextmanager
-  def pause(self):
-    """Pauses code under control while controlling code is in context."""
-    with self._condition:
-      self._pause = True
-    yield
-    with self._condition:
-      self._pause = False
-      self._condition.notify_all()
-
-  def block_until_paused(self):
-    """Blocks controlling code until code under control is paused.
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._pause = False
+        self._paused = False
+        self._fail = False
+
+    def control(self):
+        with self._condition:
+            if self._fail:
+                raise Defect()
+
+            while self._pause:
+                self._paused = True
+                self._condition.notify_all()
+                self._condition.wait()
+            self._paused = False
+
+    @contextlib.contextmanager
+    def pause(self):
+        """Pauses code under control while controlling code is in context."""
+        with self._condition:
+            self._pause = True
+        yield
+        with self._condition:
+            self._pause = False
+            self._condition.notify_all()
+
+    def block_until_paused(self):
+        """Blocks controlling code until code under control is paused.
 
     May only be called within the context of a pause call.
     """
-    with self._condition:
-      while not self._paused:
-        self._condition.wait()
-
-  @contextlib.contextmanager
-  def fail(self):
-    """Fails code under control while controlling code is in context."""
-    with self._condition:
-      self._fail = True
-    yield
-    with self._condition:
-      self._fail = False
+        with self._condition:
+            while not self._paused:
+                self._condition.wait()
+
+    @contextlib.contextmanager
+    def fail(self):
+        """Fails code under control while controlling code is in context."""
+        with self._condition:
+            self._fail = True
+        yield
+        with self._condition:
+            self._fail = False
diff --git a/src/python/grpcio_tests/tests/unit/framework/common/test_coverage.py b/src/python/grpcio_tests/tests/unit/framework/common/test_coverage.py
index ea2d2812ce..13ceec31a0 100644
--- a/src/python/grpcio_tests/tests/unit/framework/common/test_coverage.py
+++ b/src/python/grpcio_tests/tests/unit/framework/common/test_coverage.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Governs coverage for tests of RPCs throughout RPC Framework."""
 
 import abc
@@ -38,80 +37,80 @@ import six
 
 
 class Coverage(six.with_metaclass(abc.ABCMeta)):
-  """Specification of test coverage."""
+    """Specification of test coverage."""
 
-  @abc.abstractmethod
-  def testSuccessfulUnaryRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testSuccessfulUnaryRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testSuccessfulUnaryRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testSuccessfulUnaryRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testSuccessfulStreamRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testSuccessfulStreamRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testSuccessfulStreamRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testSuccessfulStreamRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testSequentialInvocations(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testSequentialInvocations(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testParallelInvocations(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testParallelInvocations(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testWaitingForSomeButNotAllParallelInvocations(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testWaitingForSomeButNotAllParallelInvocations(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testCancelledUnaryRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testCancelledUnaryRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testCancelledUnaryRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testCancelledUnaryRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testCancelledStreamRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testCancelledStreamRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testCancelledStreamRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testCancelledStreamRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testExpiredUnaryRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testExpiredUnaryRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testExpiredUnaryRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testExpiredUnaryRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testExpiredStreamRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testExpiredStreamRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testExpiredStreamRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testExpiredStreamRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testFailedUnaryRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testFailedUnaryRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testFailedUnaryRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testFailedUnaryRequestStreamResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testFailedStreamRequestUnaryResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testFailedStreamRequestUnaryResponse(self):
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def testFailedStreamRequestStreamResponse(self):
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def testFailedStreamRequestStreamResponse(self):
+        raise NotImplementedError()
diff --git a/src/python/grpcio_tests/tests/unit/framework/foundation/__init__.py b/src/python/grpcio_tests/tests/unit/framework/foundation/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/foundation/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/framework/foundation/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py b/src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py
index 330e445d43..19e8cbdd8e 100644
--- a/src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py
+++ b/src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tests for grpc.framework.foundation.logging_pool."""
 
 import threading
@@ -39,50 +38,51 @@ _POOL_SIZE = 16
 
 class _CallableObject(object):
 
-  def __init__(self):
-    self._lock = threading.Lock()
-    self._passed_values = []
+    def __init__(self):
+        self._lock = threading.Lock()
+        self._passed_values = []
 
-  def __call__(self, value):
-    with self._lock:
-      self._passed_values.append(value)
+    def __call__(self, value):
+        with self._lock:
+            self._passed_values.append(value)
 
-  def passed_values(self):
-    with self._lock:
-      return tuple(self._passed_values)
+    def passed_values(self):
+        with self._lock:
+            return tuple(self._passed_values)
 
 
 class LoggingPoolTest(unittest.TestCase):
 
-  def testUpAndDown(self):
-    pool = logging_pool.pool(_POOL_SIZE)
-    pool.shutdown(wait=True)
+    def testUpAndDown(self):
+        pool = logging_pool.pool(_POOL_SIZE)
+        pool.shutdown(wait=True)
 
-    with logging_pool.pool(_POOL_SIZE) as pool:
-      self.assertIsNotNone(pool)
+        with logging_pool.pool(_POOL_SIZE) as pool:
+            self.assertIsNotNone(pool)
 
-  def testTaskExecuted(self):
-    test_list = []
+    def testTaskExecuted(self):
+        test_list = []
 
-    with logging_pool.pool(_POOL_SIZE) as pool:
-      pool.submit(lambda: test_list.append(object())).result()
+        with logging_pool.pool(_POOL_SIZE) as pool:
+            pool.submit(lambda: test_list.append(object())).result()
 
-    self.assertTrue(test_list)
+        self.assertTrue(test_list)
 
-  def testException(self):
-    with logging_pool.pool(_POOL_SIZE) as pool:
-      raised_exception = pool.submit(lambda: 1/0).exception()
+    def testException(self):
+        with logging_pool.pool(_POOL_SIZE) as pool:
+            raised_exception = pool.submit(lambda: 1 / 0).exception()
 
-    self.assertIsNotNone(raised_exception)
+        self.assertIsNotNone(raised_exception)
 
-  def testCallableObjectExecuted(self):
-    callable_object = _CallableObject()
-    passed_object = object()
-    with logging_pool.pool(_POOL_SIZE) as pool:
-      future = pool.submit(callable_object, passed_object)
-    self.assertIsNone(future.result())
-    self.assertSequenceEqual((passed_object,), callable_object.passed_values())
+    def testCallableObjectExecuted(self):
+        callable_object = _CallableObject()
+        passed_object = object()
+        with logging_pool.pool(_POOL_SIZE) as pool:
+            future = pool.submit(callable_object, passed_object)
+        self.assertIsNone(future.result())
+        self.assertSequenceEqual((passed_object,),
+                                 callable_object.passed_values())
 
 
 if __name__ == '__main__':
-  unittest.main(verbosity=2)
+    unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/framework/foundation/stream_testing.py b/src/python/grpcio_tests/tests/unit/framework/foundation/stream_testing.py
index 098a53d5e7..2929e4dd78 100644
--- a/src/python/grpcio_tests/tests/unit/framework/foundation/stream_testing.py
+++ b/src/python/grpcio_tests/tests/unit/framework/foundation/stream_testing.py
@@ -26,48 +26,47 @@
 # 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.
-
 """Utilities for testing stream-related code."""
 
 from grpc.framework.foundation import stream
 
 
 class TestConsumer(stream.Consumer):
-  """A stream.Consumer instrumented for testing.
+    """A stream.Consumer instrumented for testing.
 
   Attributes:
     calls: A sequence of value-termination pairs describing the history of calls
       made on this object.
   """
 
-  def __init__(self):
-    self.calls = []
+    def __init__(self):
+        self.calls = []
 
-  def consume(self, value):
-    """See stream.Consumer.consume for specification."""
-    self.calls.append((value, False))
+    def consume(self, value):
+        """See stream.Consumer.consume for specification."""
+        self.calls.append((value, False))
 
-  def terminate(self):
-    """See stream.Consumer.terminate for specification."""
-    self.calls.append((None, True))
+    def terminate(self):
+        """See stream.Consumer.terminate for specification."""
+        self.calls.append((None, True))
 
-  def consume_and_terminate(self, value):
-    """See stream.Consumer.consume_and_terminate for specification."""
-    self.calls.append((value, True))
+    def consume_and_terminate(self, value):
+        """See stream.Consumer.consume_and_terminate for specification."""
+        self.calls.append((value, True))
 
-  def is_legal(self):
-    """Reports whether or not a legal sequence of calls has been made."""
-    terminated = False
-    for value, terminal in self.calls:
-      if terminated:
-        return False
-      elif terminal:
-        terminated = True
-      elif value is None:
-        return False
-    else:  # pylint: disable=useless-else-on-loop
-      return True
+    def is_legal(self):
+        """Reports whether or not a legal sequence of calls has been made."""
+        terminated = False
+        for value, terminal in self.calls:
+            if terminated:
+                return False
+            elif terminal:
+                terminated = True
+            elif value is None:
+                return False
+        else:  # pylint: disable=useless-else-on-loop
+            return True
 
-  def values(self):
-    """Returns the sequence of values that have been passed to this Consumer."""
-    return [value for value, _ in self.calls if value]
+    def values(self):
+        """Returns the sequence of values that have been passed to this Consumer."""
+        return [value for value, _ in self.calls if value]
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/__init__.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_3069_test_constant.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_3069_test_constant.py
index 1ea356c0bf..2aec25c9ef 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_3069_test_constant.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_3069_test_constant.py
@@ -26,7 +26,6 @@
 # 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.
-
 """A test constant working around issue 3069."""
 
 # test_constants is referenced from specification in this module.
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/__init__.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/__init__.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/__init__.py
@@ -26,5 +26,3 @@
 # 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.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
index e338aaa396..a79834f96f 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
@@ -26,7 +26,6 @@
 # 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 code for the Face layer of RPC Framework."""
 
 from __future__ import division
@@ -50,246 +49,254 @@ from tests.unit.framework.interfaces.face import _stock_service
 from tests.unit.framework.interfaces.face import test_interfaces  # pylint: disable=unused-import
 
 
-class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.TestCase)):
-  """A test of the Face layer of RPC Framework.
+class TestCase(
+        six.with_metaclass(abc.ABCMeta, test_coverage.Coverage,
+                           unittest.TestCase)):
+    """A test of the Face layer of RPC Framework.
 
   Concrete subclasses must have an "implementation" attribute of type
   test_interfaces.Implementation and an "invoker_constructor" attribute of type
   _invocation.InvokerConstructor.
   """
 
-  NAME = 'BlockingInvocationInlineServiceTest'
+    NAME = 'BlockingInvocationInlineServiceTest'
 
-  def setUp(self):
-    """See unittest.TestCase.setUp for full specification.
+    def setUp(self):
+        """See unittest.TestCase.setUp for full specification.
 
     Overriding implementations must call this implementation.
     """
-    self._control = test_control.PauseFailControl()
-    self._digest = _digest.digest(
-        _stock_service.STOCK_TEST_SERVICE, self._control, None)
+        self._control = test_control.PauseFailControl()
+        self._digest = _digest.digest(_stock_service.STOCK_TEST_SERVICE,
+                                      self._control, None)
 
-    generic_stub, dynamic_stubs, self._memo = self.implementation.instantiate(
-        self._digest.methods, self._digest.inline_method_implementations, None)
-    self._invoker = self.invoker_constructor.construct_invoker(
-        generic_stub, dynamic_stubs, self._digest.methods)
+        generic_stub, dynamic_stubs, self._memo = self.implementation.instantiate(
+            self._digest.methods, self._digest.inline_method_implementations,
+            None)
+        self._invoker = self.invoker_constructor.construct_invoker(
+            generic_stub, dynamic_stubs, self._digest.methods)
 
-  def tearDown(self):
-    """See unittest.TestCase.tearDown for full specification.
+    def tearDown(self):
+        """See unittest.TestCase.tearDown for full specification.
 
     Overriding implementations must call this implementation.
     """
-    self._invoker = None
-    self.implementation.destantiate(self._memo)
-
-  def testSuccessfulUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        response, call = self._invoker.blocking(group, method)(
-            request, test_constants.LONG_TIMEOUT, with_call=True)
-
-        test_messages.verify(request, response, self)
-
-  def testSuccessfulUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        response_iterator = self._invoker.blocking(group, method)(
-            request, test_constants.LONG_TIMEOUT)
-        responses = list(response_iterator)
-
-        test_messages.verify(request, responses, self)
-
-  def testSuccessfulStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        response, call = self._invoker.blocking(group, method)(
-            iter(requests), test_constants.LONG_TIMEOUT, with_call=True)
-
-        test_messages.verify(requests, response, self)
-
-  def testSuccessfulStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        response_iterator = self._invoker.blocking(group, method)(
-            iter(requests), test_constants.LONG_TIMEOUT)
-        responses = list(response_iterator)
-
-        test_messages.verify(requests, responses, self)
-
-  def testSequentialInvocations(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        first_request = test_messages.request()
-        second_request = test_messages.request()
-
-        first_response = self._invoker.blocking(group, method)(
-            first_request, test_constants.LONG_TIMEOUT)
-
-        test_messages.verify(first_request, first_response, self)
-
-        second_response = self._invoker.blocking(group, method)(
-            second_request, test_constants.LONG_TIMEOUT)
-
-        test_messages.verify(second_request, second_response, self)
-
-  def testParallelInvocations(self):
-    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = []
-        response_futures = []
-        for _ in range(test_constants.THREAD_CONCURRENCY):
-          request = test_messages.request()
-          response_future = pool.submit(
-              self._invoker.blocking(group, method), request,
-              test_constants.LONG_TIMEOUT)
-          requests.append(request)
-          response_futures.append(response_future)
-
-        responses = [
-            response_future.result() for response_future in response_futures]
-
-        for request, response in zip(requests, responses):
-          test_messages.verify(request, response, self)
-    pool.shutdown(wait=True)
-
-  def testWaitingForSomeButNotAllParallelInvocations(self):
-    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = []
-        response_futures_to_indices = {}
-        for index in range(test_constants.THREAD_CONCURRENCY):
-          request = test_messages.request()
-          response_future = pool.submit(
-              self._invoker.blocking(group, method), request,
-              test_constants.LONG_TIMEOUT)
-          requests.append(request)
-          response_futures_to_indices[response_future] = index
-
-        some_completed_response_futures_iterator = itertools.islice(
-            futures.as_completed(response_futures_to_indices),
-            test_constants.THREAD_CONCURRENCY // 2)
-        for response_future in some_completed_response_futures_iterator:
-          index = response_futures_to_indices[response_future]
-          test_messages.verify(requests[index], response_future.result(), self)
-    pool.shutdown(wait=True)
-
-  @unittest.skip('Cancellation impossible with blocking control flow!')
-  def testCancelledUnaryRequestUnaryResponse(self):
-    raise NotImplementedError()
-
-  @unittest.skip('Cancellation impossible with blocking control flow!')
-  def testCancelledUnaryRequestStreamResponse(self):
-    raise NotImplementedError()
-
-  @unittest.skip('Cancellation impossible with blocking control flow!')
-  def testCancelledStreamRequestUnaryResponse(self):
-    raise NotImplementedError()
-
-  @unittest.skip('Cancellation impossible with blocking control flow!')
-  def testCancelledStreamRequestStreamResponse(self):
-    raise NotImplementedError()
-
-  def testExpiredUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.pause(), self.assertRaises(
-            face.ExpirationError):
-          self._invoker.blocking(group, method)(
-              request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-
-  def testExpiredUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.pause(), self.assertRaises(
-            face.ExpirationError):
-          response_iterator = self._invoker.blocking(group, method)(
-              request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          list(response_iterator)
-
-  def testExpiredStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.pause(), self.assertRaises(
-            face.ExpirationError):
-          self._invoker.blocking(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-
-  def testExpiredStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.pause(), self.assertRaises(
-            face.ExpirationError):
-          response_iterator = self._invoker.blocking(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          list(response_iterator)
-
-  def testFailedUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.fail(), self.assertRaises(face.RemoteError):
-          self._invoker.blocking(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-
-  def testFailedUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.fail(), self.assertRaises(face.RemoteError):
-          response_iterator = self._invoker.blocking(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-          list(response_iterator)
-
-  def testFailedStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.fail(), self.assertRaises(face.RemoteError):
-          self._invoker.blocking(group, method)(
-              iter(requests), test_constants.LONG_TIMEOUT)
-
-  def testFailedStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.fail(), self.assertRaises(face.RemoteError):
-          response_iterator = self._invoker.blocking(group, method)(
-              iter(requests), test_constants.LONG_TIMEOUT)
-          list(response_iterator)
+        self._invoker = None
+        self.implementation.destantiate(self._memo)
+
+    def testSuccessfulUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                response, call = self._invoker.blocking(group, method)(
+                    request, test_constants.LONG_TIMEOUT, with_call=True)
+
+                test_messages.verify(request, response, self)
+
+    def testSuccessfulUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                response_iterator = self._invoker.blocking(group, method)(
+                    request, test_constants.LONG_TIMEOUT)
+                responses = list(response_iterator)
+
+                test_messages.verify(request, responses, self)
+
+    def testSuccessfulStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                response, call = self._invoker.blocking(group, method)(
+                    iter(requests), test_constants.LONG_TIMEOUT, with_call=True)
+
+                test_messages.verify(requests, response, self)
+
+    def testSuccessfulStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                response_iterator = self._invoker.blocking(group, method)(
+                    iter(requests), test_constants.LONG_TIMEOUT)
+                responses = list(response_iterator)
+
+                test_messages.verify(requests, responses, self)
+
+    def testSequentialInvocations(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                first_request = test_messages.request()
+                second_request = test_messages.request()
+
+                first_response = self._invoker.blocking(group, method)(
+                    first_request, test_constants.LONG_TIMEOUT)
+
+                test_messages.verify(first_request, first_response, self)
+
+                second_response = self._invoker.blocking(group, method)(
+                    second_request, test_constants.LONG_TIMEOUT)
+
+                test_messages.verify(second_request, second_response, self)
+
+    def testParallelInvocations(self):
+        pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = []
+                response_futures = []
+                for _ in range(test_constants.THREAD_CONCURRENCY):
+                    request = test_messages.request()
+                    response_future = pool.submit(
+                        self._invoker.blocking(group, method), request,
+                        test_constants.LONG_TIMEOUT)
+                    requests.append(request)
+                    response_futures.append(response_future)
+
+                responses = [
+                    response_future.result()
+                    for response_future in response_futures
+                ]
+
+                for request, response in zip(requests, responses):
+                    test_messages.verify(request, response, self)
+        pool.shutdown(wait=True)
+
+    def testWaitingForSomeButNotAllParallelInvocations(self):
+        pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = []
+                response_futures_to_indices = {}
+                for index in range(test_constants.THREAD_CONCURRENCY):
+                    request = test_messages.request()
+                    response_future = pool.submit(
+                        self._invoker.blocking(group, method), request,
+                        test_constants.LONG_TIMEOUT)
+                    requests.append(request)
+                    response_futures_to_indices[response_future] = index
+
+                some_completed_response_futures_iterator = itertools.islice(
+                    futures.as_completed(response_futures_to_indices),
+                    test_constants.THREAD_CONCURRENCY // 2)
+                for response_future in some_completed_response_futures_iterator:
+                    index = response_futures_to_indices[response_future]
+                    test_messages.verify(requests[index],
+                                         response_future.result(), self)
+        pool.shutdown(wait=True)
+
+    @unittest.skip('Cancellation impossible with blocking control flow!')
+    def testCancelledUnaryRequestUnaryResponse(self):
+        raise NotImplementedError()
+
+    @unittest.skip('Cancellation impossible with blocking control flow!')
+    def testCancelledUnaryRequestStreamResponse(self):
+        raise NotImplementedError()
+
+    @unittest.skip('Cancellation impossible with blocking control flow!')
+    def testCancelledStreamRequestUnaryResponse(self):
+        raise NotImplementedError()
+
+    @unittest.skip('Cancellation impossible with blocking control flow!')
+    def testCancelledStreamRequestStreamResponse(self):
+        raise NotImplementedError()
+
+    def testExpiredUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.pause(), self.assertRaises(
+                        face.ExpirationError):
+                    self._invoker.blocking(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+
+    def testExpiredUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.pause(), self.assertRaises(
+                        face.ExpirationError):
+                    response_iterator = self._invoker.blocking(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    list(response_iterator)
+
+    def testExpiredStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.pause(), self.assertRaises(
+                        face.ExpirationError):
+                    self._invoker.blocking(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+
+    def testExpiredStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.pause(), self.assertRaises(
+                        face.ExpirationError):
+                    response_iterator = self._invoker.blocking(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    list(response_iterator)
+
+    def testFailedUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.fail(), self.assertRaises(face.RemoteError):
+                    self._invoker.blocking(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+
+    def testFailedUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.fail(), self.assertRaises(face.RemoteError):
+                    response_iterator = self._invoker.blocking(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+                    list(response_iterator)
+
+    def testFailedStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.fail(), self.assertRaises(face.RemoteError):
+                    self._invoker.blocking(group, method)(
+                        iter(requests), test_constants.LONG_TIMEOUT)
+
+    def testFailedStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.fail(), self.assertRaises(face.RemoteError):
+                    response_iterator = self._invoker.blocking(group, method)(
+                        iter(requests), test_constants.LONG_TIMEOUT)
+                    list(response_iterator)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_digest.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_digest.py
index f0befb0b27..0411da0a66 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_digest.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_digest.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Code for making a service.TestService more amenable to use in tests."""
 
 import collections
@@ -49,17 +48,16 @@ _IDENTITY = lambda x: x
 
 
 class TestServiceDigest(
-    collections.namedtuple(
-        'TestServiceDigest',
-        ('methods',
-         'inline_method_implementations',
-         'event_method_implementations',
-         'multi_method_implementation',
-         'unary_unary_messages_sequences',
-         'unary_stream_messages_sequences',
-         'stream_unary_messages_sequences',
-         'stream_stream_messages_sequences',))):
-  """A transformation of a service.TestService.
+        collections.namedtuple('TestServiceDigest', (
+            'methods',
+            'inline_method_implementations',
+            'event_method_implementations',
+            'multi_method_implementation',
+            'unary_unary_messages_sequences',
+            'unary_stream_messages_sequences',
+            'stream_unary_messages_sequences',
+            'stream_stream_messages_sequences',))):
+    """A transformation of a service.TestService.
 
   Attributes:
     methods: A dict from method group-name pair to test_interfaces.Method object
@@ -88,303 +86,308 @@ class TestServiceDigest(
 
 
 class _BufferingConsumer(stream.Consumer):
-  """A trivial Consumer that dumps what it consumes in a user-mutable buffer."""
+    """A trivial Consumer that dumps what it consumes in a user-mutable buffer."""
 
-  def __init__(self):
-    self.consumed = []
-    self.terminated = False
+    def __init__(self):
+        self.consumed = []
+        self.terminated = False
 
-  def consume(self, value):
-    self.consumed.append(value)
+    def consume(self, value):
+        self.consumed.append(value)
 
-  def terminate(self):
-    self.terminated = True
+    def terminate(self):
+        self.terminated = True
 
-  def consume_and_terminate(self, value):
-    self.consumed.append(value)
-    self.terminated = True
+    def consume_and_terminate(self, value):
+        self.consumed.append(value)
+        self.terminated = True
 
 
 class _InlineUnaryUnaryMethod(face.MethodImplementation):
 
-  def __init__(self, unary_unary_test_method, control):
-    self._test_method = unary_unary_test_method
-    self._control = control
+    def __init__(self, unary_unary_test_method, control):
+        self._test_method = unary_unary_test_method
+        self._control = control
 
-    self.cardinality = cardinality.Cardinality.UNARY_UNARY
-    self.style = style.Service.INLINE
+        self.cardinality = cardinality.Cardinality.UNARY_UNARY
+        self.style = style.Service.INLINE
 
-  def unary_unary_inline(self, request, context):
-    response_list = []
-    self._test_method.service(
-        request, response_list.append, context, self._control)
-    return response_list.pop(0)
+    def unary_unary_inline(self, request, context):
+        response_list = []
+        self._test_method.service(request, response_list.append, context,
+                                  self._control)
+        return response_list.pop(0)
 
 
 class _EventUnaryUnaryMethod(face.MethodImplementation):
 
-  def __init__(self, unary_unary_test_method, control, pool):
-    self._test_method = unary_unary_test_method
-    self._control = control
-    self._pool = pool
+    def __init__(self, unary_unary_test_method, control, pool):
+        self._test_method = unary_unary_test_method
+        self._control = control
+        self._pool = pool
 
-    self.cardinality = cardinality.Cardinality.UNARY_UNARY
-    self.style = style.Service.EVENT
+        self.cardinality = cardinality.Cardinality.UNARY_UNARY
+        self.style = style.Service.EVENT
 
-  def unary_unary_event(self, request, response_callback, context):
-    if self._pool is None:
-      self._test_method.service(
-          request, response_callback, context, self._control)
-    else:
-      self._pool.submit(
-          self._test_method.service, request, response_callback, context,
-          self._control)
+    def unary_unary_event(self, request, response_callback, context):
+        if self._pool is None:
+            self._test_method.service(request, response_callback, context,
+                                      self._control)
+        else:
+            self._pool.submit(self._test_method.service, request,
+                              response_callback, context, self._control)
 
 
 class _InlineUnaryStreamMethod(face.MethodImplementation):
 
-  def __init__(self, unary_stream_test_method, control):
-    self._test_method = unary_stream_test_method
-    self._control = control
+    def __init__(self, unary_stream_test_method, control):
+        self._test_method = unary_stream_test_method
+        self._control = control
 
-    self.cardinality = cardinality.Cardinality.UNARY_STREAM
-    self.style = style.Service.INLINE
+        self.cardinality = cardinality.Cardinality.UNARY_STREAM
+        self.style = style.Service.INLINE
 
-  def unary_stream_inline(self, request, context):
-    response_consumer = _BufferingConsumer()
-    self._test_method.service(
-        request, response_consumer, context, self._control)
-    for response in response_consumer.consumed:
-      yield response
+    def unary_stream_inline(self, request, context):
+        response_consumer = _BufferingConsumer()
+        self._test_method.service(request, response_consumer, context,
+                                  self._control)
+        for response in response_consumer.consumed:
+            yield response
 
 
 class _EventUnaryStreamMethod(face.MethodImplementation):
 
-  def __init__(self, unary_stream_test_method, control, pool):
-    self._test_method = unary_stream_test_method
-    self._control = control
-    self._pool = pool
+    def __init__(self, unary_stream_test_method, control, pool):
+        self._test_method = unary_stream_test_method
+        self._control = control
+        self._pool = pool
 
-    self.cardinality = cardinality.Cardinality.UNARY_STREAM
-    self.style = style.Service.EVENT
+        self.cardinality = cardinality.Cardinality.UNARY_STREAM
+        self.style = style.Service.EVENT
 
-  def unary_stream_event(self, request, response_consumer, context):
-    if self._pool is None:
-      self._test_method.service(
-          request, response_consumer, context, self._control)
-    else:
-      self._pool.submit(
-          self._test_method.service, request, response_consumer, context,
-          self._control)
+    def unary_stream_event(self, request, response_consumer, context):
+        if self._pool is None:
+            self._test_method.service(request, response_consumer, context,
+                                      self._control)
+        else:
+            self._pool.submit(self._test_method.service, request,
+                              response_consumer, context, self._control)
 
 
 class _InlineStreamUnaryMethod(face.MethodImplementation):
 
-  def __init__(self, stream_unary_test_method, control):
-    self._test_method = stream_unary_test_method
-    self._control = control
+    def __init__(self, stream_unary_test_method, control):
+        self._test_method = stream_unary_test_method
+        self._control = control
 
-    self.cardinality = cardinality.Cardinality.STREAM_UNARY
-    self.style = style.Service.INLINE
+        self.cardinality = cardinality.Cardinality.STREAM_UNARY
+        self.style = style.Service.INLINE
 
-  def stream_unary_inline(self, request_iterator, context):
-    response_list = []
-    request_consumer = self._test_method.service(
-        response_list.append, context, self._control)
-    for request in request_iterator:
-      request_consumer.consume(request)
-    request_consumer.terminate()
-    return response_list.pop(0)
+    def stream_unary_inline(self, request_iterator, context):
+        response_list = []
+        request_consumer = self._test_method.service(response_list.append,
+                                                     context, self._control)
+        for request in request_iterator:
+            request_consumer.consume(request)
+        request_consumer.terminate()
+        return response_list.pop(0)
 
 
 class _EventStreamUnaryMethod(face.MethodImplementation):
 
-  def __init__(self, stream_unary_test_method, control, pool):
-    self._test_method = stream_unary_test_method
-    self._control = control
-    self._pool = pool
+    def __init__(self, stream_unary_test_method, control, pool):
+        self._test_method = stream_unary_test_method
+        self._control = control
+        self._pool = pool
 
-    self.cardinality = cardinality.Cardinality.STREAM_UNARY
-    self.style = style.Service.EVENT
+        self.cardinality = cardinality.Cardinality.STREAM_UNARY
+        self.style = style.Service.EVENT
 
-  def stream_unary_event(self, response_callback, context):
-    request_consumer = self._test_method.service(
-        response_callback, context, self._control)
-    if self._pool is None:
-      return request_consumer
-    else:
-      return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool)
+    def stream_unary_event(self, response_callback, context):
+        request_consumer = self._test_method.service(response_callback, context,
+                                                     self._control)
+        if self._pool is None:
+            return request_consumer
+        else:
+            return stream_util.ThreadSwitchingConsumer(request_consumer,
+                                                       self._pool)
 
 
 class _InlineStreamStreamMethod(face.MethodImplementation):
 
-  def __init__(self, stream_stream_test_method, control):
-    self._test_method = stream_stream_test_method
-    self._control = control
+    def __init__(self, stream_stream_test_method, control):
+        self._test_method = stream_stream_test_method
+        self._control = control
 
-    self.cardinality = cardinality.Cardinality.STREAM_STREAM
-    self.style = style.Service.INLINE
+        self.cardinality = cardinality.Cardinality.STREAM_STREAM
+        self.style = style.Service.INLINE
 
-  def stream_stream_inline(self, request_iterator, context):
-    response_consumer = _BufferingConsumer()
-    request_consumer = self._test_method.service(
-        response_consumer, context, self._control)
+    def stream_stream_inline(self, request_iterator, context):
+        response_consumer = _BufferingConsumer()
+        request_consumer = self._test_method.service(response_consumer, context,
+                                                     self._control)
 
-    for request in request_iterator:
-      request_consumer.consume(request)
-      while response_consumer.consumed:
-        yield response_consumer.consumed.pop(0)
-    response_consumer.terminate()
+        for request in request_iterator:
+            request_consumer.consume(request)
+            while response_consumer.consumed:
+                yield response_consumer.consumed.pop(0)
+        response_consumer.terminate()
 
 
 class _EventStreamStreamMethod(face.MethodImplementation):
 
-  def __init__(self, stream_stream_test_method, control, pool):
-    self._test_method = stream_stream_test_method
-    self._control = control
-    self._pool = pool
+    def __init__(self, stream_stream_test_method, control, pool):
+        self._test_method = stream_stream_test_method
+        self._control = control
+        self._pool = pool
 
-    self.cardinality = cardinality.Cardinality.STREAM_STREAM
-    self.style = style.Service.EVENT
+        self.cardinality = cardinality.Cardinality.STREAM_STREAM
+        self.style = style.Service.EVENT
 
-  def stream_stream_event(self, response_consumer, context):
-    request_consumer = self._test_method.service(
-        response_consumer, context, self._control)
-    if self._pool is None:
-      return request_consumer
-    else:
-      return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool)
+    def stream_stream_event(self, response_consumer, context):
+        request_consumer = self._test_method.service(response_consumer, context,
+                                                     self._control)
+        if self._pool is None:
+            return request_consumer
+        else:
+            return stream_util.ThreadSwitchingConsumer(request_consumer,
+                                                       self._pool)
 
 
 class _UnaryConsumer(stream.Consumer):
-  """A Consumer that only allows consumption of exactly one value."""
-
-  def __init__(self, action):
-    self._lock = threading.Lock()
-    self._action = action
-    self._consumed = False
-    self._terminated = False
-
-  def consume(self, value):
-    with self._lock:
-      if self._consumed:
-        raise ValueError('Unary consumer already consumed!')
-      elif self._terminated:
-        raise ValueError('Unary consumer already terminated!')
-      else:
-        self._consumed = True
-
-    self._action(value)
-
-  def terminate(self):
-    with self._lock:
-      if not self._consumed:
-        raise ValueError('Unary consumer hasn\'t yet consumed!')
-      elif self._terminated:
-        raise ValueError('Unary consumer already terminated!')
-      else:
-        self._terminated = True
-
-  def consume_and_terminate(self, value):
-    with self._lock:
-      if self._consumed:
-        raise ValueError('Unary consumer already consumed!')
-      elif self._terminated:
-        raise ValueError('Unary consumer already terminated!')
-      else:
-        self._consumed = True
-        self._terminated = True
-
-    self._action(value)
+    """A Consumer that only allows consumption of exactly one value."""
+
+    def __init__(self, action):
+        self._lock = threading.Lock()
+        self._action = action
+        self._consumed = False
+        self._terminated = False
+
+    def consume(self, value):
+        with self._lock:
+            if self._consumed:
+                raise ValueError('Unary consumer already consumed!')
+            elif self._terminated:
+                raise ValueError('Unary consumer already terminated!')
+            else:
+                self._consumed = True
+
+        self._action(value)
+
+    def terminate(self):
+        with self._lock:
+            if not self._consumed:
+                raise ValueError('Unary consumer hasn\'t yet consumed!')
+            elif self._terminated:
+                raise ValueError('Unary consumer already terminated!')
+            else:
+                self._terminated = True
+
+    def consume_and_terminate(self, value):
+        with self._lock:
+            if self._consumed:
+                raise ValueError('Unary consumer already consumed!')
+            elif self._terminated:
+                raise ValueError('Unary consumer already terminated!')
+            else:
+                self._consumed = True
+                self._terminated = True
+
+        self._action(value)
 
 
 class _UnaryUnaryAdaptation(object):
 
-  def __init__(self, unary_unary_test_method):
-    self._method = unary_unary_test_method
+    def __init__(self, unary_unary_test_method):
+        self._method = unary_unary_test_method
+
+    def service(self, response_consumer, context, control):
+
+        def action(request):
+            self._method.service(request,
+                                 response_consumer.consume_and_terminate,
+                                 context, control)
 
-  def service(self, response_consumer, context, control):
-    def action(request):
-      self._method.service(
-          request, response_consumer.consume_and_terminate, context, control)
-    return _UnaryConsumer(action)
+        return _UnaryConsumer(action)
 
 
 class _UnaryStreamAdaptation(object):
 
-  def __init__(self, unary_stream_test_method):
-    self._method = unary_stream_test_method
+    def __init__(self, unary_stream_test_method):
+        self._method = unary_stream_test_method
+
+    def service(self, response_consumer, context, control):
+
+        def action(request):
+            self._method.service(request, response_consumer, context, control)
 
-  def service(self, response_consumer, context, control):
-    def action(request):
-      self._method.service(request, response_consumer, context, control)
-    return _UnaryConsumer(action)
+        return _UnaryConsumer(action)
 
 
 class _StreamUnaryAdaptation(object):
 
-  def __init__(self, stream_unary_test_method):
-    self._method = stream_unary_test_method
+    def __init__(self, stream_unary_test_method):
+        self._method = stream_unary_test_method
 
-  def service(self, response_consumer, context, control):
-    return self._method.service(
-        response_consumer.consume_and_terminate, context, control)
+    def service(self, response_consumer, context, control):
+        return self._method.service(response_consumer.consume_and_terminate,
+                                    context, control)
 
 
 class _MultiMethodImplementation(face.MultiMethodImplementation):
 
-  def __init__(self, methods, control, pool):
-    self._methods = methods
-    self._control = control
-    self._pool = pool
+    def __init__(self, methods, control, pool):
+        self._methods = methods
+        self._control = control
+        self._pool = pool
 
-  def service(self, group, name, response_consumer, context):
-    method = self._methods.get(group, name, None)
-    if method is None:
-      raise face.NoSuchMethodError(group, name)
-    elif self._pool is None:
-      return method(response_consumer, context, self._control)
-    else:
-      request_consumer = method(response_consumer, context, self._control)
-      return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool)
+    def service(self, group, name, response_consumer, context):
+        method = self._methods.get(group, name, None)
+        if method is None:
+            raise face.NoSuchMethodError(group, name)
+        elif self._pool is None:
+            return method(response_consumer, context, self._control)
+        else:
+            request_consumer = method(response_consumer, context, self._control)
+            return stream_util.ThreadSwitchingConsumer(request_consumer,
+                                                       self._pool)
 
 
 class _Assembly(
-    collections.namedtuple(
-        '_Assembly',
-        ['methods', 'inlines', 'events', 'adaptations', 'messages'])):
-  """An intermediate structure created when creating a TestServiceDigest."""
-
-
-def _assemble(
-    scenarios, identifiers, inline_method_constructor, event_method_constructor,
-    adapter, control, pool):
-  """Creates an _Assembly from the given scenarios."""
-  methods = {}
-  inlines = {}
-  events = {}
-  adaptations = {}
-  messages = {}
-  for identifier, scenario in six.iteritems(scenarios):
-    if identifier in identifiers:
-      raise ValueError('Repeated identifier "(%s, %s)"!' % identifier)
-
-    test_method = scenario[0]
-    inline_method = inline_method_constructor(test_method, control)
-    event_method = event_method_constructor(test_method, control, pool)
-    adaptation = adapter(test_method)
-
-    methods[identifier] = test_method
-    inlines[identifier] = inline_method
-    events[identifier] = event_method
-    adaptations[identifier] = adaptation
-    messages[identifier] = scenario[1]
-
-  return _Assembly(methods, inlines, events, adaptations, messages)
+        collections.namedtuple(
+            '_Assembly',
+            ['methods', 'inlines', 'events', 'adaptations', 'messages'])):
+    """An intermediate structure created when creating a TestServiceDigest."""
+
+
+def _assemble(scenarios, identifiers, inline_method_constructor,
+              event_method_constructor, adapter, control, pool):
+    """Creates an _Assembly from the given scenarios."""
+    methods = {}
+    inlines = {}
+    events = {}
+    adaptations = {}
+    messages = {}
+    for identifier, scenario in six.iteritems(scenarios):
+        if identifier in identifiers:
+            raise ValueError('Repeated identifier "(%s, %s)"!' % identifier)
+
+        test_method = scenario[0]
+        inline_method = inline_method_constructor(test_method, control)
+        event_method = event_method_constructor(test_method, control, pool)
+        adaptation = adapter(test_method)
+
+        methods[identifier] = test_method
+        inlines[identifier] = inline_method
+        events[identifier] = event_method
+        adaptations[identifier] = adaptation
+        messages[identifier] = scenario[1]
+
+    return _Assembly(methods, inlines, events, adaptations, messages)
 
 
 def digest(service, control, pool):
-  """Creates a TestServiceDigest from a TestService.
+    """Creates a TestServiceDigest from a TestService.
 
   Args:
     service: A _service.TestService.
@@ -396,51 +399,48 @@ def digest(service, control, pool):
   Returns:
     A TestServiceDigest synthesized from the given service.TestService.
   """
-  identifiers = set()
-
-  unary_unary = _assemble(
-      service.unary_unary_scenarios(), identifiers, _InlineUnaryUnaryMethod,
-      _EventUnaryUnaryMethod, _UnaryUnaryAdaptation, control, pool)
-  identifiers.update(unary_unary.inlines)
-
-  unary_stream = _assemble(
-      service.unary_stream_scenarios(), identifiers, _InlineUnaryStreamMethod,
-      _EventUnaryStreamMethod, _UnaryStreamAdaptation, control, pool)
-  identifiers.update(unary_stream.inlines)
-
-  stream_unary = _assemble(
-      service.stream_unary_scenarios(), identifiers, _InlineStreamUnaryMethod,
-      _EventStreamUnaryMethod, _StreamUnaryAdaptation, control, pool)
-  identifiers.update(stream_unary.inlines)
-
-  stream_stream = _assemble(
-      service.stream_stream_scenarios(), identifiers, _InlineStreamStreamMethod,
-      _EventStreamStreamMethod, _IDENTITY, control, pool)
-  identifiers.update(stream_stream.inlines)
-
-  methods = dict(unary_unary.methods)
-  methods.update(unary_stream.methods)
-  methods.update(stream_unary.methods)
-  methods.update(stream_stream.methods)
-  adaptations = dict(unary_unary.adaptations)
-  adaptations.update(unary_stream.adaptations)
-  adaptations.update(stream_unary.adaptations)
-  adaptations.update(stream_stream.adaptations)
-  inlines = dict(unary_unary.inlines)
-  inlines.update(unary_stream.inlines)
-  inlines.update(stream_unary.inlines)
-  inlines.update(stream_stream.inlines)
-  events = dict(unary_unary.events)
-  events.update(unary_stream.events)
-  events.update(stream_unary.events)
-  events.update(stream_stream.events)
-
-  return TestServiceDigest(
-      methods,
-      inlines,
-      events,
-      _MultiMethodImplementation(adaptations, control, pool),
-      unary_unary.messages,
-      unary_stream.messages,
-      stream_unary.messages,
-      stream_stream.messages)
+    identifiers = set()
+
+    unary_unary = _assemble(service.unary_unary_scenarios(), identifiers,
+                            _InlineUnaryUnaryMethod, _EventUnaryUnaryMethod,
+                            _UnaryUnaryAdaptation, control, pool)
+    identifiers.update(unary_unary.inlines)
+
+    unary_stream = _assemble(service.unary_stream_scenarios(), identifiers,
+                             _InlineUnaryStreamMethod, _EventUnaryStreamMethod,
+                             _UnaryStreamAdaptation, control, pool)
+    identifiers.update(unary_stream.inlines)
+
+    stream_unary = _assemble(service.stream_unary_scenarios(), identifiers,
+                             _InlineStreamUnaryMethod, _EventStreamUnaryMethod,
+                             _StreamUnaryAdaptation, control, pool)
+    identifiers.update(stream_unary.inlines)
+
+    stream_stream = _assemble(service.stream_stream_scenarios(), identifiers,
+                              _InlineStreamStreamMethod,
+                              _EventStreamStreamMethod, _IDENTITY, control,
+                              pool)
+    identifiers.update(stream_stream.inlines)
+
+    methods = dict(unary_unary.methods)
+    methods.update(unary_stream.methods)
+    methods.update(stream_unary.methods)
+    methods.update(stream_stream.methods)
+    adaptations = dict(unary_unary.adaptations)
+    adaptations.update(unary_stream.adaptations)
+    adaptations.update(stream_unary.adaptations)
+    adaptations.update(stream_stream.adaptations)
+    inlines = dict(unary_unary.inlines)
+    inlines.update(unary_stream.inlines)
+    inlines.update(stream_unary.inlines)
+    inlines.update(stream_stream.inlines)
+    events = dict(unary_unary.events)
+    events.update(unary_stream.events)
+    events.update(stream_unary.events)
+    events.update(stream_stream.events)
+
+    return TestServiceDigest(
+        methods, inlines, events,
+        _MultiMethodImplementation(adaptations, control, pool),
+        unary_unary.messages, unary_stream.messages, stream_unary.messages,
+        stream_stream.messages)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
index df620b19ba..703eef3a82 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
@@ -26,7 +26,6 @@
 # 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 code for the Face layer of RPC Framework."""
 
 from __future__ import division
@@ -55,457 +54,470 @@ from tests.unit.framework.interfaces.face import test_interfaces  # pylint: disa
 
 class _PauseableIterator(object):
 
-  def __init__(self, upstream):
-    self._upstream = upstream
-    self._condition = threading.Condition()
-    self._paused = False
+    def __init__(self, upstream):
+        self._upstream = upstream
+        self._condition = threading.Condition()
+        self._paused = False
 
-  @contextlib.contextmanager
-  def pause(self):
-    with self._condition:
-      self._paused = True
-    yield
-    with self._condition:
-      self._paused = False
-      self._condition.notify_all()
+    @contextlib.contextmanager
+    def pause(self):
+        with self._condition:
+            self._paused = True
+        yield
+        with self._condition:
+            self._paused = False
+            self._condition.notify_all()
 
-  def __iter__(self):
-    return self
+    def __iter__(self):
+        return self
 
-  def __next__(self):
-    return self.next()
+    def __next__(self):
+        return self.next()
 
-  def next(self):
-    with self._condition:
-      while self._paused:
-        self._condition.wait()
-    return next(self._upstream)
+    def next(self):
+        with self._condition:
+            while self._paused:
+                self._condition.wait()
+        return next(self._upstream)
 
 
 class _Callback(object):
 
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._called = False
-    self._passed_future = None
-    self._passed_other_stuff = None
-
-  def __call__(self, *args, **kwargs):
-    with self._condition:
-      self._called = True
-      if args:
-        self._passed_future = args[0]
-      if 1 < len(args) or kwargs:
-        self._passed_other_stuff = tuple(args[1:]), dict(kwargs)
-      self._condition.notify_all()
-
-  def future(self):
-    with self._condition:
-      while True:
-        if self._passed_other_stuff is not None:
-          raise ValueError(
-              'Test callback passed unexpected values: %s',
-              self._passed_other_stuff)
-        elif self._called:
-          return self._passed_future
-        else:
-          self._condition.wait()
-
-
-class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.TestCase)):
-  """A test of the Face layer of RPC Framework.
+    def __init__(self):
+        self._condition = threading.Condition()
+        self._called = False
+        self._passed_future = None
+        self._passed_other_stuff = None
+
+    def __call__(self, *args, **kwargs):
+        with self._condition:
+            self._called = True
+            if args:
+                self._passed_future = args[0]
+            if 1 < len(args) or kwargs:
+                self._passed_other_stuff = tuple(args[1:]), dict(kwargs)
+            self._condition.notify_all()
+
+    def future(self):
+        with self._condition:
+            while True:
+                if self._passed_other_stuff is not None:
+                    raise ValueError(
+                        'Test callback passed unexpected values: %s',
+                        self._passed_other_stuff)
+                elif self._called:
+                    return self._passed_future
+                else:
+                    self._condition.wait()
+
+
+class TestCase(
+        six.with_metaclass(abc.ABCMeta, test_coverage.Coverage,
+                           unittest.TestCase)):
+    """A test of the Face layer of RPC Framework.
 
   Concrete subclasses must have an "implementation" attribute of type
   test_interfaces.Implementation and an "invoker_constructor" attribute of type
   _invocation.InvokerConstructor.
   """
 
-  NAME = 'FutureInvocationAsynchronousEventServiceTest'
+    NAME = 'FutureInvocationAsynchronousEventServiceTest'
 
-  def setUp(self):
-    """See unittest.TestCase.setUp for full specification.
+    def setUp(self):
+        """See unittest.TestCase.setUp for full specification.
 
     Overriding implementations must call this implementation.
     """
-    self._control = test_control.PauseFailControl()
-    self._digest_pool = logging_pool.pool(test_constants.POOL_SIZE)
-    self._digest = _digest.digest(
-        _stock_service.STOCK_TEST_SERVICE, self._control, self._digest_pool)
+        self._control = test_control.PauseFailControl()
+        self._digest_pool = logging_pool.pool(test_constants.POOL_SIZE)
+        self._digest = _digest.digest(_stock_service.STOCK_TEST_SERVICE,
+                                      self._control, self._digest_pool)
 
-    generic_stub, dynamic_stubs, self._memo = self.implementation.instantiate(
-        self._digest.methods, self._digest.event_method_implementations, None)
-    self._invoker = self.invoker_constructor.construct_invoker(
-        generic_stub, dynamic_stubs, self._digest.methods)
+        generic_stub, dynamic_stubs, self._memo = self.implementation.instantiate(
+            self._digest.methods, self._digest.event_method_implementations,
+            None)
+        self._invoker = self.invoker_constructor.construct_invoker(
+            generic_stub, dynamic_stubs, self._digest.methods)
 
-  def tearDown(self):
-    """See unittest.TestCase.tearDown for full specification.
+    def tearDown(self):
+        """See unittest.TestCase.tearDown for full specification.
 
     Overriding implementations must call this implementation.
     """
-    self._invoker = None
-    self.implementation.destantiate(self._memo)
-    self._digest_pool.shutdown(wait=True)
-
-  def testSuccessfulUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-        callback = _Callback()
-
-        response_future = self._invoker.future(group, method)(
-            request, test_constants.LONG_TIMEOUT)
-        response_future.add_done_callback(callback)
-        response = response_future.result()
-
-        test_messages.verify(request, response, self)
-        self.assertIs(callback.future(), response_future)
-        self.assertIsNone(response_future.exception())
-        self.assertIsNone(response_future.traceback())
-
-  def testSuccessfulUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        response_iterator = self._invoker.future(group, method)(
-            request, test_constants.LONG_TIMEOUT)
-        responses = list(response_iterator)
-
-        test_messages.verify(request, responses, self)
-
-  def testSuccessfulStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-        request_iterator = _PauseableIterator(iter(requests))
-        callback = _Callback()
-
-        # Use of a paused iterator of requests allows us to test that control is
-        # returned to calling code before the iterator yields any requests.
-        with request_iterator.pause():
-          response_future = self._invoker.future(group, method)(
-              request_iterator, test_constants.LONG_TIMEOUT)
-          response_future.add_done_callback(callback)
-        future_passed_to_callback = callback.future()
-        response = future_passed_to_callback.result()
-
-        test_messages.verify(requests, response, self)
-        self.assertIs(future_passed_to_callback, response_future)
-        self.assertIsNone(response_future.exception())
-        self.assertIsNone(response_future.traceback())
-
-  def testSuccessfulStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-        request_iterator = _PauseableIterator(iter(requests))
-
-        # Use of a paused iterator of requests allows us to test that control is
-        # returned to calling code before the iterator yields any requests.
-        with request_iterator.pause():
-          response_iterator = self._invoker.future(group, method)(
-              request_iterator, test_constants.LONG_TIMEOUT)
-        responses = list(response_iterator)
-
-        test_messages.verify(requests, responses, self)
-
-  def testSequentialInvocations(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        first_request = test_messages.request()
-        second_request = test_messages.request()
-
-        first_response_future = self._invoker.future(group, method)(
-            first_request, test_constants.LONG_TIMEOUT)
-        first_response = first_response_future.result()
-
-        test_messages.verify(first_request, first_response, self)
-
-        second_response_future = self._invoker.future(group, method)(
-            second_request, test_constants.LONG_TIMEOUT)
-        second_response = second_response_future.result()
-
-        test_messages.verify(second_request, second_response, self)
-
-  def testParallelInvocations(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        first_request = test_messages.request()
-        second_request = test_messages.request()
-
-        first_response_future = self._invoker.future(group, method)(
-            first_request, test_constants.LONG_TIMEOUT)
-        second_response_future = self._invoker.future(group, method)(
-            second_request, test_constants.LONG_TIMEOUT)
-        first_response = first_response_future.result()
-        second_response = second_response_future.result()
-
-        test_messages.verify(first_request, first_response, self)
-        test_messages.verify(second_request, second_response, self)
-
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = []
-        response_futures = []
-        for _ in range(test_constants.THREAD_CONCURRENCY):
-          request = test_messages.request()
-          response_future = self._invoker.future(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-          requests.append(request)
-          response_futures.append(response_future)
-
-        responses = [
-            response_future.result() for response_future in response_futures]
-
-        for request, response in zip(requests, responses):
-          test_messages.verify(request, response, self)
-
-  def testWaitingForSomeButNotAllParallelInvocations(self):
-    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = []
-        response_futures_to_indices = {}
-        for index in range(test_constants.THREAD_CONCURRENCY):
-          request = test_messages.request()
-          inner_response_future = self._invoker.future(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-          outer_response_future = pool.submit(inner_response_future.result)
-          requests.append(request)
-          response_futures_to_indices[outer_response_future] = index
-
-        some_completed_response_futures_iterator = itertools.islice(
-            futures.as_completed(response_futures_to_indices),
-            test_constants.THREAD_CONCURRENCY // 2)
-        for response_future in some_completed_response_futures_iterator:
-          index = response_futures_to_indices[response_future]
-          test_messages.verify(requests[index], response_future.result(), self)
-    pool.shutdown(wait=True)
-
-  def testCancelledUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-        callback = _Callback()
-
-        with self._control.pause():
-          response_future = self._invoker.future(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-          response_future.add_done_callback(callback)
-          cancel_method_return_value = response_future.cancel()
-
-        self.assertIs(callback.future(), response_future)
-        self.assertFalse(cancel_method_return_value)
-        self.assertTrue(response_future.cancelled())
-        with self.assertRaises(future.CancelledError):
-          response_future.result()
-        with self.assertRaises(future.CancelledError):
-          response_future.exception()
-        with self.assertRaises(future.CancelledError):
-          response_future.traceback()
-
-  def testCancelledUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.pause():
-          response_iterator = self._invoker.future(group, method)(
-              request, test_constants.LONG_TIMEOUT)
-          response_iterator.cancel()
-
-        with self.assertRaises(face.CancellationError):
-          next(response_iterator)
-
-  def testCancelledStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-        callback = _Callback()
-
-        with self._control.pause():
-          response_future = self._invoker.future(group, method)(
-              iter(requests), test_constants.LONG_TIMEOUT)
-          response_future.add_done_callback(callback)
-          cancel_method_return_value = response_future.cancel()
-
-        self.assertIs(callback.future(), response_future)
-        self.assertFalse(cancel_method_return_value)
-        self.assertTrue(response_future.cancelled())
-        with self.assertRaises(future.CancelledError):
-          response_future.result()
-        with self.assertRaises(future.CancelledError):
-          response_future.exception()
-        with self.assertRaises(future.CancelledError):
-          response_future.traceback()
-
-  def testCancelledStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.pause():
-          response_iterator = self._invoker.future(group, method)(
-              iter(requests), test_constants.LONG_TIMEOUT)
-          response_iterator.cancel()
-
-        with self.assertRaises(face.CancellationError):
-          next(response_iterator)
-
-  def testExpiredUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-        callback = _Callback()
-
-        with self._control.pause():
-          response_future = self._invoker.future(
-              group, method)(request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          response_future.add_done_callback(callback)
-          self.assertIs(callback.future(), response_future)
-          self.assertIsInstance(
-              response_future.exception(), face.ExpirationError)
-          with self.assertRaises(face.ExpirationError):
-            response_future.result()
-          self.assertIsInstance(
-              response_future.exception(), face.AbortionError)
-          self.assertIsNotNone(response_future.traceback())
-
-  def testExpiredUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        with self._control.pause():
-          response_iterator = self._invoker.future(group, method)(
-              request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          with self.assertRaises(face.ExpirationError):
-            list(response_iterator)
-
-  def testExpiredStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-        callback = _Callback()
-
-        with self._control.pause():
-          response_future = self._invoker.future(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          response_future.add_done_callback(callback)
-          self.assertIs(callback.future(), response_future)
-          self.assertIsInstance(
-              response_future.exception(), face.ExpirationError)
-          with self.assertRaises(face.ExpirationError):
-            response_future.result()
-          self.assertIsInstance(
-              response_future.exception(), face.AbortionError)
-          self.assertIsNotNone(response_future.traceback())
-
-  def testExpiredStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        with self._control.pause():
-          response_iterator = self._invoker.future(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          with self.assertRaises(face.ExpirationError):
-            list(response_iterator)
-
-  def testFailedUnaryRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-        callback = _Callback()
-        abortion_callback = _Callback()
-
-        with self._control.fail():
-          response_future = self._invoker.future(group, method)(
-              request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          response_future.add_done_callback(callback)
-          response_future.add_abortion_callback(abortion_callback)
-
-          self.assertIs(callback.future(), response_future)
-          # Because the servicer fails outside of the thread from which the
-          # servicer-side runtime called into it its failure is
-          # indistinguishable from simply not having called its
-          # response_callback before the expiration of the RPC.
-          self.assertIsInstance(
-              response_future.exception(), face.ExpirationError)
-          with self.assertRaises(face.ExpirationError):
-            response_future.result()
-          self.assertIsNotNone(response_future.traceback())
-          self.assertIsNotNone(abortion_callback.future())
-
-  def testFailedUnaryRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.unary_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        request = test_messages.request()
-
-        # Because the servicer fails outside of the thread from which the
-        # servicer-side runtime called into it its failure is indistinguishable
-        # from simply not having called its response_consumer before the
-        # expiration of the RPC.
-        with self._control.fail(), self.assertRaises(face.ExpirationError):
-          response_iterator = self._invoker.future(group, method)(
-              request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          list(response_iterator)
-
-  def testFailedStreamRequestUnaryResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_unary_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-        callback = _Callback()
-        abortion_callback = _Callback()
-
-        with self._control.fail():
-          response_future = self._invoker.future(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          response_future.add_done_callback(callback)
-          response_future.add_abortion_callback(abortion_callback)
-
-          self.assertIs(callback.future(), response_future)
-          # Because the servicer fails outside of the thread from which the
-          # servicer-side runtime called into it its failure is
-          # indistinguishable from simply not having called its
-          # response_callback before the expiration of the RPC.
-          self.assertIsInstance(
-              response_future.exception(), face.ExpirationError)
-          with self.assertRaises(face.ExpirationError):
-            response_future.result()
-          self.assertIsNotNone(response_future.traceback())
-          self.assertIsNotNone(abortion_callback.future())
-
-  def testFailedStreamRequestStreamResponse(self):
-    for (group, method), test_messages_sequence in (
-        six.iteritems(self._digest.stream_stream_messages_sequences)):
-      for test_messages in test_messages_sequence:
-        requests = test_messages.requests()
-
-        # Because the servicer fails outside of the thread from which the
-        # servicer-side runtime called into it its failure is indistinguishable
-        # from simply not having called its response_consumer before the
-        # expiration of the RPC.
-        with self._control.fail(), self.assertRaises(face.ExpirationError):
-          response_iterator = self._invoker.future(group, method)(
-              iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
-          list(response_iterator)
+        self._invoker = None
+        self.implementation.destantiate(self._memo)
+        self._digest_pool.shutdown(wait=True)
+
+    def testSuccessfulUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+                callback = _Callback()
+
+                response_future = self._invoker.future(group, method)(
+                    request, test_constants.LONG_TIMEOUT)
+                response_future.add_done_callback(callback)
+                response = response_future.result()
+
+                test_messages.verify(request, response, self)
+                self.assertIs(callback.future(), response_future)
+                self.assertIsNone(response_future.exception())
+                self.assertIsNone(response_future.traceback())
+
+    def testSuccessfulUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                response_iterator = self._invoker.future(group, method)(
+                    request, test_constants.LONG_TIMEOUT)
+                responses = list(response_iterator)
+
+                test_messages.verify(request, responses, self)
+
+    def testSuccessfulStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+                request_iterator = _PauseableIterator(iter(requests))
+                callback = _Callback()
+
+                # Use of a paused iterator of requests allows us to test that control is
+                # returned to calling code before the iterator yields any requests.
+                with request_iterator.pause():
+                    response_future = self._invoker.future(group, method)(
+                        request_iterator, test_constants.LONG_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                future_passed_to_callback = callback.future()
+                response = future_passed_to_callback.result()
+
+                test_messages.verify(requests, response, self)
+                self.assertIs(future_passed_to_callback, response_future)
+                self.assertIsNone(response_future.exception())
+                self.assertIsNone(response_future.traceback())
+
+    def testSuccessfulStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+                request_iterator = _PauseableIterator(iter(requests))
+
+                # Use of a paused iterator of requests allows us to test that control is
+                # returned to calling code before the iterator yields any requests.
+                with request_iterator.pause():
+                    response_iterator = self._invoker.future(group, method)(
+                        request_iterator, test_constants.LONG_TIMEOUT)
+                responses = list(response_iterator)
+
+                test_messages.verify(requests, responses, self)
+
+    def testSequentialInvocations(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                first_request = test_messages.request()
+                second_request = test_messages.request()
+
+                first_response_future = self._invoker.future(group, method)(
+                    first_request, test_constants.LONG_TIMEOUT)
+                first_response = first_response_future.result()
+
+                test_messages.verify(first_request, first_response, self)
+
+                second_response_future = self._invoker.future(group, method)(
+                    second_request, test_constants.LONG_TIMEOUT)
+                second_response = second_response_future.result()
+
+                test_messages.verify(second_request, second_response, self)
+
+    def testParallelInvocations(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                first_request = test_messages.request()
+                second_request = test_messages.request()
+
+                first_response_future = self._invoker.future(group, method)(
+                    first_request, test_constants.LONG_TIMEOUT)
+                second_response_future = self._invoker.future(group, method)(
+                    second_request, test_constants.LONG_TIMEOUT)
+                first_response = first_response_future.result()
+                second_response = second_response_future.result()
+
+                test_messages.verify(first_request, first_response, self)
+                test_messages.verify(second_request, second_response, self)
+
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = []
+                response_futures = []
+                for _ in range(test_constants.THREAD_CONCURRENCY):
+                    request = test_messages.request()
+                    response_future = self._invoker.future(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+                    requests.append(request)
+                    response_futures.append(response_future)
+
+                responses = [
+                    response_future.result()
+                    for response_future in response_futures
+                ]
+
+                for request, response in zip(requests, responses):
+                    test_messages.verify(request, response, self)
+
+    def testWaitingForSomeButNotAllParallelInvocations(self):
+        pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = []
+                response_futures_to_indices = {}
+                for index in range(test_constants.THREAD_CONCURRENCY):
+                    request = test_messages.request()
+                    inner_response_future = self._invoker.future(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+                    outer_response_future = pool.submit(
+                        inner_response_future.result)
+                    requests.append(request)
+                    response_futures_to_indices[outer_response_future] = index
+
+                some_completed_response_futures_iterator = itertools.islice(
+                    futures.as_completed(response_futures_to_indices),
+                    test_constants.THREAD_CONCURRENCY // 2)
+                for response_future in some_completed_response_futures_iterator:
+                    index = response_futures_to_indices[response_future]
+                    test_messages.verify(requests[index],
+                                         response_future.result(), self)
+        pool.shutdown(wait=True)
+
+    def testCancelledUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+                callback = _Callback()
+
+                with self._control.pause():
+                    response_future = self._invoker.future(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    cancel_method_return_value = response_future.cancel()
+
+                self.assertIs(callback.future(), response_future)
+                self.assertFalse(cancel_method_return_value)
+                self.assertTrue(response_future.cancelled())
+                with self.assertRaises(future.CancelledError):
+                    response_future.result()
+                with self.assertRaises(future.CancelledError):
+                    response_future.exception()
+                with self.assertRaises(future.CancelledError):
+                    response_future.traceback()
+
+    def testCancelledUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.pause():
+                    response_iterator = self._invoker.future(group, method)(
+                        request, test_constants.LONG_TIMEOUT)
+                    response_iterator.cancel()
+
+                with self.assertRaises(face.CancellationError):
+                    next(response_iterator)
+
+    def testCancelledStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+                callback = _Callback()
+
+                with self._control.pause():
+                    response_future = self._invoker.future(group, method)(
+                        iter(requests), test_constants.LONG_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    cancel_method_return_value = response_future.cancel()
+
+                self.assertIs(callback.future(), response_future)
+                self.assertFalse(cancel_method_return_value)
+                self.assertTrue(response_future.cancelled())
+                with self.assertRaises(future.CancelledError):
+                    response_future.result()
+                with self.assertRaises(future.CancelledError):
+                    response_future.exception()
+                with self.assertRaises(future.CancelledError):
+                    response_future.traceback()
+
+    def testCancelledStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.pause():
+                    response_iterator = self._invoker.future(group, method)(
+                        iter(requests), test_constants.LONG_TIMEOUT)
+                    response_iterator.cancel()
+
+                with self.assertRaises(face.CancellationError):
+                    next(response_iterator)
+
+    def testExpiredUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+                callback = _Callback()
+
+                with self._control.pause():
+                    response_future = self._invoker.future(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    self.assertIs(callback.future(), response_future)
+                    self.assertIsInstance(response_future.exception(),
+                                          face.ExpirationError)
+                    with self.assertRaises(face.ExpirationError):
+                        response_future.result()
+                    self.assertIsInstance(response_future.exception(),
+                                          face.AbortionError)
+                    self.assertIsNotNone(response_future.traceback())
+
+    def testExpiredUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                with self._control.pause():
+                    response_iterator = self._invoker.future(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    with self.assertRaises(face.ExpirationError):
+                        list(response_iterator)
+
+    def testExpiredStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+                callback = _Callback()
+
+                with self._control.pause():
+                    response_future = self._invoker.future(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    self.assertIs(callback.future(), response_future)
+                    self.assertIsInstance(response_future.exception(),
+                                          face.ExpirationError)
+                    with self.assertRaises(face.ExpirationError):
+                        response_future.result()
+                    self.assertIsInstance(response_future.exception(),
+                                          face.AbortionError)
+                    self.assertIsNotNone(response_future.traceback())
+
+    def testExpiredStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                with self._control.pause():
+                    response_iterator = self._invoker.future(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    with self.assertRaises(face.ExpirationError):
+                        list(response_iterator)
+
+    def testFailedUnaryRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+                callback = _Callback()
+                abortion_callback = _Callback()
+
+                with self._control.fail():
+                    response_future = self._invoker.future(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    response_future.add_abortion_callback(abortion_callback)
+
+                    self.assertIs(callback.future(), response_future)
+                    # Because the servicer fails outside of the thread from which the
+                    # servicer-side runtime called into it its failure is
+                    # indistinguishable from simply not having called its
+                    # response_callback before the expiration of the RPC.
+                    self.assertIsInstance(response_future.exception(),
+                                          face.ExpirationError)
+                    with self.assertRaises(face.ExpirationError):
+                        response_future.result()
+                    self.assertIsNotNone(response_future.traceback())
+                    self.assertIsNotNone(abortion_callback.future())
+
+    def testFailedUnaryRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.unary_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                request = test_messages.request()
+
+                # Because the servicer fails outside of the thread from which the
+                # servicer-side runtime called into it its failure is indistinguishable
+                # from simply not having called its response_consumer before the
+                # expiration of the RPC.
+                with self._control.fail(), self.assertRaises(
+                        face.ExpirationError):
+                    response_iterator = self._invoker.future(group, method)(
+                        request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    list(response_iterator)
+
+    def testFailedStreamRequestUnaryResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_unary_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+                callback = _Callback()
+                abortion_callback = _Callback()
+
+                with self._control.fail():
+                    response_future = self._invoker.future(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    response_future.add_done_callback(callback)
+                    response_future.add_abortion_callback(abortion_callback)
+
+                    self.assertIs(callback.future(), response_future)
+                    # Because the servicer fails outside of the thread from which the
+                    # servicer-side runtime called into it its failure is
+                    # indistinguishable from simply not having called its
+                    # response_callback before the expiration of the RPC.
+                    self.assertIsInstance(response_future.exception(),
+                                          face.ExpirationError)
+                    with self.assertRaises(face.ExpirationError):
+                        response_future.result()
+                    self.assertIsNotNone(response_future.traceback())
+                    self.assertIsNotNone(abortion_callback.future())
+
+    def testFailedStreamRequestStreamResponse(self):
+        for (group, method), test_messages_sequence in (
+                six.iteritems(self._digest.stream_stream_messages_sequences)):
+            for test_messages in test_messages_sequence:
+                requests = test_messages.requests()
+
+                # Because the servicer fails outside of the thread from which the
+                # servicer-side runtime called into it its failure is indistinguishable
+                # from simply not having called its response_consumer before the
+                # expiration of the RPC.
+                with self._control.fail(), self.assertRaises(
+                        face.ExpirationError):
+                    response_iterator = self._invoker.future(group, method)(
+                        iter(requests),
+                        _3069_test_constant.REALLY_SHORT_TIMEOUT)
+                    list(response_iterator)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_invocation.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_invocation.py
index ac487bed4f..4e144a3635 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_invocation.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_invocation.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Coverage across the Face layer's generic-to-dynamic range for invocation."""
 
 import abc
@@ -65,149 +64,149 @@ _CARDINALITY_TO_MULTI_CALLABLE_ATTRIBUTE = {
 
 
 class Invoker(six.with_metaclass(abc.ABCMeta)):
-  """A type used to invoke test RPCs."""
+    """A type used to invoke test RPCs."""
 
-  @abc.abstractmethod
-  def blocking(self, group, name):
-    """Invokes an RPC with blocking control flow."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def blocking(self, group, name):
+        """Invokes an RPC with blocking control flow."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def future(self, group, name):
-    """Invokes an RPC with future control flow."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def future(self, group, name):
+        """Invokes an RPC with future control flow."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def event(self, group, name):
-    """Invokes an RPC with event control flow."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def event(self, group, name):
+        """Invokes an RPC with event control flow."""
+        raise NotImplementedError()
 
 
 class InvokerConstructor(six.with_metaclass(abc.ABCMeta)):
-  """A type used to create Invokers."""
+    """A type used to create Invokers."""
 
-  @abc.abstractmethod
-  def name(self):
-    """Specifies the name of the Invoker constructed by this object."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def name(self):
+        """Specifies the name of the Invoker constructed by this object."""
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def construct_invoker(self, generic_stub, dynamic_stubs, methods):
-    """Constructs an Invoker for the given stubs and methods."""
-    raise NotImplementedError()
+    @abc.abstractmethod
+    def construct_invoker(self, generic_stub, dynamic_stubs, methods):
+        """Constructs an Invoker for the given stubs and methods."""
+        raise NotImplementedError()
 
 
 class _GenericInvoker(Invoker):
 
-  def __init__(self, generic_stub, methods):
-    self._stub = generic_stub
-    self._methods = methods
+    def __init__(self, generic_stub, methods):
+        self._stub = generic_stub
+        self._methods = methods
 
-  def _behavior(self, group, name, cardinality_to_generic_method):
-    method_cardinality = self._methods[group, name].cardinality()
-    behavior = getattr(
-        self._stub, cardinality_to_generic_method[method_cardinality])
-    return lambda *args, **kwargs: behavior(group, name, *args, **kwargs)
+    def _behavior(self, group, name, cardinality_to_generic_method):
+        method_cardinality = self._methods[group, name].cardinality()
+        behavior = getattr(self._stub,
+                           cardinality_to_generic_method[method_cardinality])
+        return lambda *args, **kwargs: behavior(group, name, *args, **kwargs)
 
-  def blocking(self, group, name):
-    return self._behavior(
-        group, name, _CARDINALITY_TO_GENERIC_BLOCKING_BEHAVIOR)
+    def blocking(self, group, name):
+        return self._behavior(group, name,
+                              _CARDINALITY_TO_GENERIC_BLOCKING_BEHAVIOR)
 
-  def future(self, group, name):
-    return self._behavior(group, name, _CARDINALITY_TO_GENERIC_FUTURE_BEHAVIOR)
+    def future(self, group, name):
+        return self._behavior(group, name,
+                              _CARDINALITY_TO_GENERIC_FUTURE_BEHAVIOR)
 
-  def event(self, group, name):
-    return self._behavior(group, name, _CARDINALITY_TO_GENERIC_EVENT_BEHAVIOR)
+    def event(self, group, name):
+        return self._behavior(group, name,
+                              _CARDINALITY_TO_GENERIC_EVENT_BEHAVIOR)
 
 
 class _GenericInvokerConstructor(InvokerConstructor):
 
-  def name(self):
-    return 'GenericInvoker'
+    def name(self):
+        return 'GenericInvoker'
 
-  def construct_invoker(self, generic_stub, dynamic_stub, methods):
-    return _GenericInvoker(generic_stub, methods)
+    def construct_invoker(self, generic_stub, dynamic_stub, methods):
+        return _GenericInvoker(generic_stub, methods)
 
 
 class _MultiCallableInvoker(Invoker):
 
-  def __init__(self, generic_stub, methods):
-    self._stub = generic_stub
-    self._methods = methods
+    def __init__(self, generic_stub, methods):
+        self._stub = generic_stub
+        self._methods = methods
 
-  def _multi_callable(self, group, name):
-    method_cardinality = self._methods[group, name].cardinality()
-    behavior = getattr(
-        self._stub,
-        _CARDINALITY_TO_MULTI_CALLABLE_ATTRIBUTE[method_cardinality])
-    return behavior(group, name)
+    def _multi_callable(self, group, name):
+        method_cardinality = self._methods[group, name].cardinality()
+        behavior = getattr(
+            self._stub,
+            _CARDINALITY_TO_MULTI_CALLABLE_ATTRIBUTE[method_cardinality])
+        return behavior(group, name)
 
-  def blocking(self, group, name):
-    return self._multi_callable(group, name)
+    def blocking(self, group, name):
+        return self._multi_callable(group, name)
 
-  def future(self, group, name):
-    method_cardinality = self._methods[group, name].cardinality()
-    behavior = getattr(
-        self._stub,
-        _CARDINALITY_TO_MULTI_CALLABLE_ATTRIBUTE[method_cardinality])
-    if method_cardinality in (
-        cardinality.Cardinality.UNARY_UNARY,
-        cardinality.Cardinality.STREAM_UNARY):
-      return behavior(group, name).future
-    else:
-      return behavior(group, name)
+    def future(self, group, name):
+        method_cardinality = self._methods[group, name].cardinality()
+        behavior = getattr(
+            self._stub,
+            _CARDINALITY_TO_MULTI_CALLABLE_ATTRIBUTE[method_cardinality])
+        if method_cardinality in (cardinality.Cardinality.UNARY_UNARY,
+                                  cardinality.Cardinality.STREAM_UNARY):
+            return behavior(group, name).future
+        else:
+            return behavior(group, name)
 
-  def event(self, group, name):
-    return self._multi_callable(group, name).event
+    def event(self, group, name):
+        return self._multi_callable(group, name).event
 
 
 class _MultiCallableInvokerConstructor(InvokerConstructor):
 
-  def name(self):
-    return 'MultiCallableInvoker'
+    def name(self):
+        return 'MultiCallableInvoker'
 
-  def construct_invoker(self, generic_stub, dynamic_stub, methods):
-    return _MultiCallableInvoker(generic_stub, methods)
+    def construct_invoker(self, generic_stub, dynamic_stub, methods):
+        return _MultiCallableInvoker(generic_stub, methods)
 
 
 class _DynamicInvoker(Invoker):
 
-  def __init__(self, dynamic_stubs, methods):
-    self._stubs = dynamic_stubs
-    self._methods = methods
+    def __init__(self, dynamic_stubs, methods):
+        self._stubs = dynamic_stubs
+        self._methods = methods
 
-  def blocking(self, group, name):
-    return getattr(self._stubs[group], name)
+    def blocking(self, group, name):
+        return getattr(self._stubs[group], name)
 
-  def future(self, group, name):
-    if self._methods[group, name].cardinality() in (
-        cardinality.Cardinality.UNARY_UNARY,
-        cardinality.Cardinality.STREAM_UNARY):
-      return getattr(self._stubs[group], name).future
-    else:
-      return getattr(self._stubs[group], name)
+    def future(self, group, name):
+        if self._methods[group, name].cardinality() in (
+                cardinality.Cardinality.UNARY_UNARY,
+                cardinality.Cardinality.STREAM_UNARY):
+            return getattr(self._stubs[group], name).future
+        else:
+            return getattr(self._stubs[group], name)
 
-  def event(self, group, name):
-    return getattr(self._stubs[group], name).event
+    def event(self, group, name):
+        return getattr(self._stubs[group], name).event
 
 
 class _DynamicInvokerConstructor(InvokerConstructor):
 
-  def name(self):
-    return 'DynamicInvoker'
+    def name(self):
+        return 'DynamicInvoker'
 
-  def construct_invoker(self, generic_stub, dynamic_stubs, methods):
-    return _DynamicInvoker(dynamic_stubs, methods)
+    def construct_invoker(self, generic_stub, dynamic_stubs, methods):
+        return _DynamicInvoker(dynamic_stubs, methods)
 
 
 def invoker_constructors():
-  """Creates a sequence of InvokerConstructors to use in tests of RPCs.
+    """Creates a sequence of InvokerConstructors to use in tests of RPCs.
 
   Returns:
     A sequence of InvokerConstructors.
   """
-  return (
-      _GenericInvokerConstructor(),
-      _MultiCallableInvokerConstructor(),
-      _DynamicInvokerConstructor(),
-  )
+    return (
+        _GenericInvokerConstructor(),
+        _MultiCallableInvokerConstructor(),
+        _DynamicInvokerConstructor(),)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_service.py
index f13dff0558..f14ac6a987 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_service.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_service.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Private interfaces implemented by data sets used in Face-layer tests."""
 
 import abc
@@ -38,12 +37,13 @@ from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 from tests.unit.framework.interfaces.face import test_interfaces
 
 
-class UnaryUnaryTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
-  """A controllable implementation of a unary-unary method."""
+class UnaryUnaryTestMethodImplementation(
+        six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
+    """A controllable implementation of a unary-unary method."""
 
-  @abc.abstractmethod
-  def service(self, request, response_callback, context, control):
-    """Services an RPC that accepts one message and produces one message.
+    @abc.abstractmethod
+    def service(self, request, response_callback, context, control):
+        """Services an RPC that accepts one message and produces one message.
 
     Args:
       request: The single request message for the RPC.
@@ -56,15 +56,15 @@ class UnaryUnaryTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_in
       abandonment.Abandoned: May or may not be raised when the RPC has been
         aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class UnaryUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
-  """A type for unary-request-unary-response message pairings."""
+    """A type for unary-request-unary-response message pairings."""
 
-  @abc.abstractmethod
-  def request(self):
-    """Affords a request message.
+    @abc.abstractmethod
+    def request(self):
+        """Affords a request message.
 
     Implementations of this method should return a different message with each
     call so that multiple test executions of the test method may be made with
@@ -73,11 +73,11 @@ class UnaryUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A request message.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def verify(self, request, response, test_case):
-    """Verifies that the computed response matches the given request.
+    @abc.abstractmethod
+    def verify(self, request, response, test_case):
+        """Verifies that the computed response matches the given request.
 
     Args:
       request: A request message.
@@ -88,15 +88,16 @@ class UnaryUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
       AssertionError: If the request and response do not match, indicating that
         there was some problem executing the RPC under test.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
-class UnaryStreamTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
-  """A controllable implementation of a unary-stream method."""
+class UnaryStreamTestMethodImplementation(
+        six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
+    """A controllable implementation of a unary-stream method."""
 
-  @abc.abstractmethod
-  def service(self, request, response_consumer, context, control):
-    """Services an RPC that takes one message and produces a stream of messages.
+    @abc.abstractmethod
+    def service(self, request, response_consumer, context, control):
+        """Services an RPC that takes one message and produces a stream of messages.
 
     Args:
       request: The single request message for the RPC.
@@ -109,15 +110,15 @@ class UnaryStreamTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_i
       abandonment.Abandoned: May or may not be raised when the RPC has been
         aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class UnaryStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
-  """A type for unary-request-stream-response message pairings."""
+    """A type for unary-request-stream-response message pairings."""
 
-  @abc.abstractmethod
-  def request(self):
-    """Affords a request message.
+    @abc.abstractmethod
+    def request(self):
+        """Affords a request message.
 
     Implementations of this method should return a different message with each
     call so that multiple test executions of the test method may be made with
@@ -126,11 +127,11 @@ class UnaryStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A request message.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def verify(self, request, responses, test_case):
-    """Verifies that the computed responses match the given request.
+    @abc.abstractmethod
+    def verify(self, request, responses, test_case):
+        """Verifies that the computed responses match the given request.
 
     Args:
       request: A request message.
@@ -141,15 +142,16 @@ class UnaryStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
       AssertionError: If the request and responses do not match, indicating that
         there was some problem executing the RPC under test.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
-class StreamUnaryTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
-  """A controllable implementation of a stream-unary method."""
+class StreamUnaryTestMethodImplementation(
+        six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
+    """A controllable implementation of a stream-unary method."""
 
-  @abc.abstractmethod
-  def service(self, response_callback, context, control):
-    """Services an RPC that takes a stream of messages and produces one message.
+    @abc.abstractmethod
+    def service(self, response_callback, context, control):
+        """Services an RPC that takes a stream of messages and produces one message.
 
     Args:
       response_callback: A callback to be called to accept the response message
@@ -169,15 +171,15 @@ class StreamUnaryTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_i
       abandonment.Abandoned: May or may not be raised when the RPC has been
         aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
-  """A type for stream-request-unary-response message pairings."""
+    """A type for stream-request-unary-response message pairings."""
 
-  @abc.abstractmethod
-  def requests(self):
-    """Affords a sequence of request messages.
+    @abc.abstractmethod
+    def requests(self):
+        """Affords a sequence of request messages.
 
     Implementations of this method should return a different sequences with each
     call so that multiple test executions of the test method may be made with
@@ -186,11 +188,11 @@ class StreamUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A sequence of request messages.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def verify(self, requests, response, test_case):
-    """Verifies that the computed response matches the given requests.
+    @abc.abstractmethod
+    def verify(self, requests, response, test_case):
+        """Verifies that the computed response matches the given requests.
 
     Args:
       requests: A sequence of request messages.
@@ -201,15 +203,16 @@ class StreamUnaryTestMessages(six.with_metaclass(abc.ABCMeta)):
       AssertionError: If the requests and response do not match, indicating that
         there was some problem executing the RPC under test.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
-class StreamStreamTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
-  """A controllable implementation of a stream-stream method."""
+class StreamStreamTestMethodImplementation(
+        six.with_metaclass(abc.ABCMeta, test_interfaces.Method)):
+    """A controllable implementation of a stream-stream method."""
 
-  @abc.abstractmethod
-  def service(self, response_consumer, context, control):
-    """Services an RPC that accepts and produces streams of messages.
+    @abc.abstractmethod
+    def service(self, response_consumer, context, control):
+        """Services an RPC that accepts and produces streams of messages.
 
     Args:
       response_consumer: A stream.Consumer to be called to accept the response
@@ -229,15 +232,15 @@ class StreamStreamTestMethodImplementation(six.with_metaclass(abc.ABCMeta, test_
       abandonment.Abandoned: May or may not be raised when the RPC has been
         aborted.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class StreamStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
-  """A type for stream-request-stream-response message pairings."""
+    """A type for stream-request-stream-response message pairings."""
 
-  @abc.abstractmethod
-  def requests(self):
-    """Affords a sequence of request messages.
+    @abc.abstractmethod
+    def requests(self):
+        """Affords a sequence of request messages.
 
     Implementations of this method should return a different sequences with each
     call so that multiple test executions of the test method may be made with
@@ -246,11 +249,11 @@ class StreamStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
     Returns:
       A sequence of request messages.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def verify(self, requests, responses, test_case):
-    """Verifies that the computed response matches the given requests.
+    @abc.abstractmethod
+    def verify(self, requests, responses, test_case):
+        """Verifies that the computed response matches the given requests.
 
     Args:
       requests: A sequence of request messages.
@@ -261,15 +264,15 @@ class StreamStreamTestMessages(six.with_metaclass(abc.ABCMeta)):
       AssertionError: If the requests and responses do not match, indicating
         that there was some problem executing the RPC under test.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class TestService(six.with_metaclass(abc.ABCMeta)):
-  """A specification of implemented methods to use in tests."""
+    """A specification of implemented methods to use in tests."""
 
-  @abc.abstractmethod
-  def unary_unary_scenarios(self):
-    """Affords unary-request-unary-response test methods and their messages.
+    @abc.abstractmethod
+    def unary_unary_scenarios(self):
+        """Affords unary-request-unary-response test methods and their messages.
 
     Returns:
       A dict from method group-name pair to implementation/messages pair. The
@@ -277,11 +280,11 @@ class TestService(six.with_metaclass(abc.ABCMeta)):
         and the second element is a sequence of UnaryUnaryTestMethodMessages
         objects.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def unary_stream_scenarios(self):
-    """Affords unary-request-stream-response test methods and their messages.
+    @abc.abstractmethod
+    def unary_stream_scenarios(self):
+        """Affords unary-request-stream-response test methods and their messages.
 
     Returns:
       A dict from method group-name pair to implementation/messages pair. The
@@ -289,11 +292,11 @@ class TestService(six.with_metaclass(abc.ABCMeta)):
         object and the second element is a sequence of
         UnaryStreamTestMethodMessages objects.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_unary_scenarios(self):
-    """Affords stream-request-unary-response test methods and their messages.
+    @abc.abstractmethod
+    def stream_unary_scenarios(self):
+        """Affords stream-request-unary-response test methods and their messages.
 
     Returns:
       A dict from method group-name pair to implementation/messages pair. The
@@ -301,11 +304,11 @@ class TestService(six.with_metaclass(abc.ABCMeta)):
         object and the second element is a sequence of
         StreamUnaryTestMethodMessages objects.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def stream_stream_scenarios(self):
-    """Affords stream-request-stream-response test methods and their messages.
+    @abc.abstractmethod
+    def stream_stream_scenarios(self):
+        """Affords stream-request-stream-response test methods and their messages.
 
     Returns:
       A dict from method group-name pair to implementation/messages pair. The
@@ -313,4 +316,4 @@ class TestService(six.with_metaclass(abc.ABCMeta)):
         object and the second element is a sequence of
         StreamStreamTestMethodMessages objects.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_stock_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_stock_service.py
index 5299655bb3..41a55c13f4 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_stock_service.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_stock_service.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Examples of Python implementations of the stock.proto Stock service."""
 
 from grpc.framework.common import cardinality
@@ -44,353 +43,363 @@ _price = lambda symbol_name: float(hash(symbol_name) % 4096)
 
 
 def _get_last_trade_price(stock_request, stock_reply_callback, control, active):
-  """A unary-request, unary-response test method."""
-  control.control()
-  if active():
-    stock_reply_callback(
-        stock_pb2.StockReply(
-            symbol=stock_request.symbol, price=_price(stock_request.symbol)))
-  else:
-    raise abandonment.Abandoned()
-
-
-def _get_last_trade_price_multiple(stock_reply_consumer, control, active):
-  """A stream-request, stream-response test method."""
-  def stock_reply_for_stock_request(stock_request):
+    """A unary-request, unary-response test method."""
     control.control()
     if active():
-      return stock_pb2.StockReply(
-          symbol=stock_request.symbol, price=_price(stock_request.symbol))
+        stock_reply_callback(
+            stock_pb2.StockReply(
+                symbol=stock_request.symbol, price=_price(
+                    stock_request.symbol)))
     else:
-      raise abandonment.Abandoned()
-
-  class StockRequestConsumer(stream.Consumer):
+        raise abandonment.Abandoned()
 
-    def consume(self, stock_request):
-      stock_reply_consumer.consume(stock_reply_for_stock_request(stock_request))
 
-    def terminate(self):
-      control.control()
-      stock_reply_consumer.terminate()
+def _get_last_trade_price_multiple(stock_reply_consumer, control, active):
+    """A stream-request, stream-response test method."""
 
-    def consume_and_terminate(self, stock_request):
-      stock_reply_consumer.consume_and_terminate(
-          stock_reply_for_stock_request(stock_request))
+    def stock_reply_for_stock_request(stock_request):
+        control.control()
+        if active():
+            return stock_pb2.StockReply(
+                symbol=stock_request.symbol, price=_price(stock_request.symbol))
+        else:
+            raise abandonment.Abandoned()
 
-  return StockRequestConsumer()
+    class StockRequestConsumer(stream.Consumer):
 
+        def consume(self, stock_request):
+            stock_reply_consumer.consume(
+                stock_reply_for_stock_request(stock_request))
 
-def _watch_future_trades(stock_request, stock_reply_consumer, control, active):
-  """A unary-request, stream-response test method."""
-  base_price = _price(stock_request.symbol)
-  for index in range(stock_request.num_trades_to_watch):
-    control.control()
-    if active():
-      stock_reply_consumer.consume(
-          stock_pb2.StockReply(
-              symbol=stock_request.symbol, price=base_price + index))
-    else:
-      raise abandonment.Abandoned()
-  stock_reply_consumer.terminate()
+        def terminate(self):
+            control.control()
+            stock_reply_consumer.terminate()
 
+        def consume_and_terminate(self, stock_request):
+            stock_reply_consumer.consume_and_terminate(
+                stock_reply_for_stock_request(stock_request))
 
-def _get_highest_trade_price(stock_reply_callback, control, active):
-  """A stream-request, unary-response test method."""
+    return StockRequestConsumer()
 
-  class StockRequestConsumer(stream.Consumer):
-    """Keeps an ongoing record of the most valuable symbol yet consumed."""
 
-    def __init__(self):
-      self._symbol = None
-      self._price = None
-
-    def consume(self, stock_request):
-      control.control()
-      if active():
-        if self._price is None:
-          self._symbol = stock_request.symbol
-          self._price = _price(stock_request.symbol)
-        else:
-          candidate_price = _price(stock_request.symbol)
-          if self._price < candidate_price:
-            self._symbol = stock_request.symbol
-            self._price = candidate_price
-
-    def terminate(self):
-      control.control()
-      if active():
-        if self._symbol is None:
-          raise ValueError()
-        else:
-          stock_reply_callback(
-              stock_pb2.StockReply(symbol=self._symbol, price=self._price))
-          self._symbol = None
-          self._price = None
-
-    def consume_and_terminate(self, stock_request):
-      control.control()
-      if active():
-        if self._price is None:
-          stock_reply_callback(
-              stock_pb2.StockReply(
-                  symbol=stock_request.symbol,
-                  price=_price(stock_request.symbol)))
-        else:
-          candidate_price = _price(stock_request.symbol)
-          if self._price < candidate_price:
-            stock_reply_callback(
-                stock_pb2.StockReply(
-                    symbol=stock_request.symbol, price=candidate_price))
-          else:
-            stock_reply_callback(
+def _watch_future_trades(stock_request, stock_reply_consumer, control, active):
+    """A unary-request, stream-response test method."""
+    base_price = _price(stock_request.symbol)
+    for index in range(stock_request.num_trades_to_watch):
+        control.control()
+        if active():
+            stock_reply_consumer.consume(
                 stock_pb2.StockReply(
-                    symbol=self._symbol, price=self._price))
+                    symbol=stock_request.symbol, price=base_price + index))
+        else:
+            raise abandonment.Abandoned()
+    stock_reply_consumer.terminate()
 
-        self._symbol = None
-        self._price = None
 
-  return StockRequestConsumer()
+def _get_highest_trade_price(stock_reply_callback, control, active):
+    """A stream-request, unary-response test method."""
+
+    class StockRequestConsumer(stream.Consumer):
+        """Keeps an ongoing record of the most valuable symbol yet consumed."""
+
+        def __init__(self):
+            self._symbol = None
+            self._price = None
+
+        def consume(self, stock_request):
+            control.control()
+            if active():
+                if self._price is None:
+                    self._symbol = stock_request.symbol
+                    self._price = _price(stock_request.symbol)
+                else:
+                    candidate_price = _price(stock_request.symbol)
+                    if self._price < candidate_price:
+                        self._symbol = stock_request.symbol
+                        self._price = candidate_price
+
+        def terminate(self):
+            control.control()
+            if active():
+                if self._symbol is None:
+                    raise ValueError()
+                else:
+                    stock_reply_callback(
+                        stock_pb2.StockReply(
+                            symbol=self._symbol, price=self._price))
+                    self._symbol = None
+                    self._price = None
+
+        def consume_and_terminate(self, stock_request):
+            control.control()
+            if active():
+                if self._price is None:
+                    stock_reply_callback(
+                        stock_pb2.StockReply(
+                            symbol=stock_request.symbol,
+                            price=_price(stock_request.symbol)))
+                else:
+                    candidate_price = _price(stock_request.symbol)
+                    if self._price < candidate_price:
+                        stock_reply_callback(
+                            stock_pb2.StockReply(
+                                symbol=stock_request.symbol,
+                                price=candidate_price))
+                    else:
+                        stock_reply_callback(
+                            stock_pb2.StockReply(
+                                symbol=self._symbol, price=self._price))
+
+                self._symbol = None
+                self._price = None
+
+    return StockRequestConsumer()
 
 
 class GetLastTradePrice(_service.UnaryUnaryTestMethodImplementation):
-  """GetLastTradePrice for use in tests."""
+    """GetLastTradePrice for use in tests."""
 
-  def group(self):
-    return _STOCK_GROUP_NAME
+    def group(self):
+        return _STOCK_GROUP_NAME
 
-  def name(self):
-    return 'GetLastTradePrice'
+    def name(self):
+        return 'GetLastTradePrice'
 
-  def cardinality(self):
-    return cardinality.Cardinality.UNARY_UNARY
+    def cardinality(self):
+        return cardinality.Cardinality.UNARY_UNARY
 
-  def request_class(self):
-    return stock_pb2.StockRequest
+    def request_class(self):
+        return stock_pb2.StockRequest
 
-  def response_class(self):
-    return stock_pb2.StockReply
+    def response_class(self):
+        return stock_pb2.StockReply
 
-  def serialize_request(self, request):
-    return request.SerializeToString()
+    def serialize_request(self, request):
+        return request.SerializeToString()
 
-  def deserialize_request(self, serialized_request):
-    return stock_pb2.StockRequest.FromString(serialized_request)
+    def deserialize_request(self, serialized_request):
+        return stock_pb2.StockRequest.FromString(serialized_request)
 
-  def serialize_response(self, response):
-    return response.SerializeToString()
+    def serialize_response(self, response):
+        return response.SerializeToString()
 
-  def deserialize_response(self, serialized_response):
-    return stock_pb2.StockReply.FromString(serialized_response)
+    def deserialize_response(self, serialized_response):
+        return stock_pb2.StockReply.FromString(serialized_response)
 
-  def service(self, request, response_callback, context, control):
-    _get_last_trade_price(
-        request, response_callback, control, context.is_active)
+    def service(self, request, response_callback, context, control):
+        _get_last_trade_price(request, response_callback, control,
+                              context.is_active)
 
 
 class GetLastTradePriceMessages(_service.UnaryUnaryTestMessages):
 
-  def __init__(self):
-    self._index = 0
+    def __init__(self):
+        self._index = 0
 
-  def request(self):
-    symbol = _SYMBOL_FORMAT % self._index
-    self._index += 1
-    return stock_pb2.StockRequest(symbol=symbol)
+    def request(self):
+        symbol = _SYMBOL_FORMAT % self._index
+        self._index += 1
+        return stock_pb2.StockRequest(symbol=symbol)
 
-  def verify(self, request, response, test_case):
-    test_case.assertEqual(request.symbol, response.symbol)
-    test_case.assertEqual(_price(request.symbol), response.price)
+    def verify(self, request, response, test_case):
+        test_case.assertEqual(request.symbol, response.symbol)
+        test_case.assertEqual(_price(request.symbol), response.price)
 
 
 class GetLastTradePriceMultiple(_service.StreamStreamTestMethodImplementation):
-  """GetLastTradePriceMultiple for use in tests."""
+    """GetLastTradePriceMultiple for use in tests."""
 
-  def group(self):
-    return _STOCK_GROUP_NAME
+    def group(self):
+        return _STOCK_GROUP_NAME
 
-  def name(self):
-    return 'GetLastTradePriceMultiple'
+    def name(self):
+        return 'GetLastTradePriceMultiple'
 
-  def cardinality(self):
-    return cardinality.Cardinality.STREAM_STREAM
+    def cardinality(self):
+        return cardinality.Cardinality.STREAM_STREAM
 
-  def request_class(self):
-    return stock_pb2.StockRequest
+    def request_class(self):
+        return stock_pb2.StockRequest
 
-  def response_class(self):
-    return stock_pb2.StockReply
+    def response_class(self):
+        return stock_pb2.StockReply
 
-  def serialize_request(self, request):
-    return request.SerializeToString()
+    def serialize_request(self, request):
+        return request.SerializeToString()
 
-  def deserialize_request(self, serialized_request):
-    return stock_pb2.StockRequest.FromString(serialized_request)
+    def deserialize_request(self, serialized_request):
+        return stock_pb2.StockRequest.FromString(serialized_request)
 
-  def serialize_response(self, response):
-    return response.SerializeToString()
+    def serialize_response(self, response):
+        return response.SerializeToString()
 
-  def deserialize_response(self, serialized_response):
-    return stock_pb2.StockReply.FromString(serialized_response)
+    def deserialize_response(self, serialized_response):
+        return stock_pb2.StockReply.FromString(serialized_response)
 
-  def service(self, response_consumer, context, control):
-    return _get_last_trade_price_multiple(
-        response_consumer, control, context.is_active)
+    def service(self, response_consumer, context, control):
+        return _get_last_trade_price_multiple(response_consumer, control,
+                                              context.is_active)
 
 
 class GetLastTradePriceMultipleMessages(_service.StreamStreamTestMessages):
-  """Pairs of message streams for use with GetLastTradePriceMultiple."""
+    """Pairs of message streams for use with GetLastTradePriceMultiple."""
 
-  def __init__(self):
-    self._index = 0
+    def __init__(self):
+        self._index = 0
 
-  def requests(self):
-    base_index = self._index
-    self._index += 1
-    return [
-        stock_pb2.StockRequest(symbol=_SYMBOL_FORMAT % (base_index + index))
-        for index in range(test_constants.STREAM_LENGTH)]
+    def requests(self):
+        base_index = self._index
+        self._index += 1
+        return [
+            stock_pb2.StockRequest(symbol=_SYMBOL_FORMAT % (base_index + index))
+            for index in range(test_constants.STREAM_LENGTH)
+        ]
 
-  def verify(self, requests, responses, test_case):
-    test_case.assertEqual(len(requests), len(responses))
-    for stock_request, stock_reply in zip(requests, responses):
-      test_case.assertEqual(stock_request.symbol, stock_reply.symbol)
-      test_case.assertEqual(_price(stock_request.symbol), stock_reply.price)
+    def verify(self, requests, responses, test_case):
+        test_case.assertEqual(len(requests), len(responses))
+        for stock_request, stock_reply in zip(requests, responses):
+            test_case.assertEqual(stock_request.symbol, stock_reply.symbol)
+            test_case.assertEqual(
+                _price(stock_request.symbol), stock_reply.price)
 
 
 class WatchFutureTrades(_service.UnaryStreamTestMethodImplementation):
-  """WatchFutureTrades for use in tests."""
+    """WatchFutureTrades for use in tests."""
 
-  def group(self):
-    return _STOCK_GROUP_NAME
+    def group(self):
+        return _STOCK_GROUP_NAME
 
-  def name(self):
-    return 'WatchFutureTrades'
+    def name(self):
+        return 'WatchFutureTrades'
 
-  def cardinality(self):
-    return cardinality.Cardinality.UNARY_STREAM
+    def cardinality(self):
+        return cardinality.Cardinality.UNARY_STREAM
 
-  def request_class(self):
-    return stock_pb2.StockRequest
+    def request_class(self):
+        return stock_pb2.StockRequest
 
-  def response_class(self):
-    return stock_pb2.StockReply
+    def response_class(self):
+        return stock_pb2.StockReply
 
-  def serialize_request(self, request):
-    return request.SerializeToString()
+    def serialize_request(self, request):
+        return request.SerializeToString()
 
-  def deserialize_request(self, serialized_request):
-    return stock_pb2.StockRequest.FromString(serialized_request)
+    def deserialize_request(self, serialized_request):
+        return stock_pb2.StockRequest.FromString(serialized_request)
 
-  def serialize_response(self, response):
-    return response.SerializeToString()
+    def serialize_response(self, response):
+        return response.SerializeToString()
 
-  def deserialize_response(self, serialized_response):
-    return stock_pb2.StockReply.FromString(serialized_response)
+    def deserialize_response(self, serialized_response):
+        return stock_pb2.StockReply.FromString(serialized_response)
 
-  def service(self, request, response_consumer, context, control):
-    _watch_future_trades(request, response_consumer, control, context.is_active)
+    def service(self, request, response_consumer, context, control):
+        _watch_future_trades(request, response_consumer, control,
+                             context.is_active)
 
 
 class WatchFutureTradesMessages(_service.UnaryStreamTestMessages):
-  """Pairs of a single request message and a sequence of response messages."""
+    """Pairs of a single request message and a sequence of response messages."""
 
-  def __init__(self):
-    self._index = 0
+    def __init__(self):
+        self._index = 0
 
-  def request(self):
-    symbol = _SYMBOL_FORMAT % self._index
-    self._index += 1
-    return stock_pb2.StockRequest(
-        symbol=symbol, num_trades_to_watch=test_constants.STREAM_LENGTH)
+    def request(self):
+        symbol = _SYMBOL_FORMAT % self._index
+        self._index += 1
+        return stock_pb2.StockRequest(
+            symbol=symbol, num_trades_to_watch=test_constants.STREAM_LENGTH)
 
-  def verify(self, request, responses, test_case):
-    test_case.assertEqual(test_constants.STREAM_LENGTH, len(responses))
-    base_price = _price(request.symbol)
-    for index, response in enumerate(responses):
-      test_case.assertEqual(base_price + index, response.price)
+    def verify(self, request, responses, test_case):
+        test_case.assertEqual(test_constants.STREAM_LENGTH, len(responses))
+        base_price = _price(request.symbol)
+        for index, response in enumerate(responses):
+            test_case.assertEqual(base_price + index, response.price)
 
 
 class GetHighestTradePrice(_service.StreamUnaryTestMethodImplementation):
-  """GetHighestTradePrice for use in tests."""
+    """GetHighestTradePrice for use in tests."""
 
-  def group(self):
-    return _STOCK_GROUP_NAME
+    def group(self):
+        return _STOCK_GROUP_NAME
 
-  def name(self):
-    return 'GetHighestTradePrice'
+    def name(self):
+        return 'GetHighestTradePrice'
 
-  def cardinality(self):
-    return cardinality.Cardinality.STREAM_UNARY
+    def cardinality(self):
+        return cardinality.Cardinality.STREAM_UNARY
 
-  def request_class(self):
-    return stock_pb2.StockRequest
+    def request_class(self):
+        return stock_pb2.StockRequest
 
-  def response_class(self):
-    return stock_pb2.StockReply
+    def response_class(self):
+        return stock_pb2.StockReply
 
-  def serialize_request(self, request):
-    return request.SerializeToString()
+    def serialize_request(self, request):
+        return request.SerializeToString()
 
-  def deserialize_request(self, serialized_request):
-    return stock_pb2.StockRequest.FromString(serialized_request)
+    def deserialize_request(self, serialized_request):
+        return stock_pb2.StockRequest.FromString(serialized_request)
 
-  def serialize_response(self, response):
-    return response.SerializeToString()
+    def serialize_response(self, response):
+        return response.SerializeToString()
 
-  def deserialize_response(self, serialized_response):
-    return stock_pb2.StockReply.FromString(serialized_response)
+    def deserialize_response(self, serialized_response):
+        return stock_pb2.StockReply.FromString(serialized_response)
 
-  def service(self, response_callback, context, control):
-    return _get_highest_trade_price(
-        response_callback, control, context.is_active)
+    def service(self, response_callback, context, control):
+        return _get_highest_trade_price(response_callback, control,
+                                        context.is_active)
 
 
 class GetHighestTradePriceMessages(_service.StreamUnaryTestMessages):
 
-  def requests(self):
-    return [
-        stock_pb2.StockRequest(symbol=_SYMBOL_FORMAT % index)
-        for index in range(test_constants.STREAM_LENGTH)]
-
-  def verify(self, requests, response, test_case):
-    price = None
-    symbol = None
-    for stock_request in requests:
-      current_symbol = stock_request.symbol
-      current_price = _price(current_symbol)
-      if price is None or price < current_price:
-        price = current_price
-        symbol = current_symbol
-    test_case.assertEqual(price, response.price)
-    test_case.assertEqual(symbol, response.symbol)
+    def requests(self):
+        return [
+            stock_pb2.StockRequest(symbol=_SYMBOL_FORMAT % index)
+            for index in range(test_constants.STREAM_LENGTH)
+        ]
+
+    def verify(self, requests, response, test_case):
+        price = None
+        symbol = None
+        for stock_request in requests:
+            current_symbol = stock_request.symbol
+            current_price = _price(current_symbol)
+            if price is None or price < current_price:
+                price = current_price
+                symbol = current_symbol
+        test_case.assertEqual(price, response.price)
+        test_case.assertEqual(symbol, response.symbol)
 
 
 class StockTestService(_service.TestService):
-  """A corpus of test data with one method of each RPC cardinality."""
-
-  def unary_unary_scenarios(self):
-    return {
-        (_STOCK_GROUP_NAME, 'GetLastTradePrice'): (
-            GetLastTradePrice(), [GetLastTradePriceMessages()]),
-    }
-
-  def unary_stream_scenarios(self):
-    return {
-        (_STOCK_GROUP_NAME, 'WatchFutureTrades'): (
-            WatchFutureTrades(), [WatchFutureTradesMessages()]),
-    }
-
-  def stream_unary_scenarios(self):
-    return {
-        (_STOCK_GROUP_NAME, 'GetHighestTradePrice'): (
-            GetHighestTradePrice(), [GetHighestTradePriceMessages()])
-    }
-
-  def stream_stream_scenarios(self):
-    return {
-        (_STOCK_GROUP_NAME, 'GetLastTradePriceMultiple'): (
-            GetLastTradePriceMultiple(), [GetLastTradePriceMultipleMessages()]),
-    }
+    """A corpus of test data with one method of each RPC cardinality."""
+
+    def unary_unary_scenarios(self):
+        return {
+            (_STOCK_GROUP_NAME, 'GetLastTradePrice'):
+            (GetLastTradePrice(), [GetLastTradePriceMessages()]),
+        }
+
+    def unary_stream_scenarios(self):
+        return {
+            (_STOCK_GROUP_NAME, 'WatchFutureTrades'):
+            (WatchFutureTrades(), [WatchFutureTradesMessages()]),
+        }
+
+    def stream_unary_scenarios(self):
+        return {
+            (_STOCK_GROUP_NAME, 'GetHighestTradePrice'):
+            (GetHighestTradePrice(), [GetHighestTradePriceMessages()])
+        }
+
+    def stream_stream_scenarios(self):
+        return {
+            (_STOCK_GROUP_NAME, 'GetLastTradePriceMultiple'):
+            (GetLastTradePriceMultiple(),
+             [GetLastTradePriceMultipleMessages()]),
+        }
 
 
 STOCK_TEST_SERVICE = StockTestService()
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_cases.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_cases.py
index 71de9d835e..d84e1fc136 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_cases.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_cases.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Tools for creating tests of implementations of the Face layer."""
 
 # unittest is referenced from specification in this module.
@@ -40,12 +39,11 @@ from tests.unit.framework.interfaces.face import test_interfaces  # pylint: disa
 
 _TEST_CASE_SUPERCLASSES = (
     _blocking_invocation_inline_service.TestCase,
-    _future_invocation_asynchronous_event_service.TestCase,
-)
+    _future_invocation_asynchronous_event_service.TestCase,)
 
 
 def test_cases(implementation):
-  """Creates unittest.TestCase classes for a given Face layer implementation.
+    """Creates unittest.TestCase classes for a given Face layer implementation.
 
   Args:
     implementation: A test_interfaces.Implementation specifying creation and
@@ -55,13 +53,14 @@ def test_cases(implementation):
     A sequence of subclasses of unittest.TestCase defining tests of the
       specified Face layer implementation.
   """
-  test_case_classes = []
-  for invoker_constructor in _invocation.invoker_constructors():
-    for super_class in _TEST_CASE_SUPERCLASSES:
-      test_case_classes.append(
-          type(invoker_constructor.name() + super_class.NAME, (super_class,),
-               {'implementation': implementation,
-                'invoker_constructor': invoker_constructor,
-                '__module__': implementation.__module__,
-               }))
-  return test_case_classes
+    test_case_classes = []
+    for invoker_constructor in _invocation.invoker_constructors():
+        for super_class in _TEST_CASE_SUPERCLASSES:
+            test_case_classes.append(
+                type(invoker_constructor.name() + super_class.NAME, (
+                    super_class,), {
+                        'implementation': implementation,
+                        'invoker_constructor': invoker_constructor,
+                        '__module__': implementation.__module__,
+                    }))
+    return test_case_classes
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_interfaces.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_interfaces.py
index 40f38e68ba..a789d435b4 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_interfaces.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/test_interfaces.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Interfaces used in tests of implementations of the Face layer."""
 
 import abc
@@ -38,103 +37,102 @@ from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 
 
 class Method(six.with_metaclass(abc.ABCMeta)):
-  """Specifies a method to be used in tests."""
+    """Specifies a method to be used in tests."""
 
-  @abc.abstractmethod
-  def group(self):
-    """Identify the group of the method.
+    @abc.abstractmethod
+    def group(self):
+        """Identify the group of the method.
 
     Returns:
       The group of the method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def name(self):
-    """Identify the name of the method.
+    @abc.abstractmethod
+    def name(self):
+        """Identify the name of the method.
 
     Returns:
       The name of the method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def cardinality(self):
-    """Identify the cardinality of the method.
+    @abc.abstractmethod
+    def cardinality(self):
+        """Identify the cardinality of the method.
 
     Returns:
       A cardinality.Cardinality value describing the streaming semantics of the
         method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def request_class(self):
-    """Identify the class used for the method's request objects.
+    @abc.abstractmethod
+    def request_class(self):
+        """Identify the class used for the method's request objects.
 
     Returns:
       The class object of the class to which the method's request objects
         belong.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def response_class(self):
-    """Identify the class used for the method's response objects.
+    @abc.abstractmethod
+    def response_class(self):
+        """Identify the class used for the method's response objects.
 
     Returns:
       The class object of the class to which the method's response objects
         belong.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def serialize_request(self, request):
-    """Serialize the given request object.
+    @abc.abstractmethod
+    def serialize_request(self, request):
+        """Serialize the given request object.
 
     Args:
       request: A request object appropriate for this method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def deserialize_request(self, serialized_request):
-    """Synthesize a request object from a given bytestring.
+    @abc.abstractmethod
+    def deserialize_request(self, serialized_request):
+        """Synthesize a request object from a given bytestring.
 
     Args:
       serialized_request: A bytestring deserializable into a request object
         appropriate for this method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def serialize_response(self, response):
-    """Serialize the given response object.
+    @abc.abstractmethod
+    def serialize_response(self, response):
+        """Serialize the given response object.
 
     Args:
       response: A response object appropriate for this method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def deserialize_response(self, serialized_response):
-    """Synthesize a response object from a given bytestring.
+    @abc.abstractmethod
+    def deserialize_response(self, serialized_response):
+        """Synthesize a response object from a given bytestring.
 
     Args:
       serialized_response: A bytestring deserializable into a response object
         appropriate for this method.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
 
 class Implementation(six.with_metaclass(abc.ABCMeta)):
-  """Specifies an implementation of the Face layer."""
+    """Specifies an implementation of the Face layer."""
 
-  @abc.abstractmethod
-  def instantiate(
-      self, methods, method_implementations,
-      multi_method_implementation):
-    """Instantiates the Face layer implementation to be used in a test.
+    @abc.abstractmethod
+    def instantiate(self, methods, method_implementations,
+                    multi_method_implementation):
+        """Instantiates the Face layer implementation to be used in a test.
 
     Args:
       methods: A sequence of Method objects describing the methods available to
@@ -151,69 +149,69 @@ class Implementation(six.with_metaclass(abc.ABCMeta)):
         passed to destantiate at the conclusion of the test. The returned stubs
         must be backed by the provided implementations.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def destantiate(self, memo):
-    """Destroys the Face layer implementation under test.
+    @abc.abstractmethod
+    def destantiate(self, memo):
+        """Destroys the Face layer implementation under test.
 
     Args:
       memo: The object from the third position of the return value of a call to
         instantiate.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def invocation_metadata(self):
-    """Provides the metadata to be used when invoking a test RPC.
+    @abc.abstractmethod
+    def invocation_metadata(self):
+        """Provides the metadata to be used when invoking a test RPC.
 
     Returns:
       An object to use as the supplied-at-invocation-time metadata in a test
         RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def initial_metadata(self):
-    """Provides the metadata for use as a test RPC's first servicer metadata.
+    @abc.abstractmethod
+    def initial_metadata(self):
+        """Provides the metadata for use as a test RPC's first servicer metadata.
 
     Returns:
       An object to use as the from-the-servicer-before-responses metadata in a
         test RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def terminal_metadata(self):
-    """Provides the metadata for use as a test RPC's second servicer metadata.
+    @abc.abstractmethod
+    def terminal_metadata(self):
+        """Provides the metadata for use as a test RPC's second servicer metadata.
 
     Returns:
       An object to use as the from-the-servicer-after-all-responses metadata in
         a test RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def code(self):
-    """Provides the value for use as a test RPC's code.
+    @abc.abstractmethod
+    def code(self):
+        """Provides the value for use as a test RPC's code.
 
     Returns:
       An object to use as the from-the-servicer code in a test RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def details(self):
-    """Provides the value for use as a test RPC's details.
+    @abc.abstractmethod
+    def details(self):
+        """Provides the value for use as a test RPC's details.
 
     Returns:
       An object to use as the from-the-servicer details in a test RPC.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
 
-  @abc.abstractmethod
-  def metadata_transmitted(self, original_metadata, transmitted_metadata):
-    """Identifies whether or not metadata was properly transmitted.
+    @abc.abstractmethod
+    def metadata_transmitted(self, original_metadata, transmitted_metadata):
+        """Identifies whether or not metadata was properly transmitted.
 
     Args:
       original_metadata: A metadata value passed to the Face interface
@@ -226,4 +224,4 @@ class Implementation(six.with_metaclass(abc.ABCMeta)):
       Whether or not the metadata was properly transmitted by the Face interface
         implementation under test.
     """
-    raise NotImplementedError()
+        raise NotImplementedError()
diff --git a/src/python/grpcio_tests/tests/unit/resources.py b/src/python/grpcio_tests/tests/unit/resources.py
index 023cdb155f..55a2fff979 100644
--- a/src/python/grpcio_tests/tests/unit/resources.py
+++ b/src/python/grpcio_tests/tests/unit/resources.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Constants and functions for data used in interoperability testing."""
 
 import os
@@ -39,14 +38,14 @@ _CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem'
 
 
 def test_root_certificates():
-  return pkg_resources.resource_string(
-      __name__, _ROOT_CERTIFICATES_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__,
+                                         _ROOT_CERTIFICATES_RESOURCE_PATH)
 
 
 def private_key():
-  return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH)
 
 
 def certificate_chain():
-  return pkg_resources.resource_string(
-      __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH)
+    return pkg_resources.resource_string(__name__,
+                                         _CERTIFICATE_CHAIN_RESOURCE_PATH)
diff --git a/src/python/grpcio_tests/tests/unit/test_common.py b/src/python/grpcio_tests/tests/unit/test_common.py
index cd71bd80d7..00fbe0567a 100644
--- a/src/python/grpcio_tests/tests/unit/test_common.py
+++ b/src/python/grpcio_tests/tests/unit/test_common.py
@@ -26,7 +26,6 @@
 # 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.
-
 """Common code used throughout tests of gRPC."""
 
 import collections
@@ -34,14 +33,23 @@ import collections
 import grpc
 import six
 
-INVOCATION_INITIAL_METADATA = (('0', 'abc'), ('1', 'def'), ('2', 'ghi'),)
-SERVICE_INITIAL_METADATA = (('3', 'jkl'), ('4', 'mno'), ('5', 'pqr'),)
-SERVICE_TERMINAL_METADATA = (('6', 'stu'), ('7', 'vwx'), ('8', 'yza'),)
+INVOCATION_INITIAL_METADATA = (
+    ('0', 'abc'),
+    ('1', 'def'),
+    ('2', 'ghi'),)
+SERVICE_INITIAL_METADATA = (
+    ('3', 'jkl'),
+    ('4', 'mno'),
+    ('5', 'pqr'),)
+SERVICE_TERMINAL_METADATA = (
+    ('6', 'stu'),
+    ('7', 'vwx'),
+    ('8', 'yza'),)
 DETAILS = 'test details'
 
 
 def metadata_transmitted(original_metadata, transmitted_metadata):
-  """Judges whether or not metadata was acceptably transmitted.
+    """Judges whether or not metadata was acceptably transmitted.
 
   gRPC is allowed to insert key-value pairs into the metadata values given by
   applications and to reorder key-value pairs with different keys but it is not
@@ -59,31 +67,30 @@ def metadata_transmitted(original_metadata, transmitted_metadata):
      A boolean indicating whether transmitted_metadata accurately reflects
       original_metadata after having been transmitted via gRPC.
   """
-  original = collections.defaultdict(list)
-  for key, value in original_metadata:
-    original[key].append(value)
-  transmitted = collections.defaultdict(list)
-  for key, value in transmitted_metadata:
-    transmitted[key].append(value)
+    original = collections.defaultdict(list)
+    for key, value in original_metadata:
+        original[key].append(value)
+    transmitted = collections.defaultdict(list)
+    for key, value in transmitted_metadata:
+        transmitted[key].append(value)
 
-  for key, values in six.iteritems(original):
-    transmitted_values = transmitted[key]
-    transmitted_iterator = iter(transmitted_values)
-    try:
-      for value in values:
-        while True:
-          transmitted_value = next(transmitted_iterator)
-          if value == transmitted_value:
-            break
-    except StopIteration:
-      return False
-  else:
-    return True
+    for key, values in six.iteritems(original):
+        transmitted_values = transmitted[key]
+        transmitted_iterator = iter(transmitted_values)
+        try:
+            for value in values:
+                while True:
+                    transmitted_value = next(transmitted_iterator)
+                    if value == transmitted_value:
+                        break
+        except StopIteration:
+            return False
+    else:
+        return True
 
 
-def test_secure_channel(
-    target, channel_credentials, server_host_override):
-  """Creates an insecure Channel to a remote host.
+def test_secure_channel(target, channel_credentials, server_host_override):
+    """Creates an insecure Channel to a remote host.
 
   Args:
     host: The name of the remote host to which to connect.
@@ -96,7 +103,7 @@ def test_secure_channel(
     An implementations.Channel to the remote host through which RPCs may be
       conducted.
   """
-  channel = grpc.secure_channel(
-      target, channel_credentials,
-      (('grpc.ssl_target_name_override', server_host_override,),))
-  return channel
+    channel = grpc.secure_channel(target, channel_credentials, ((
+        'grpc.ssl_target_name_override',
+        server_host_override,),))
+    return channel
-- 
GitLab


From c781f6451887ee5b47623c511ba337b08532f583 Mon Sep 17 00:00:00 2001
From: murgatroid99 <michael.lumish@gmail.com>
Date: Tue, 17 Jan 2017 11:47:06 -0800
Subject: [PATCH 327/344] Use config file template instead of Rakefile template

---
 Rakefile                           |   4 +-
 build_config.rb                    |   3 +
 templates/Rakefile.template        | 126 -----------------------------
 templates/build_config.rb.template |   5 ++
 4 files changed, 11 insertions(+), 127 deletions(-)
 create mode 100644 build_config.rb
 delete mode 100644 templates/Rakefile.template
 create mode 100644 templates/build_config.rb.template

diff --git a/Rakefile b/Rakefile
index 8a88b4401f..c8bca20ad1 100755
--- a/Rakefile
+++ b/Rakefile
@@ -5,6 +5,8 @@ require 'rubocop/rake_task'
 require 'bundler/gem_tasks'
 require 'fileutils'
 
+require_relative 'build_config.rb'
+
 load 'tools/distrib/docker_for_windows.rb'
 
 # Add rubocop style checking tasks
@@ -83,7 +85,7 @@ task 'dlls' do
   env += 'EMBED_ZLIB=true '
   env += 'BUILDDIR=/tmp '
   env += "V=#{verbose} "
-  out = '/tmp/libs/opt/grpc-2.dll'
+  out = GrpcBuildConfig::CORE_WINDOWS_DLL
 
   w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' }
   w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' }
diff --git a/build_config.rb b/build_config.rb
new file mode 100644
index 0000000000..83edb1c390
--- /dev/null
+++ b/build_config.rb
@@ -0,0 +1,3 @@
+module GrpcBuildConfig
+  CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-2.dll'
+end
diff --git a/templates/Rakefile.template b/templates/Rakefile.template
deleted file mode 100644
index 2ab505b7c1..0000000000
--- a/templates/Rakefile.template
+++ /dev/null
@@ -1,126 +0,0 @@
-%YAML 1.2
---- |
-  # -*- ruby -*-
-  require 'rake/extensiontask'
-  require 'rspec/core/rake_task'
-  require 'rubocop/rake_task'
-  require 'bundler/gem_tasks'
-  require 'fileutils'
-
-  load 'tools/distrib/docker_for_windows.rb'
-
-  # Add rubocop style checking tasks
-  RuboCop::RakeTask.new(:rubocop) do |task|
-    task.options = ['-c', 'src/ruby/.rubocop.yml']
-    task.patterns = ['src/ruby/{lib,spec}/**/*.rb']
-  end
-
-  spec = Gem::Specification.load('grpc.gemspec')
-
-  Gem::PackageTask.new(spec) do |pkg|
-  end
-
-  # Add the extension compiler task
-  Rake::ExtensionTask.new('grpc_c', spec) do |ext|
-    ext.source_pattern = '**/*.{c,h}'
-    ext.ext_dir = File.join('src', 'ruby', 'ext', 'grpc')
-    ext.lib_dir = File.join('src', 'ruby', 'lib', 'grpc')
-    ext.cross_compile = true
-    ext.cross_platform = [
-      'x86-mingw32', 'x64-mingw32',
-      'x86_64-linux', 'x86-linux',
-      'universal-darwin'
-    ]
-    ext.cross_compiling do |spec|
-      spec.files = %w( etc/roots.pem grpc_c.32.ruby grpc_c.64.ruby )
-      spec.files += Dir.glob('src/ruby/bin/**/*')
-      spec.files += Dir.glob('src/ruby/ext/**/*')
-      spec.files += Dir.glob('src/ruby/lib/**/*')
-      spec.files += Dir.glob('src/ruby/pb/**/*')
-    end
-  end
-
-  # Define the test suites
-  SPEC_SUITES = [
-    { id: :wrapper, title: 'wrapper layer', files: %w(src/ruby/spec/*.rb) },
-    { id: :idiomatic, title: 'idiomatic layer', dir: %w(src/ruby/spec/generic),
-      tags: ['~bidi', '~server'] },
-    { id: :bidi, title: 'bidi tests', dir: %w(src/ruby/spec/generic),
-      tag: 'bidi' },
-    { id: :server, title: 'rpc server thread tests', dir: %w(src/ruby/spec/generic),
-      tag: 'server' },
-    { id: :pb, title: 'protobuf service tests', dir: %w(src/ruby/spec/pb) }
-  ]
-  namespace :suite do
-    SPEC_SUITES.each do |suite|
-      desc "Run all specs in the #{suite[:title]} spec suite"
-      RSpec::Core::RakeTask.new(suite[:id]) do |t|
-        ENV['COVERAGE_NAME'] = suite[:id].to_s
-        spec_files = []
-        suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
-
-        if suite[:dir]
-          suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
-        end
-        helper = 'src/ruby/spec/spec_helper.rb'
-        spec_files << helper unless spec_files.include?(helper)
-
-        t.pattern = spec_files
-        t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
-        if suite[:tags]
-          t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
-        end
-      end
-    end
-  end
-
-  desc 'Build the Windows gRPC DLLs for Ruby'
-  task 'dlls' do
-    grpc_config = ENV['GRPC_CONFIG'] || 'opt'
-    verbose = ENV['V'] || '0'
-
-    env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result" '
-    env += 'LDFLAGS=-static '
-    env += 'SYSTEM=MINGW32 '
-    env += 'EMBED_ZLIB=true '
-    env += 'BUILDDIR=/tmp '
-    env += "V=#{verbose} "
-    out = '/tmp/libs/opt/grpc-${settings.core_version.major}.dll'
-
-    w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' }
-    w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' }
-
-    [ w64, w32 ].each do |opt|
-      env_comp = "CC=#{opt[:cross]}-gcc "
-      env_comp += "LD=#{opt[:cross]}-gcc "
-      docker_for_windows "#{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}"
-    end
-
-  end
-
-  desc 'Build the native gem file under rake_compiler_dock'
-  task 'gem:native' do
-    verbose = ENV['V'] || '0'
-
-    grpc_config = ENV['GRPC_CONFIG'] || 'opt'
-
-    if RUBY_PLATFORM =~ /darwin/
-      FileUtils.touch 'grpc_c.32.ruby'
-      FileUtils.touch 'grpc_c.64.ruby'
-      system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
-    else
-      Rake::Task['dlls'].execute
-      docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
-    end
-  end
-
-  # Define dependencies between the suites.
-  task 'suite:wrapper' => [:compile, :rubocop]
-  task 'suite:idiomatic' => 'suite:wrapper'
-  task 'suite:bidi' => 'suite:wrapper'
-  task 'suite:server' => 'suite:wrapper'
-  task 'suite:pb' => 'suite:server'
-
-  desc 'Compiles the gRPC extension then runs all the tests'
-  task all: ['suite:idiomatic', 'suite:bidi', 'suite:pb', 'suite:server']
-  task default: :all
diff --git a/templates/build_config.rb.template b/templates/build_config.rb.template
new file mode 100644
index 0000000000..4cb4810d33
--- /dev/null
+++ b/templates/build_config.rb.template
@@ -0,0 +1,5 @@
+%YAML 1.2
+--- |
+  module GrpcBuildConfig
+    CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-${settings.core_version.major}.dll'
+  end
\ No newline at end of file
-- 
GitLab


From 9c627c2032c44af55e1a2dfec43d109ea7b5c4d7 Mon Sep 17 00:00:00 2001
From: Dan Born <daniel-j-born@users.noreply.github.com>
Date: Tue, 17 Jan 2017 13:01:38 -0800
Subject: [PATCH 328/344] Document new function grpc_resource_user_quota

---
 src/core/lib/iomgr/resource_quota.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 14475c864e..cfacee13ef 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -88,8 +88,12 @@ typedef struct grpc_resource_user grpc_resource_user;
 
 grpc_resource_user *grpc_resource_user_create(
     grpc_resource_quota *resource_quota, const char *name);
+
+/* Returns a borrowed reference to the underlying resource quota for this
+   resource user. */
 grpc_resource_quota *grpc_resource_user_quota(
     grpc_resource_user *resource_user);
+
 void grpc_resource_user_ref(grpc_resource_user *resource_user);
 void grpc_resource_user_unref(grpc_exec_ctx *exec_ctx,
                               grpc_resource_user *resource_user);
-- 
GitLab


From 5aa2bcfd4dea92ca18b7b6b0b3f40d1b8fabc246 Mon Sep 17 00:00:00 2001
From: Nathaniel Manista <nathaniel@google.com>
Date: Tue, 17 Jan 2017 23:31:17 +0000
Subject: [PATCH 329/344] Pass an iterator rather than an iterable

This should have been included in dd52a31337616fe935f79debfe5d56c6d73a
but was missed because it falsely passes almost all of the time.
---
 src/python/grpcio_tests/tests/unit/beta/_not_found_test.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py b/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
index 664e47c769..ce7b91e9fe 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_not_found_test.py
@@ -62,7 +62,7 @@ class NotFoundTest(unittest.TestCase):
 
     def test_future_stream_unary_not_found(self):
         rpc_future = self._generic_stub.future_stream_unary(
-            'grupe', 'mevvod', [b'def'], test_constants.LONG_TIMEOUT)
+            'grupe', 'mevvod', iter([b'def']), test_constants.LONG_TIMEOUT)
         with self.assertRaises(face.LocalError) as exception_assertion_context:
             rpc_future.result()
         self.assertIs(exception_assertion_context.exception.code,
-- 
GitLab


From 57b02fcaba2162631d787b4349b42146efdc45ab Mon Sep 17 00:00:00 2001
From: Adele Zhou <adelez@google.com>
Date: Tue, 17 Jan 2017 14:18:41 -0800
Subject: [PATCH 330/344] merge

---
 tools/run_tests/run_interop_tests.py | 44 ++++++++++++++++++----------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 56efac50ca..b2dac7d1a8 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -86,7 +86,7 @@ class CXXLanguage:
     return {}
 
   def server_cmd(self, args):
-    return ['bins/opt/interop_server', '--use_tls=true'] + args
+    return ['bins/opt/interop_server'] + args
 
   def global_env(self):
     return {}
@@ -115,7 +115,7 @@ class CSharpLanguage:
     return {}
 
   def server_cmd(self, args):
-    return ['mono', 'Grpc.IntegrationTesting.Server.exe', '--use_tls=true'] + args
+    return ['mono', 'Grpc.IntegrationTesting.Server.exe'] + args
 
   def global_env(self):
     return {}
@@ -144,7 +144,7 @@ class CSharpCoreCLRLanguage:
     return {}
 
   def server_cmd(self, args):
-    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll', '--use_tls=true'] + args
+    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll'] + args
 
   def global_env(self):
     return {}
@@ -176,7 +176,7 @@ class JavaLanguage:
     return {}
 
   def server_cmd(self, args):
-    return ['./run-test-server.sh', '--use_tls=true'] + args
+    return ['./run-test-server.sh'] + args
 
   def global_env(self):
     return {}
@@ -206,7 +206,7 @@ class GoLanguage:
     return {}
 
   def server_cmd(self, args):
-    return ['go', 'run', 'server.go', '--use_tls=true'] + args
+    return ['go', 'run', 'server.go'] + args
 
   def global_env(self):
     return {}
@@ -292,8 +292,7 @@ class NodeLanguage:
 
   def server_cmd(self, args):
     return ['tools/run_tests/interop/with_nvm.sh',
-            'node', 'src/node/interop/interop_server.js',
-            '--use_tls=true'] + args
+            'node', 'src/node/interop/interop_server.js'] + args
 
   def global_env(self):
     return {}
@@ -374,7 +373,7 @@ class RubyLanguage:
 
   def server_cmd(self, args):
     return ['tools/run_tests/interop/with_rvm.sh',
-            'ruby', 'src/ruby/pb/test/server.rb', '--use_tls=true'] + args
+            'ruby', 'src/ruby/pb/test/server.rb'] + args
 
   def global_env(self):
     return {}
@@ -419,7 +418,7 @@ class PythonLanguage:
         'src/python/grpcio_tests/setup.py',
         'run_interop',
         '--server',
-        '--args="{}"'.format(' '.join(args) + ' --use_tls=true')
+        '--args="{}"'.format(' '.join(args))
     ]
 
   def global_env(self):
@@ -586,11 +585,11 @@ def cloud_to_prod_jobspec(language, test_case, server_host_name,
 
 
 def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
-                           server_port, docker_image=None):
+                           server_port, docker_image=None, insecure=False):
   """Creates jobspec for cloud-to-cloud interop test"""
   interop_only_options = [
       '--server_host_override=foo.test.google.fr',
-      '--use_tls=true',
+      '--use_tls=%s' % ('false' if insecure else 'true'),
       '--use_test_ca=true',
   ]
   common_options = [
@@ -634,11 +633,12 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
   return test_job
 
 
-def server_jobspec(language, docker_image):
+def server_jobspec(language, docker_image, insecure=False):
   """Create jobspec for running a server"""
   container_name = dockerjob.random_name('interop_server_%s' % language.safename)
   cmdline = bash_cmdline(
-      language.server_cmd(['--port=%s' % _DEFAULT_SERVER_PORT]))
+      language.server_cmd(['--port=%s' % _DEFAULT_SERVER_PORT,
+                           '--use_tls=%s' % ('false' if insecure else 'true')]))
   environ = language.global_env()
   if language.safename == 'http2':
     # we are running the http2 interop server. Open next N ports beginning
@@ -803,6 +803,11 @@ argp.add_argument('--http2_badserver_interop',
                   action='store_const',
                   const=True,
                   help='Enable HTTP/2 server edge case testing. (Good client, bad server)')
+argp.add_argument('--insecure',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Whether to use secure channel.')
 
 args = argp.parse_args()
 
@@ -868,7 +873,8 @@ server_addresses={}
 try:
   for s in servers:
     lang = str(s)
-    spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang))
+    spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang),
+                          args.insecure)
     job = dockerjob.DockerJob(spec)
     server_jobs[lang] = job
     server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
@@ -883,6 +889,8 @@ try:
 
   jobs = []
   if args.cloud_to_prod:
+    if args.insecure:
+      print('TLS is always enabled for cloud_to_prod scenarios.')
     for server_host_name in args.prod_servers:
       for language in languages:
         for test_case in _TEST_CASES:
@@ -903,6 +911,8 @@ try:
           jobs.append(test_job)
 
   if args.cloud_to_prod_auth:
+    if args.insecure:
+      print('TLS is always enabled for cloud_to_prod scenarios.')
     for server_host_name in args.prod_servers:
       for language in languages:
         for test_case in _AUTH_TEST_CASES:
@@ -934,7 +944,8 @@ try:
                                                 server_name,
                                                 server_host,
                                                 server_port,
-                                                docker_image=docker_images.get(str(language)))
+                                                docker_image=docker_images.get(str(language)),
+                                                insecure=args.insecure)
               jobs.append(test_job)
 
     if args.http2_interop:
@@ -947,7 +958,8 @@ try:
                                           server_name,
                                           server_host,
                                           server_port,
-                                          docker_image=docker_images.get(str(http2Interop)))
+                                          docker_image=docker_images.get(str(http2Interop)),
+                                          insecure=args.insecure)
         jobs.append(test_job)
 
     if args.http2_badserver_interop:
-- 
GitLab


From e375975e0d9e80516698271233a1d92ff1160a7f Mon Sep 17 00:00:00 2001
From: murgatroid99 <michael.lumish@gmail.com>
Date: Tue, 17 Jan 2017 16:32:23 -0800
Subject: [PATCH 331/344] Fixed sanity errors

---
 build_config.rb                    | 29 ++++++++++++++++++++++++++++
 src/core/ext/census/tracing.c      |  2 +-
 templates/build_config.rb.template | 31 +++++++++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/build_config.rb b/build_config.rb
index 83edb1c390..35e887ef62 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -1,3 +1,32 @@
+# 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.
+
 module GrpcBuildConfig
   CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-2.dll'
 end
diff --git a/src/core/ext/census/tracing.c b/src/core/ext/census/tracing.c
index afb70441d2..9371fffc8d 100644
--- a/src/core/ext/census/tracing.c
+++ b/src/core/ext/census/tracing.c
@@ -33,8 +33,8 @@
 
 //#include "src/core/ext/census/tracing.h"
 
-#include <stdlib.h>
 #include <grpc/census.h>
+#include <stdlib.h>
 
 /* TODO(aveitch): These are all placeholder implementations. */
 
diff --git a/templates/build_config.rb.template b/templates/build_config.rb.template
index 4cb4810d33..0d9191b1a0 100644
--- a/templates/build_config.rb.template
+++ b/templates/build_config.rb.template
@@ -1,5 +1,34 @@
 %YAML 1.2
 --- |
+  # 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.
+
   module GrpcBuildConfig
     CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-${settings.core_version.major}.dll'
-  end
\ No newline at end of file
+  end
-- 
GitLab


From 79e8d81e8127590bf9489db371a65bc7493747e8 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Tue, 17 Jan 2017 15:01:33 -0800
Subject: [PATCH 332/344] update path to build_artifacts_ruby.sh in jenkins
 script

---
 tools/jenkins/build_artifacts.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/jenkins/build_artifacts.sh b/tools/jenkins/build_artifacts.sh
index c0acbdfb27..b15db2cdc2 100755
--- a/tools/jenkins/build_artifacts.sh
+++ b/tools/jenkins/build_artifacts.sh
@@ -40,7 +40,7 @@ curr_platform="$platform"
 unset platform  # variable named 'platform' breaks the windows build
 
 if [ "$curr_platform" == "linux" ] && [ "$language" == "ruby" ] ; then
-  ./tools/run_tests/build_artifact_ruby.sh
+  ./tools/run_tests/artifacts/build_artifact_ruby.sh
 else
   python tools/run_tests/task_runner.py -f artifact $language $curr_platform $architecture
 fi
-- 
GitLab


From b4227370fc8b84fdf8d11c3d1ba94492347da1a8 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 18 Jan 2017 09:21:20 -0800
Subject: [PATCH 333/344] Code review changes and other improvements.

---
 doc/images/load-balancing.png | Bin 27733 -> 28073 bytes
 doc/images/load-balancing.svg |   2 +-
 doc/load-balancing.md         |  67 +++++++++++++++++++++-------------
 doc/naming.md                 |  18 ++++++---
 4 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/doc/images/load-balancing.png b/doc/images/load-balancing.png
index 18b68bfdad83d15b33f37eeeb98f582feb8ee0c0..7c70465e653dcf732875e96ab80e65331ff7c67d 100644
GIT binary patch
literal 28073
zcmeEug;x~s`{*pvh=i0M6r`I4LAnGK1qnsEMM_w@mRuD?K)|9Kl<ru%OS)u1mc}K8
zr91Ade!kyx@43H!;GT2maA0`noq3;lpMGXSwKP=7N&g`Q0D%0_L*=IcaHSal@P>#9
z!4WgB8x;TmbAF_J@0s`H?*@u5H}(9NeaFA+Pqfk@9fAZBTfSSDSg|om#=sy-g!~JT
z7i{mZ?pOd2R$_hy2}7-tt9baOp@2oF_e38d2OpgPRXDY>t^<wMyKBRor1==za@KeB
zR;gtw-NTFAaMhIC`)fx2feF&z^42!vH&gO92bYs(<5xFNeCr&?&r#Sxk82=U|Nr>^
z6!?FF0&~W69Y`_c@Wer<=MQxEM8*W+YpcVP!=3k51~LEnL8|tq>@B8rw3PLpt>3tM
z9RlP<1@zev7Bh##>>cvYBc2C1_?Px)<$@@u^~P^>$)-<C)1X@>G}@5@$Zw+80fqe!
zE79494;}1napHkcTskiO+`ctG@%EOf1%Oa385wK!^{fqLk;73<D;1(gmdTXK0{}hY
zDaM<wm0YoEe{bXw4&ej<Zmu__x1wN~Y{o>mC8N139ef?!>_`EGYuan_E23AxQ3a!k
zxt9ZP0}}9Xj|70)TVn>2Z$YII$0Qm(Y?uH6$I>hdTq_O4h(id0mD@^12l%dX>bUWt
zC#WvZ<|keRKpNX#&E$)Xa9f=ELD*TSIIw|FS2+E-Oze--KXDq?9mphW0I-GjNdLqV
z*WhjkX9`*)^D*awUqKWAK=q2H2!If~jm0wb<NnwB=Nb9Q*Gyhf5XiVk*KtE%!USe;
zf5D?R0bV4g)Wr`1o_3etgQgLO05@L(ogFQBw~)u4==PVzTvl*U!N7nH%>-hSc2_>9
z&JG6;VkARKfcNd)#4HfDe-bUx3L=0)@JbZyHuApX%V9o|bFqp-0#QET%S}oCnBl7c
zpnWNPE8_-`_UPn!IO*e*FcVYrx9@2S++>hXnl?o9w9`U7x}L5l9jx~`?o4!@)y^X;
zHrykpOD-KGJZ2ctQ;p@fjspOpkHL~nQ6S~;RZRL5@c^M45WgScEfpIFsi~^xopHd-
z{3Qh}@OF^WJw7N_?(*l%1gbh=-18g#PoK*Y`##3{cIMF=&?LQfF$T0$px`8G2@fJO
z2(3c)Z}@&s<pWUzDk#bE;xFj|PCi7q@}y5w-@~`SX0Jh)9EG+B^7K#)Q?MI%SwABa
zPd&y}514-1KIVtYut7`8@tw0J!T=n3Y-Op`0pP|}A1dC#6+b8w2kEjH3!*$GmkU9E
zG*~EM))eSpVlMCV&T9&)E&2^j*i`62&}(a0J^BjJB%6zGymjI_>Cj;2CA6sTE*O4(
z8Gc^2{^qcC1AQC>y9P8w1dt&|L820y1GcwzUT?ZA!t2XK9H+>nr-A^ct=`{BLBI^g
zERnv(^t%h&M}DGn<dSG<;R9F1UG8c6ik~i*m#@BfkJa>++cT{XJ<vu|z~XwT0ppE(
zzaHUsEaWOs*w!8&lnocsgHuiA0I1vQDL>c(;?p_txAaxFCf7RzB*c^3N;${vlmYBE
z`dV<_fLS`~RAfN?xF`Je#;q-ENOTU#D?*?X1^{Ot@Dvz79_r0E8MwWPS|V=oiB8j7
zCY~x_)eo7jAt*dRQT6p-%-rSUT_>5lFDQTM{rS@2(b`nV+V3kMDDTk#Fo~b;0hnK{
zK6747zsbU&`znT5v>5xYx2VThlzc?E$&?|ZzAX?H_Huu6Af1kE&ckuaQtrc@QwNi^
zspX{#X*>pivKhzSTNybE+X#Dpe5s@|Ti7dL(|#+CpS^Cz4-?UMh5wa*-Ybl?I156&
z_9SI1BG;{W90?Lx0l<lRMf^8{R*zhJ86thAf$JB$-?V9(m*7R>9Un<yJimMbTJE5y
z+CTh~+0GZ*l2s?2!(5c}Cq{r90$&JFkYvat0h%+17DXJNk6Bxm+ZU1Uxr#Hf%G#6S
z=?7Ow`npI%ZQ=<os-u4Vj3MctCg_bz^DnpuaagXAvos1ncRl|Xjx8lp0Mn*C*)u2G
zZ|6ICSDt)Cqp1(YLp-PTB2Pkh(zot=#PThulev-S;~m05b&`#{rVp9D7UAFb@k{#e
z`L(L|X~(R{uT+T#e!@EfV%dNfXQm)_AcYLu9mM6#HlIMHI2I1n6@gw$`(0va%4@*$
zl|)4S-1K^9{)5!*RB=U#!R;H+JBKHW6^h1WZ!nDUgpV@Lz63rrA1j0j&Q;!6XrhAD
zLnTt~8pq&hj@zabJ8z4eE9=qfrj!Yk6-hIarbC6r<%P7l7~SJ>H%=Ghov)4uc%H@L
z!MvJTihCdAub~G7p}M0T6){Jcn6CrA2A!p{bPi5^$?LhLZknU1lOZro+ETC6ecTGT
z9V=j6-g~XId}@L~lnQ9BxCd@L9OWx0gX#JF#Q7z@$)G<M1$+cmrTG*g&`iMtJR=My
z<V)2#F71KHEp@s**}ecZisKbvE`$cCCDl>Uo#)VT(lyQB3A7pE2mb8Cya6FlvOxv-
zN6x{Mzgq)5xs3qrRU5;9ui_p89zCr9IP^bH2f!Ol6TnFz^Z?LYO%4D@ECk>w4nUmL
zfTuWkR&Knt!=2;M`FnuO`g?$PYTfFz{qI%zuefn7Izrsg|2Q4Idh1{W{|{HdsW|z>
z(E>ac#ehGkgW$R_0t$mdQ=PElcQCfM9^Z9`lK-j&V6=twk}bj_SyUN>1&4Fm;&(QB
zff`KwaLCNb&8znLt5UmfUPrjg{-uoqljR0YGc}j|=}aL5N_W)bEsk<H$R3YV@Zd2h
z0bYcz8^W&3tKs_Cy-G;!Ke(-^1RUl8oa0PvUMY?5hQ~qRAn#cazOTQgnt1iPW%|w>
z+_`Gs<326%l*n+Bp56>@wbw}B#L&hWS44L5=Lv0;%>rvS)FMWgzt|X1Ush`^v}Pt7
zxl4CPy&A9M=7rN8R5rMa<6wCUJOJ2Mgz$y%7}g0OkEuXj{~v=&IPu2;#fA{R3V9E7
z;#A28p+6_Y=2szC|NO#H^xvz9zf=DF`QIjhoT6-Iz+=GS0{Qa`@PUMxTM(P$mLtR$
z(j|w;D0qQ}AF#xYy}pK9veXo}+`rGlzl8%9yb1t0Ilx7CQDUZ&nGxlADwe;Xu224V
z!?&l;`y-`$_YC4A_b)Hng1cQ-oubI*YDxu^z}x0xM5K{A7YuLL_@zh3vNq9_Xli^R
zR3@G`R7nqXCuo}a0x@O3tV<otJ*TbMhw|7F8`ZnNKN)C-&mbK%c$AmFhomOn{Csgx
z0;JHQ<;ELdyAYcf=n-tyPegVh`<dI)Cy?~-X5W-<?DR72D}ty#!6yTq4Hcjl39Ci&
z5p1364X6iM*)qdVqlfp$`yR`g$sO_IZ|#wp!{e`=-jl-7xhh7zbmJlXjb<0}w&hO?
z=!b}o0E0g?0uY;2%_1oWP8q#|@gHyeW9$JrBTB6k6#soRnJ@S-=Gbhungk-#falGQ
z#01pgh(Bd`Vwsq_vy-y3AQo=Wa;au1{pv4&hWOj8=$a{Hw|-A)t;j&mxGpz?hgI~<
zXvv#=H1-C@O_=---i#{;?iSJ~v;78@R^ZvW9v6B<ic?}=Z$=-clxh>qX5YkY=B87&
z+2)kO=x_6jK!B?Ge(!{whw<ccRg<&-(n-_d(b?CHili9%Eot!=f`|PA;~XirMuO8Z
z>42^r@?z=M;Y8+Oc;mt9vZl9YvByo)RbA<<CL({L$*i4f`Te2#U#Gk;W9|ANIL6Nn
z7!QV3$2}=|oEj*^u`T@!+4$}+HVtZO_$By1KN+RO-yluqKyXy-rPOzNP08^29DG~m
zD&7}2*1#54pN_2b^bTseI<{fhnf6nVETgC5CWr4yI*{ynnB<h>z1<A7WBtnS6KdZ=
z%I3+`7?R-i6_t}u=id%<H-fveLI`}!OkY&C+#i&HO6uNnTd@ilOO8!~<r|$qW$HGD
z(1`~CpNtVKMo=be@#>%%npywZ=}b}l>E4S|DZ)y7?n(7()uWR{pS`u%K2Yuur8C!?
z?JcEO%i2<vPR`#LVMzJdeZ+9v02Bm067zUvV<{Rb0R#s2!#;FQE3LbH)o%dCjj+Nt
zUWS$TCcOKkCDM{T=paws>7$uqD!}Gq$D}Th4YRA!vZYH-l*wA<9ik5DIUidtu0CHN
zNqLIShUZplN?XJA`ZM##cdXI1Qk{$`hwqjB40T}FlMH7EF1N;=RD&uHEN6aK07&GI
zfL6Cp;)Yo4<pw=xG3JRzRWK3?DZ~y>_D7m!7@~i`C&eh6K{?>U-@1w&mR;(AiLBoW
zh28xZ36TnWt=T(}f^lkZL0Zye(+7Au3*yO8{^8~NY*A1-2BmAsRiAhM@`oplTGXc#
ze_5Wu{9@`|=lv)i4Z@yA-C{9OS(s`0*h%yBbL?1sd;0Bb1QqyM1A6GYP*)!#6rofX
zKZJj~aIt)_pWPhh`!Y~~jl#|66cyv?$7#$_pe9F7{YS1;&hm&+0eXoq3*JSS7OFK=
z$uG+OD_3^MEU;W4=9^M_c$j%Nn!Cm3xWNEVLcqN;dC&DuFmDK}7OS3VpF4p~yrO@l
zgVcCs4rxVuYEYeWZfgREZn<(1zAs7+LyJ0Km*LRD2#nj4Jgp3r5;rK`uc=2Gba4q6
zy7lqB=CH{3j}!kn*;U`b=}Oy^B&WN3+lVpIS>5*w)xRY4(IfNK6~ro-)1e9!^~7ee
z9}*c@8(PQm6b4lQOIc0?5koB=u=fto2vN+A{ph6~oX_v1mjy0ase@Pj-Pd0CS-cdK
zNWT~(slLpY$PIH(r5>VArT%dcFH^yLC)z{KPP;BnMN$p84ADg47uEOEZ5H^)uT*)2
z^-azMt-l~O^Uw$Q<hO-!q;cf&HHOK}Rv6H(+{z`=B=wS;58eV*lG+$ORkJ=3&XVng
z{RKss>g$vNoJGlEN)^KYDvwoXBaX0J=Iai7$ox<0ultJm<yqQK^{ZV!Z=@qk`3Chb
z*Dda$e0DDANX&1=BD0CecJS6&lq76QW%i0*8Lxzq%$2<cI%{)D-4lXo*GB(Z83f?i
z09;c_$BbQ#Eftz~4_=TD$ZPtBr;lfpGFc$$LyNjehkmIGtWVI^{(c%<P*CQk>-+F~
z-booM+Dj~1{^nbb_0td8x?RP*{RZiah66iZyGsz%ML}5w8EH^3ygi-!n*8Uki5L}}
zxx;sc<Q>QmL1g?77OR?MPd<w`3ZGz|;JrT&_fDGMP{b@TTrTuGX+(CLuIulg6zdkQ
z=|bvb)A;~}C=&AquJrY%=}md=1zN_T)g^dknD1{#*B{>p663x+yc(QEo7R(1UL9}u
zLG;@P_0kvji`f}A;@bQZs>TLj>nF<(3^p9`o<wK2DVnC2kY_(AJNDbfFX6o_Eg$@e
zN%`wwOO`^}`Oky>t=lqQ_|AtQ71d&7x3;wQ8ljDtB+P8-F?oD%)9P%a)XA2f?(*ic
zc;mUV`z28TNA2$2D&?x#-Ha8CQ?;z&;kT;09tEkVn{QuSLQMjU$|5)p8zp?!Rm@`R
znFXr?e&6aAwoCOnA3}*&HS`DWM#%*MMdoI|#UT7F@p8}xQ$I}fH_6U%GqdoQs^R^`
zjVEI?EqI`<qHJE3(KhPD&r$rsvGwcK7lqFZ<u$fOEQtOqFY&ZqkB6CclO<zrIC?Uf
zUw5Auo_wY>nT=mea_XGAgNHu#xt%6fA{jh(ZRytd8;G>Ef00`WJXndsGX;qGd1BB}
z;VvUp<bzfLyix(wwu~jJZ)Ie;FU5RWzJcy-VB5xE>TMwo8IyaBN8x5Ji;}PRTF8sl
z57J==)80Dn(*lDL)@Dz9t68bg-(4<Fuoo})lI-oZV^@oj7RAdZ;^HUm;<NG=fj*a+
z(lgTcB#@csOta;3k~SOHK_BP=APz;yiwJ$VIa?J2Rl(_M5Bw5ExPY;^(+ye=RVW+F
zx3C^+-xK?k$8grl0v$orrQMV4jTQe5X@U3q0ku-)u6B1*i|P}or$~vA8{)2x_k+tS
zZUu{F$7)Mdx%yyoqpNiozqTcFxME0jb4u|mF4oRQ)8~B(#Xj5~m$a>0b^Ebi;8ul1
z*`#;L`d^c}RvCdTMm|lnf@S6iOtK@QjjDN&Ivnd!32Rnw?CZ;5JOs|D?eCd9E_s7W
zE;e`)YQ&Q^ZBbLwEtUm`jse|d13oYM6ZxPea&=hQVt$#<{=gE!+M^MJP}ws~mFCfJ
z*;HSl+PNE=nn4~Z0Ll#h3OyV!=~)}0%8uxrbW$A!^}#3<5l=`00Bgd=4<PR?V3f^b
z-j|Q&Ecg?b?Jb=hLjGYucs&EuUZ@JGp21EUD!c7TkV3{)E8Z1Ja<L_aTnKgi_3~h7
z;QY^XGdb)?`;KA|rXgCqdPU|jcXo%9A%o#}PeVY>8+~bKQHcDwI#J$UI5S>qk2cg;
z58B8)RBz9ZP`iyNoIR^<KhK)>-!{+mFV(^G?y@&yY}j2&%#0SFqVzwA4V3KexCO`X
zeLhsu%&t$8#x{r>Y+8Cv)1I#sIz=?P4$6k|(CcC!-4577qBG<J=3e#rubz{K({uH%
z9w`mleFStjH%`n>zOB5vxOgES@r%ITOv+JuplaG(`+3uTo}QIpvCNES)84n?tq5_>
zEab!GgDirQNVC(2%uxgPmva~Wv4vF{wrZ6d^n^qrQTNh+Ofunu8p>vUT6|~JoNV4Z
z;Mzur<dv;Rk~x*e+9ii~TLo%@?+1J*;Woi9R>%dUm`J2zNwo#3o2l!UHpc8RM{E1`
zfgVDK5|vRt$K^X`Z<%Ha&K9hd(qgYQvD;mTN6{t-XwSG!N*9ThJHz5*L@25zh0kVa
zrR3D{CQkZ4hV3P49CW<7?_Wxbr{AiFu02}SjB>30UAFQ%TUMYJwmG%3Lk4}^Zpy8U
ztvQ%n$=Dr~_w}QOQ)fe~_eNHZ%Wb&US1OU;HXg17pZfe7kj}iZoE+<*bUNfZ894)`
zZuX})OL8#s+{MIlp@(Xz7w<1~vgGcY?Vc@jtxvgj(0045HMH0lJql_RI5nHydb=V?
zKNhC=^2Ubt<)H79$mhX?Zpg(iHPcT?O^;9O-K_=gFYD0@CY40&DdF9UiZO8=)4|0B
zVDRvbwt1fro4&EX{-xtU%(-tKsJFyBO1M~NfBm?o+(!VL8}uRui243m|EhZLLw8m7
zw;d&6_$6V+!LP?n`5wc|mRT(FVL4kmnd?8UH}{SU7V5}FU8+{}y7&2Dr&HmhLCE1_
zwXK&oLOm+;cj5&G;r}S5<xk;cAe$F~A-QW|pP~_}bv@J$!vEPk##scK2WmA{xZ!?E
zeL8gqHDc*Tw89TpXx+(LxlT%Dy{TH##r(QiDj&jX=WBv_^tg`VlLb+lQaGOeYw5k_
z9;L#={c)Kl>Lx=$nzEgL)@3V0HnKq(ERCOt8J|Q3dYKhEzKd*|R7{yKz$&HKfJRy2
z5VYN$wGRPiC-b36^@H(b%4WKly0yjP)U8I|yEY_qGTJL;uHJ31I8c^FXnXEB?UtuX
zFFQz-k{~nIh9Z_G#73>bl!;6&*=D`qZh8wDovf20dJ4IhMbi6S?f28;j?vo)-@@67
zLa2rg&^yZgie5vS{d77#{V|09W8BPJ&>J_C!q;CArini^(c{~y4#f13^ga?&y{SsG
zL}CsP7)}393Pst#=ljxuftOrx?+rh8iOM8oyr~AOPHM!Azn2o8e)_17z`fLKT`2hE
zwrc%4L#x%VT-2fP7*8}VEW~7dxnCmW@Ci?!slcif7QVq;_v6ahVQEAsnBY{A1`SQy
zjkg3w92n3)q_VFmG1OxjrGB%zuLLRJ?Mvsu>M_j<#iC@IwRse*n9Sk1plO2nN-ga@
z)96u&@v7pMk;!jHi4xD1%qF#7nQ}Ih`M4RbP1{Ttmb4#VUj?!k63c<0jY*2uv`?{U
zh@saJi)YoRe!FVLkyKuvV}N&*csLzv)Ti1yt!&S*=8)xK^5Dod1wejSesDhzp0!V@
z2ou!w>JBp}7jh@~6Zg&)v~=_lwma*%A}(1NYzH4gXB{C9iaaJ0-R*`AH_hP=(Tt2f
zZj2<aG!il2v)t^Jv~7_~JN>+hR-E^ke5}jEJRVi^VQaue#Jn&1^)$Dhhv-5e#`^)I
z-HqNEIXGt3y(aD5(aIulK9ZtohNFqAiZ{mcmy);;<p=h?*8VYc&4yx{>}w*|D-C+T
z9cpU=>oQgmy7e(fD0|vjQUaGyoY!|7=N(P+4$Y@sr1G*NG?%Vcm}C=_D5jb`7<+O3
zYXnWp9W0ESIFYuw=X11o^hBT01A_7|Hb&3x8JzMPK9H<U9|DyZZ``*_9elogUiSu`
z3{`G~$(85T<M>;%;*<17^N^UXJLio%CbTFp2RpFCnn*NJ-$@<ZLpC6FjjYA-0gy;k
zokRW@$Zq@C_Q3&;&>5SwqWMO8IGRJGKjR$iU~?-9^Du;EWrr@mVeIYd2U{H6c-8j!
zB}?gJ#x<j*v;2I9%UpGi8ZkTxZWA$&2G99M>st~6_1pmalwbAdc8v>f&`!Uz>^_tc
z?ysw&n8!thhBm7~)uGMp6xYNnoL8?mu1sr7GQPLdPi+1(e|CFkN_B|S80*(B5RBGZ
zLE@K0awVxv$Z5MkG5dyhSA8U#NwK;CZYv(B%SjDx6dyMtf8<}qp@UGhsESwumPzIc
z>c`x#l?0V2SJJ*!^;P5$+QoN{an{Ayj+<XA$-6_30TK`I+DrD{McRe0k(i&#B(E3j
zYE-3Tn9yeS`JYJU8m^i^Kx?9XC$t?5XSscj`rV`(o%BAKd8%Co$7lFqij8CZ8o@Nj
zrY9_3Yidn~*=O$Oa9?(+*Fa;;)J~sU`z9_EFzr4qa_7E#2Z8fAJXh)o!6d2aqoIbK
zmby=218|+R-AI*%r=u4+2^FEe)&wO%RXcAgBV8Rl_$N~p6ZTUg^SRF?X?m$!q=?je
zzrr3$tRK-7-O|k~;zHb&{fv4tF9?qq)1~fM4I7UjHm?jvX;*uTMCVE0Mx<ZClPKtO
zXnh7R!7YPdLZ%1@qg9@0_V<MnF**_`v4V`Uiv%v+8svSQG*}+Hbf<Nmf_;tFhpc>s
zb?-`9xMQ1)IXrU1e|H9Ty&087eKxNI*}b#gqOiiD$7pwIkO2xRn6jEHqHIp}u{GWM
ztv0ABlR3(QC<a6IugQu=E{ETSIm%OF{4Oq{-9$PH9ne|!jC9RTMq*rWC-Y&E>lOmg
z5}9V7z|PSN^%26Io9LY#q4kES`g2t<lXm2A*EaM%JOJ}*j7HuLQt({s{)`$1_3{R0
zb*&PaIo{6{j$aU|^xTkhJ|8xoctxUO-xB)}zq&mO$pXpW6%l@!wfjTZkP4b?b`n=v
zNZ+*3S>BbY_1pcsw=Vi?6%0N8hOl9_@Ax(%ABt$Jfm?}D6ormFAShY-75(nBbIjIf
z+aCubyFk-MR^kBZQ}u=yZX1Ry`7#iP-Rpey`sne?{=O>(i=T#m)K12b{Lqr&JJjv9
zMT0K)){8_ZiN0Rg3np`4&5hjM3L;Xe%RS+|6`dV(?=ZJZRxs&F+5D}d=@=DGozCO5
z?EZTej<rYGgfs<cyKm^wv-dtM$m%FmUbl+vdv`G|?wH4i@JKN<P1)p++Uy!Pj^<CL
ztMidaI~YD8o|~a<CcWMWI-D|GHYml&LVX%tFjE(+4J2-Tp^Q;^_FR)`xMFUs(SbLu
z0*FZ)6BAV_$&*7Hx4=zp;Ncuczi7#WGY|65zjk~*;BzWKjUI5sjgAV^l9&g(^VJ(<
z=q=2&#*b#fUItPZ-l<gak(Y`onf55~Nfu1|=J{h=_3^rl(x8)%ZxO*?%zApAp=9PH
z@+58iR6N6nKPgN<dq14@zodPn;Sl5fCEFd0%Q$<xjZSgNvhIT~mWh?qAk`nY>h;zy
z9E1;2RdJq}dMtBz5R_c3?Qi8T|B@rt`tBih)tJemQuAj+Gx6L3sd+FBpQyg6dT+dr
zl?|qW_XoXjDDW0VY>sKPR%c@$%<GM(7uN);RO>589s?n-YaKXU_@TScmM`vufyUm7
zdD?HhqZ51U2Viz<J?XINJb3*&Hm^N($GkErbWG@(A>O#$s9CUx{VmLL?U!ZGJ9zq8
zFkYweb}w#6j)489cF&JM%)?kNy#wE<L8rV3nmYoTqIlI_1SLAJby@i7e?_XDEu7y6
zl-BV}+KZ99rFEN9jMw-F3l$@1FA|qK?gN_rzgBh8J=Y6AtQQRZQLE2PfkeG$!RaG2
zTA^l`rcE$cl;Up&FQ=~R86@vWpZV-HG4q+>?yDhE$k|%#kM;`MT+)uh*01UlYnK_I
zS<3~Pa*4~##SE9C@}&f@#VAQIVF<by`hd|ZPFlaG1I46<EUZ+`LxzxoR*i%J6*OtM
za5r20!0dgXYQW(o$MSCaXmlwR=oU<O=ogck(|#Bcjtuzf)Os4#bh$Q#r`=1G8vX8J
zFrnIqmo;9En>&3NLk@&`-z0Km0fq0yfXf<M&EA0DW6c?jPNTg@TD~!0&xP-dCBY@R
zH)xwJnDSebLEXYJI?6hB-EBYYiFzzgpx!d7@7TSSX0ss49zJ6v5P*XKlW7xfZZMx+
z@$l|;-XMpdQu!b|9S8AlP?>9p5eGsbX;P-dU_tB_X)+h0t={TZVk2`fB9SsCRsu><
z(>KfUH%ngk2(X;C5}<3o@+VWj^+j3R@T=;F+SkW$b=y2w_muB<iyipzOI$xxCSjOt
zLecKr?y`_14p*p8C;ZWhSM5-2m=6nr3YT>ULkph2cH3wjf=ojD?BXR7>DRPu>;P(g
zQp_2~(0a+M!5Yv^Ay|W8o+@l+W6yK@PYy%~XX^i0&IP;)SEErpRQoes+j8ZsEagu^
zl{e=~xOEMcHFW?m414gpHsw!trkgyrJ8@ZDG+2?ZNmAfUXRg=kSpqKI2|npIqBN3h
z?r-s7>+565N~zAhsVeF!Ug~eTfvr6~dBlZ67CKtG*9tMqs-lLQ1+5_hqP0&Te&`5#
z4#ly@tta-W0ReXoi~X72a?q2QlLaHs(RcD33iD7>y2(!7rYB~*SL%}BuM0^l6w`5O
zwLdkA_kR^WDJhszb&Mg>oiPhFkFU>5*nD`YX8bbJ+(=_AjW(sgt@5UE=!@&c5yW$>
zpPOU61rip;p_dX3ea!M>seL>SsgEdoe^(9&^Zho$s_ltTfK?MPRr@#9c^kpUkHAb<
z*hP$_c3<an%59D3Q1%cskgV7l=&{U)@jNr=jk}${e0R*%Zq$<|CYj5b_EQ07q*bCq
zQ&tq}b^~4%U3Z4Ga-;qzs2#8+UiE^^qYyfO30k24q5<LpXu;q58UShqs&hOlo_E$&
zA6kd1@Nw&~Kg~C%-g}vvv0(7unhLJoWG<uy0V9!Ez4VsV)xdv*gDLGz;NfkQFW}J_
zlftqi9bazcvvi^qlM~DPe_8Yw9ne>TXwT#;|6as4)vkKbMmpTjW`7%fx$ZZgSLUm}
z9v@Wi8kj%V@h@Nh-lV|xe!muo;nCBBmwz_U!+RoGC#4tsbezvm=i8PI?Lb~@DeK=I
z`L_gQE*1EYj{{NqlJW1J2eXP%#B-2Z#{blusNDb5jP_sut(^UD)vEuiFjadWz<#TP
z{P9gezT6AJ?S1_!vN?m&<c$Amym2COWEvNC|5+jpteSyoY&5~v*+k?JIG)uxGGWb%
zb96n3rpKpurj+~4mnWOo19|@OTf9|q|Ltn+J)jB+6>Qw;QT}bNZ(A#9_+y;#rX)@S
zFkSuQA{!ZO3^KN5J<qSP8m2E*-Md>T|KQ&m*PQ9Wi^7BD>2)z`w3p>+h<VBJ;zR%y
z+UB`5U45Vo^70?_vaNVK)V~yl92+AQvm$93ElqZ=^h1FKrf`^-1A5gy*dY`qU_uU<
zzvSPM&-t^}bu29$5{(781nm*$=oXLC=J5GF*MIz+oGYiK09%3ci&xs2Od|rK1}rBH
zhL1(SQe=c=(Ls>s18Mv%T>0eP^{e*Tt5RSQvVKK9+{lD%X<v3Ja1r@6=2-GMLs};5
z(K5k;9!25Oh;cB#ZJReakjC|7Wmqe`>X97H13|WmH|GQy;#XZ7MfOty7N2clv92hR
zs>;}VoC;`VXVa#0)_$=5nyi>%p^}JHWBPN8&+YTeF{;vh<NnW#0m$CsriuY28hH4&
zBBVkO|I$8hHaT>|=Az0^Og*}rAFLUtd8}AxKBw6QJBD(AbyED_EPA^$n}ZDIXs0PG
zrr>n2NS7W0Nb$W6q&W+uX7Rh$b1M4~M71JDAadb4phdnJwqa)MDOW60@8*VIgn75V
z8|eCTW|lw{s?eqE9Cw<3c9Bdx|M-WXy)7YtK;0Ri{lE>@$E_ZuZ`y!u4mP{&8{54F
zuE+EJBCj`sQqLPM^D_`_q9VAvPv)f+y;;?aVYNB&#$Z*sP(_nI1bhrPOHUx9+x2WU
z_=NgZ7t@v4>3Eg^b@q@Zm%z==aMOMbSm1jImje2JNsx)@fUIKmL9<5sAYZjH03JRe
z#{rbKOp~-NbIyUc^^@rfFIRTlg1iXOCLe?W=7ZA`yN~a}AhygAG@ff#EcL?siC`@q
z7L>#Ya9<%iN9bLdW!s#(IUR6W6FT9elhXEFAAV&k*wHU#UOTeh98q>gxA%#X$+=R<
zh4c#^;J%`A=<MJI(l^eUU5n!6l~YPp4)iFneJmB~WBKNEnhEXLmDCIn&ktlK5WevP
zr6t+Y&EfRs?f|5DZ?vzi+WBI;!BM8mtIX}eXQHbJN|2097UA?Q-mf8PVGiyQzJ3sZ
zMP_<W@+JiUj7G||kcMn#^8ji6{7&0*#U^;(MYEjg!{7qCr4wUWFO3HDNC2Vp9Nx9i
z3EdGIV2F^$T4s%?5Y2lVAy8pRb%!PgqCl(}?Gcbv`K6cwNR!DST_f%X0D&wh@`_{q
z!j3Zm{uZ^~?hoawh7ihDZJ7t^n9ep)06|(3$7~P8v8pv7DtIF4klv>oeGpw((6po9
zOAf^haBjrN@=Lc^`-Ds#zxx0%*4*kLs{WnwiacQZiQH7;f$2k}rO;$3t3KnK-JuE&
zx8s-KJsu3s&k6{E9QKoW)MvHeO>TFWSo+SOD|iZ2YSYStc6CJYS736?{bTT{REk|s
zyxT!K<K~U|lEix@niR*^hW9`>Cb$)%S3UXTQJr?`eUCrAg1$~a`(IIJ_3MLegUG~~
zv9=Pn0GT~~hu)i`jDMTrnng#|cZqQgJHTV<Uj$cf2jRxkdY^prrhRKT)CNlv!j6^}
zVq5`*KeH6Po(HEFNVyi52{SyzzMv$>aSANBZ$58Gl(;*TWG58~8IR{3+Sgwq8r(?0
zf}KRIxQ7o}Jj1xF2x(3I%JPcb(&)P~#qD2uYp*Nw!^)VkAV6$^o0P+OUV7^q;aepR
ziL5&$=IJ%}R9-{&d;}SRAkd)zfM?o3s_R|o^4X`G+CTA2N?Yam)1*WJ#XtQWygkqL
z$leH&S<yBFe}MusBv<~u*rOzmS1piZKB23ZLirzD_C)PXU}2d$V4=T!hPl`^SI;>Y
zayuydp_v1piGZvX@5+4AlBd~bmXo10xH=*-V`>K0V(#ch5D9ONwq%;Kp7iz|>NJ|(
z(_kY2#%Nm;UTy?kPRsoYG~(R#&6wq&6`xwJN{0zz>_OQ=I9fL{E5v)bN~(_>yjs68
zJ40mLAASYgvDV7@0r|1`#Zj71tBVd7#LxVtn#aMsI56FFNB%=tJ@IDtBdOMmiAcgL
z7%Nc{K(YFs_0f4yaTH+_n@_{f%dGYD20{79hAe~rE$h(%vP!A2L-a=>rUgEbHHf@2
z8HTTR2$68kRqpaPukJ(_fZOf!z1JRI4s}!B#CwF|OePuU5!HrqZdAMHJ}P)0^Ed1?
zb_)ZfeJ(39KQQCy{v|%(Lq%j(oG!5>5hyia!$Cw%LWt+RlEFrW_G_nu;S5_{9us8N
zrR~g4aYh9~>otCb;C)&;+^zV4mOqQkLKU|DXnLum;J_^n0&(DGKdGQ^Z&NS8wTc4j
ztWHWIH6>Sy40X~H?_0c;Ndq@q_Qz&*y*0gUUNX0tWdi5aKw16UFK88$1yelwK>61G
zzPtUyMs2$N%o2P8VkCWPM!jfCveE5K!M-5WBTtONS)^}wqqK|4kr+WKcPK7fFi|{C
zg!iOCX2#;Oi7Dgf-h<8sg`0fXLoMe({rM`{@g}d4h-G{<b`LPaA^nAx-1XWC1cjt#
z&L(`VLe+eoFsJMMSa=Q}1kPZovn^56`=j(|AaXK%!rydi(g}0(@_2a8%gy@s2a2QF
z#PlBlkp!nd`}A<~VP%!eeA{l0EvotTC#Gdyy?papDu@gOZhmm&_M^UKz2+;(6bN;(
z|Em)6_zn5QcsD2g&pv}$N<FG|ar2#gsyGS#5_#j5#QU?fyn^|`f1cgie@+2OIyZ5=
z*4R5O`NjlTF=3hFPdvH>3NXUaB9i{m(%mU7SC^{U2>M1vV3{qdpCqu6sJaha349o!
z#TP~mFBR3_vD8UP$XaDM$ZDC98$YVAZeT}r$jr)JF<t`2G64sDTBjj2rYBOS$?{dM
zeynRWGtQOzt0`*Z!I}Y)vDe_0tN%*fR^RWk-H*#B!i}g$>BiVGur*gPF6$3a%Et{V
z=eLP{5(!#v>+iw`G9H22K@@D{0^G@V4wARuBtJ>G@?5vwv&Zauh%tQGkMOVHD=69C
zF7J)dbWz^sB3=b0Waqhe94Dy14|6C@=Rtp|%z;3j7IdOim>Sqx5Y{~EcsIDu;QS0{
zYnL}f$v}Y#3EB#qs~6@Uq-+5I4(sm`AyqH)(&Q4@Et;PYNJUu$_WynWfXdJJF)^3+
zFO#uAJ@?Zxv$hhFto2smU{*k3H6GjXz8)@O7a98IrsMPAE3=XyVta9v8k^+Q(%AFD
z>kMKo?j}N>pcW(CwZ+3lK)8k;uy+a9u@)gRPW6BSLAhzl@^42J?dt_y;yKR@zqy8h
zlDhXx;FkAFr~KQkgdj~@Ymh#R+W9Bp3S_Eto&V-<M^Bn=Jj5n->)*PzmaAyT@Vxnu
zu=3~I2y~y6UZR@eM%Ca)%WJ?iThN~f4oGX~_gd7xdCRpjY!Cr#;;TKEUP5mLv7Ipi
zwMxW)Vk<y_<jKUUWy{?2#QflF#l@=<OOO=a1WvoECPGc=FiVKSe(>Lj1^Dv8<AO-v
zBInnc;tj(0>!5$Kg7+U>I9^yg)IB$PtPOJVzet1U|G5qfc@mlkJhiw6HgeNawVJRX
zum&PA`tgx=#~}goJ{@_5xKa%Fi$>;~T63g%Z%HeE?iuINHN4}5AV`Vl!K54gV2xDi
zom-=1SfAU+e?sODAxpcJJdwzen*uf<4{N7w1Ln>h>&?-I3HX4jAV>pTPy;B0d|Y<W
z76K;bw}2|x2T<j(jqk?H`OK{53Da`}ds!gK*+91+>~&SH`Q$rQ-Ss}#in4jS^^W{I
zokZr)!c-6jYSQ_X>&;H*eH57lSDZpq_LJ5>c`V5VKG`cHlBX>^-q|MUZP+D~k973y
zC(7VEp-Y**&^h<IuY^7Ckwp9TpI#`rV?3(3dTo#O8tiFs4UEfaH@ht_LiVfKMCl<@
z{(BvsLuSivcGm#zbjnR0$k`m%g=p>8C%%mA<iLCGi)ze|2aH;EU_ybz_5*^4o6vI@
z>xVXsBa@%+-g|>s&R($1xC|P&yV&g;YqH;}ETm>^FS|j6TZx75ENU&F9fDUKK7149
z9SBJ)P^``dOEuNY$>MCeLpK|t!+D-1dHtL(M|G00vnA4Sv)=Xnx(5OOm^jaKgdUAu
zBBvUd&uaZ`a9oN*v?|*SflYj1<90Y@N+?kDbIa-M{zw3{dhx<dPP@81XnRb&o*&-u
zvNtNjiuuTJf#h1Oc3cHAeakvAfJcoxaRL-ITty)LEz=qQH?Yk;LQ!9vjJM|{9o~`h
zUai^bgAqrl|035N`B-}K2J*u47ab~}w`@W!;l4@`2fQaK^Lq!5{$u~(*h``GP6UsE
zv+QRevt>~u_|Aa&9YycH2))eIS3nWTTuW7e*sdFGTN&*8m4fHGh8JgKf?<M9*7p`9
zQMCqm`ZXQ!1uBqALy4{H75TIcuU9Rbg(;ll89WzvP4l%-e&A*@<PO?T+}WKg@A5GL
zioIWGj?h6HZD32wyv`iZl8dH`gVTX9Oo>#*jvrVkS{oMBq3M0xQI0D(H3U00*G(VM
zsMy<5Bism!Rs5JgGML``3@C&LZKV<v2hLv>ZCXJJ{7i#|%v?Km2jX|Whv^!)@WIqx
zOW4=4(LZ}1vn)>2Zc(&VU}F*rhO{fCiQ7*uGvTbrdkOfruVa>A6oh$3w}R&Z^EJgI
zvp2J}BC_vICkyfP7j&0DT8ViT@4!78$7g&r?=Y8ynyDLn)v}@O8S(Xp)=C>_>>f|b
zRgfo6J|rmm?Y~QBFHik*vItq6VF<DpF{6;4oPAEQ^lD;hm>uvi*dWS=oBjhJ9vlze
zSQvji%t==J1fWma#i!U<826Wm&lW#3Hk~i|5G_-;)Dm5S+BwPpV1prD7ujXy<DbMY
zk5|lvz2v|#&8wWH8uDIB#sKIq`F_X<Ai6&doRjz0w{}f=yYztKzEj)dn`q;7d1j`r
zZ(58Q9^1R0a9!dSHH>96f%H)?_ukK?<FVRFYoBCs*okRbfqLrK+~~f{_c#J=GGbly
zcJaU+rVw&865Cj@ba9HkY&kpL%_I}7P8(uddr4(j4#xhtzEH$!5RXYuHzJeNJ(>l4
zxq}qGmYaRh#VT><^cR=>@nF7Q@x^jWOAEIO4WHRj=3nItOcU<{di0oKX4hr9VhA9i
z#_vNBgeTFP;=K?W=y$f=b-Ag;d@^L#w5skTRqwsMfK_AoSKkVgCK{@VfP0_K!E=$;
zc>jE!oDf0M-s*|^tSNW=3{1x%^{=MJ30o5W&5zKet$h^p;&D4=MWnmUrs{;wEOwGj
zfc-*LWaAvAuy-&chtucMGX-1w2eZ)ntyc9&N?Tmc=R>cmUZUbX`L{%t>zR)zn}>u&
zQx9A&W!JEPI^K}U`^d-v-<@tQB1@yYckX=p*_G<EmaA?j%-D2TtR6PYEWh1;-R%}w
zEXA>lleA`Pt&_~=y<`}ux-F!J5FSyC6rt7wbDI{W`Lg;yyb=eFnKH4S%+%GTl+)DV
z(<a-qZKcT?p+5=@);qA5*8JX=97;c4o{Nybo4w>hUTn?$+w^;#XzG-~nGKQtjN+@<
z>4k)Xn>#^XzH{qXhC}-uy>Mjw8=#2E($ccr@>Q)65>r}j!hC5GUzs#BNSRG)b1^#6
zNLzgRaKNYcyiDaenyJZ@5n9JRgY7%oXGT#q**s0bJS8^oPffHsEVv<Ub8Xi8cYo?h
z`3vcj@HAX<T(rmXq6@3<5N>-7U+BwQxr8)(t#4TM+(ULmEIyuoD#fXs%)`&oM4={_
z#ZJ~|qm;?tDU<8UQQ^V1W@kTZy&Dcye|MsfUC&O^;4X{fzU3(Gmi(h#$s5?gh}p|t
z{&~irhZHu`j9Ert6;(1k)$@X2xR>ed$JgLWWO@^^A&$D4-_aEv5x%Tx2{`LZn1fgD
zZzlV@Q(L{W{x(x6EIA*8&<<_t_dD)2ODXo7(ibg?yp*H6?5BZbW@d(qD1M~qKx(gd
zAX)8YgIT&fd3)8?gSVC*M2?cp3eYKTbT~3-oReK%WW66#V?!*1MoaXJG0+9Y<n8X{
zekiSyp;qK=x^sNa==s+Sf~KjYHJm$#$!Ey>N4UxT**;?YEu^_59HA+d)&7!ahOG|0
zyl9OXVd^&2WEtEk$df9E@>^l~*x{k1hL{5JQL?ejQi<twEo*_|LoPNykG}230HfAv
z-*0V}vnl2ABgAw0C)l1dho3}^F@6ENb7-8Y20*8kgn$1HE%^`nk(<%<t?PJ@n_)RO
zE_^pLbHhGL=mZqhm-KW+1kc%~Fg(+DQ59v<W++2#*VOlhA7Er_sauWOw5;PJ*|0~P
za8v3*t}FA>ob!oNpe5e*C&;MX!#irxJhRIJVpNU@yr!6C*CogA<GhM(nx?HHB5JJ5
zM<C!Z_Cm~Ol~JC`1U|jd?Q;j7I%<I;GpmsjhG!Hv?5C8U4!L~Y{WR`(>|NFmnt9G%
z6VEZSO#0b!F`x18nq2%<XG%@X`wc6b<);mxS@^VJv!T~&wwwhcZ#d+`sT;90#yZ{)
z3zB#_g8q*6pSJ8&hHLZESoP0y4{0uHMO1)6Wng*H?F9us-u6x3y<rubU+*T;KYsj3
z5aDC-X8#%{_)b?VTzLkgo0?5gET?kx&kUI#`<|+vI-sU6$l$HEbG#m~!Dutvboj<B
zYCziQ0qa8!QIE4-`UXw|M^t&yV`aw_pz-8wEC=?H-^&Igvr0~?Odlvsixg8s-~|Ew
z{lSLS*w5z=MeQYFY%&i7@((#2E7eKdq`CZyFod%wKYz*I+JzM#E0oE?%$8Y788`J>
z4_}i(Lj~)9h5dqpT}f$`wv^_<MK69uL!L2`PpQ0?YnUeE=Z2En=}x#E0j^b-Ffqu@
zw+id8Fx#efH$!!pQFWqp?)H8YSdGvDJQn+f!!Pvd(tb>!<s#Ze^(sEsH+>Pzy-Z>d
zDARQ|>mhg3XY$lUx3r*))SN^%v}uSP;7~BTSnA^9hej2~X!<@^=kFa&09(3~_6;+{
zjWy9vN(;3n5^|z##Ent-dq(oRZ6vK?({HJ(easd-#$uQ`(6J#Bd!*}uB+o-VulFF$
zq#ramrQ$sItjH8ntOw{s7p6Y~YTweDKKof;MrQlzDO-zg^H^(&SB)W6f%8A?Bs0Sk
zV%4GAoE~>)J{yS^Y6gOxssX5Nzomta1661R#aB|*!h!4Eg>r|tyS%&@6RSnR7Sv(I
zH~qhEdCYv~rLybgbCAgAjtPCTO9!?^;AgkHR11iNYK0DK0rr<m>KfsS=#ctGse?UN
z>M`DhZ(#pIOl4%2hbk6q2Z_>{NFkXM`jU7P++nB^F#RPKcGmooM15rJszjc`A?vy6
zSzapktE6iG)ypBp^Jnt|>Ehm@mx3V;K+%hUs``(4aRq);N0;OYQV)-F12)kYQh53^
zW3r@NNI&DyDP1y6EXM%#B&iFNdVe~at}M(5Q>iHq_8m~#hN{8?!ItIhc^m9mYt;37
zb}U`7X617Q<^$K8t@)UKe)jf^w&#QJX_m))UeO3qSPlgd!JN@0r^2&5-rGT|T9fzV
z;Wg@jHu&ZPxOJR8Ixlm&ugJu5uKL6gReL>Q$WpY6@3}guaqr<yid4!}x{UC|<7(Fi
zOKtA*)|_2ZL--)pMLu}gCs@sk_lsn9o||K&6O`CoB=ng8+kD<QbtCC3lrMF$q26;{
zf;{6}6eT<G{gn2ypnTU5O!}B7_~K$Tqp^Dc@4z>Y3g~&NRm^fY=tkI5^qx}~O7s)r
z-r89UduX=d{e8#9@*}cW^On1m=J&jvvcX>2G(Y2hm;BXN>_RFkD$A9N`q9OF>FZH0
zfxKVfUh$J-dQqESw+g=iVi2BTp26Z^wR}bQ>LhshF8&tIWr7!;O}T$BQ%vJxLvUnp
zq?AV*vHX;JfZ2VS?B21=kBhP^D0U!VbRuGh_mC~hCS`myM1UUdDjmaSq@pF*O=cBS
z{bi0{JMlEEKbfX6nyPtcQq>%+9n~9>XvRMIu4)~fCNM50fG9-hND)nB87903#ERVv
zr+CLFCXu#+mhd8vfS6I7-vlPhlzg@JLZ046O0nMaxz^jI^WDiIk=>yob}uL>gO_QU
z_^yDjGSf56V%~yF{mdQpTR(EOEa2%4=EjAK-PgBCtqx{Z$@6Z@{*?5RKAN+T8u_RS
zq9x{WGyT!8JRu!!CJs{=DSLi9e{qS9$u$BeLm-h$H^n@^fPdZ&Uj3P>+3Dg(Do1o)
zB{|tJ%B%r(%8AseG3@eRUYGy$&ZpN2<=aE9q4x?GJUk9S)V;F?@P%HaDSGRYDU5}j
z+J4$pOlf~@=PO3%?Lr%7lrT#g{E+X<Px_q6<!mu2-+C*0WO}oXglC9sJxC`wCpIS%
znne1LprBwbnzrQW#{w`k+jDs52DbVU8L;&FXf8a1x07b0>g##GTA40c<Ci>UGL??p
zs)k8%Uf*1LbxplhV(%dvxIH+dNN0X;Uoln&Yn3cy=VCYa$2+?xVusnrTEp{L;0}vT
zMws~h<7%6Fg{g$fl)(s{V9dr&1~2pYpovj!#=E6xjrjT@wEK)zoKqFmyuD;2soMiU
zQ&j!<vz5UpZG87BUkjg$eTp7BrjScB-!#MxtNKu_{-rE!%AFQIXjx3<lsT+Trf+p^
zbl%mX<7K}{!G<bjw!FCSXcm@Zl+CWDAjy2A>Z<l_P^YDZy_s|l%Y-E0L;BROx_&rx
z$YuoJ0rw12jwOVP>(uDSu)WZu^LCBuwl`eb1%-@$HWQxmggK?5*S9bvZ)rO@Ye6@f
zx>;Y69CR~v?rGmlK9JWxwM<m`jId-f&l!{wckvNbb`A+HA{9BliQbrz_RTOId!9<h
zSB%xg5->fLbIcCcxXVi%4J{xY+AiHx54jUtC^SaX*c(qv+4$GRj#hb-EG)j+0d}$j
zqP^65;Y>djv@7UBnQ5Q*ByxTq)J(*5L_d^?qwg{1@Ea~D(6SD;C>F?7NTRur<}2U&
z>)hwapwFUy<bwJCn}E=xr6K&!U3$!>%N;Y0&@E2l#+xmoUCR}YPxZ@rMPr4T#VO#)
z4Me`mEd7$Kf%ohCm{Q&NHJ!&z?S0aoP~D6A^V*P>!HIF<r*%c#YvB76Kkk`+FYGq#
z47p>owCJ-fK0?lFhKCBV$A)gaSTpuI_}&&-Q@X{Rb7c2#NgPlhyi(NV`rW^1?OJM7
zA|3qWQf9xQW^gt?vpDji9+Ri)7x2aaZ?<YoN|t@abDr_n5fjw1@!vONzzjW8@Is1n
zC9A=Dz8@=fCiOSdq@s@>y07Ql7zMk5nD-Q&+;sA&#Cc9m{jKcOb1MYwZ(uPo%U<O&
zEjpxQj_F&nMpJnU=~I7c{7r>rz{r-+_7g;f);3Ot`d#9*_eWVB_M*NtGsS)~WTxbN
z_qpVHp>B1#Ou}?r@ftJX)#KG*PaE%=!7u)i)2lR%CQmEK{^YpQe%OY+)4u4kjax!k
z6G=|Bn}_jx+|?{8;?M~<6-~}iZvElQ$1#VDc>jLSN`Nsu`us+8h}Ws2&bm*>n|QVz
zP3vF0*k^UzO_k`@Dz2Xo80)l-aFtXc;LAVc3J<2L53PQTWy#`!N-BGJYT@*J|Lcd9
z%H+vXXsx@D<%NEEJ<nUhy96JD)QX9vlJlV`jzP>Tnc=KK|AC#I;o&Ds5rYaWvp)JG
zR;~2^0{o``$_3F%McXbJv3XnoJ8M<7i{{o>R|_4P@0zJ1zrr8D_S37?T-zs+&*U~C
z@*xFTV+Lc3DO0$p3vHqIVAGXdxX;Syag?cicf)+%MICkN8;kVSTJzsvZOeKnB7~92
z<FN}qu{k$=?{lM(->RhyMpz|Sd42WAc4w3ib#H=MC1bc|r2-I@HMt!`VHLy8#2#Cv
ze`FY09Okn>v0Ci8IBdlbW0QaU4M1p=j_H)lfi>cEE`lJL4{dUf;dO@tMFUj!jQrVm
zkZm*TbvmtjctKiIBpFSb^WCOt8@-8v`WsnR6%M9?qQA&y=X|Dy-l&&O&N2$|_fj^2
z-&3$YVotdsN&r67;m9s%XUE0LXg5eDc1c^~MrvK%jIWdCi;7hZ!`%JWDzb1RFpml5
zY^a*GZj)LcQ(D5Q#|e(BRh|Ld_P5Ml@Q_sPN5@okU-82>9B$Unzh%5QK^ZyulL(;q
zl!DXUxyuLFr_&Tog90_l<wLf4f}jA<yw{dSIN6QU8ibdYmhoeY{_kMV%<FcMu`J&!
zqQFl-G~XXZKB<O2u$cC#p5qh5Mq`NQB;~%qIa&)~6gM7FHG&|GhUjR^z9uF_=n@O`
z&*tTQ-&P28<NxY;<Y%m-KJ&RUl2pw=uINzAaa$)I6Y)E>{l`7tYSE=mvYhudOo_GX
zOdi-rv+>$n>+UmGa5Wc%<9%(x-)@V$cGtkHhgML#?TovC>32G~D~0EgGv-_t6S!D`
zP1&jbwv)LJJg<UMiz#!v88OTC?NhisumzLZh#etHw2Qc0)DkP0J$n4B^UYzfoG3h*
zaA#)*{Gdm8Zl=Nd@mc3$qv4iVs(7udySsa-B3MFq7xhO|i8E0*q^&LVEI)EOnC;H3
z&l|g_Gva|t>3J*%If0#*d!nX?Ae59P17k9c|4{O>y9k2uypgTBU=-}t2Z5bmOt}-Q
zyzD-8`Rc2>lI+j@x#2TY9m?1*YDZ6}!0%<GDZj7XuCMNo<cS17YT<obF6Y?Uf152d
z=Z%G}gK0qF;lk$LmD9U<Kmp{OeaEF&IoHiJx+-zk#6d0i4)zIm`62$IMbb>jb^AZm
z$5_Yb2SWridD7nCT+OPRw8Brl^9NUx;@MI(etDB~e7*Jyv#aR4Jr)z<r%{yUE5#!m
zU0Fa&J1Y95!nkIOf`t;tM2?UJt|7ZPBJZ`=cHB%aipObq6IwZMT}$MO^t;&1*>Sn+
zRMeWngAjdHb5ZM1XJe!&cEN<?3zAt+$G`tM@6lPq!7%P)AmEF?j+CiN)$GXm`qvLi
zou^Y-5(d15EB{wJ-xby5x9v+&kggPwt{_DLQ9)V=MMM;-(mN`>OAQHuAR;!ffQTSX
zdhely&{PzWfRsoJAT87o2m}%W=fnRQ=k9UuxDWfj-krCs@vS-6`pvoKDzl_t*H3b<
zY*V&8740OeoJvM?z}VJWK>5r9tVURB#1tqwH+mWNr{ffG3~G8~9os2`pt~f%4H7h@
z?vLpf7ki7tGwU-q18LAwd9n9DN+jhT)*I|LYnpsU*4b9CEXv~Wi<hlD_s|~+rg7a?
z#huDOoj7LFFZzFB)Bpzcw&ph%zHj%C{$#t~O|?c=-5n=%XoR@5W&gL;$K(xvOldE>
zpI%&ESPM~YfKB%k{GbBe-Q{>!Qs{Y{g4$nz+!KVd{@lue^ET2S3l!SOoVemFzXy48
z!tT99=357+pVhK&3~k(&Dh6xKKbJc+Z6eF!ELcD%^*5&pTb9W8JUtGMC>608Ho)(5
zN(ufo6`<z%;=ywXZ90{NV=pZy6PVl6*{;7;ah;nL-MLp~U&n#o@qQ*|Bv2nkqf9|D
zFkCQ2F>CK7yz;{!dvSKEsEb9UolGi(qnE^0`;QFuRhD9%Ts)uW@+q;LMF@4lT*LPw
zCk7L&7T)a=w^lg+Y?ofrtfZJ4%WOT{ZIMjKYp96VIWh#=d!w^ozRdhimFDjGhFF=_
zXgARyewJggh|8lyPP{?Ac8%D)`)RQe(`}i!$fVIUtj{I0dHv_C&x80woC%cxe^J45
z!<76<*qQYWV5Kb5H4}&q^6Y}y)_Q&S6<iV*AzM3h98dTb%IK>fE6UqOJXE~nq@m@p
z**6WfNs>VDmu%SZ<n#_%7FBI<1VwWF5<gNUQ)M%d$^Dx-UwgXWHC$3SZ!0c!vZWAi
zvtq0@?HDWF&_c}Ik5%K+GX9GFId*#Wruq5eTO)RMsG3f)??YKp$dSElugmQ>*J|zk
zAbcfQ&f_&m_Q02AuW|APdVCkOj-m9%x7c5)VdT~z!es4*dwiQ#Yci_MI$9oezTW^G
zNr>gDi%35uMhg~a$M84Do^#z1u~e<;e7BXtwe^suq-*C9i;C<`8dv-y8Ie5`-1x2#
zRwk3|IGo1ERB3?r(^RrNuC=6BwLq18UzfK##qk&G;{%9GAOCm)E;8V-m3DXTMk2pT
zwMO;Tt5<8X8Lu-LJbgu{n#w~Tcon%OsoJZl;uLWh;#<16&=Vnl4hX@ZD~V^aW1aw>
zw7Zm846!bo#f6!6%Y_FKy^Gk3m>r8un{9^Op+&93y{yPN2{E<(ZxXK}EmwR%>;^FY
z2%k_6SNMY1$B#s*bEs>`dtlxRqh9zlv4^u<QrNAZ##|A6Xn;pH)Dr>eJmt-tA#kIw
zxAd{l<1BZ(Ow~92#KROI`Oot(G~d*nFK08SS3mXy0#*F%w3Q5l_Ev=tYqMJ9c!p#z
z(alcc2tSFOz^^Z!I40hg?PoZD>z(e3?1KM>S`gK@Bvs?wN+JK-6S&;a<R2@+Q2uLp
zxDFk8VH*jOPTotdko-jFQqrj+6N!A10*t6g*&aoA^Rl*i(OrKWNz`d|AtK09#=XiY
zK8|kPI0ht*Jje3(BPN{Uvyxp<`Mk2yQj*>62`ig(&=F?M%yFMC<p`X8VRM57EQxD^
zC%?wFJ8Ful2%Py^`QEKu`qZB<Pp_M)P$O|2oQ5Jmx}+-W?VVv17EmqZ@5J9-JS^j7
zq0dFXlD-8r20cFIAy4_KyUPG5SjYu#jvlWcTV-Aw*3;j?6?-Ok!VFGKv(6S)s%P-^
z2s``0wnQ6Asw<NaVke(c_YiTg@UIvzCZdkPm2?CC$jVld_8P|{E7pkGE@eLiPV{WG
zbi+cfnJfn>r2bg;1H!A%%s-?)ebigT6P<8Vv&Ut~debS@T8V>uh#y!47YFQV1h64@
zg~}1&xmANe2uG;J$u$FBhLV%BDAs&jZ3=K!Z&-WXY1EQ;;bglc_bK42$YsXc6RCQ_
z4fn1-QM8N{D6?fTAlzZqZ)!faJ#c>Xm>N3W>u4`s*ZuM&k*f3N*yXr;7hjU+DmXSD
za>Wk^%oqQ(!@wqyKJA4X1`*ThuU~;g*datv`|wpbWCo_b81sTPkBImLmfLLGqO@uW
z2%Vc9?Zj66G}j0OB!a(`EaWa4Gs#H^C??M2u)$M_zl6`VXefwb*<OU!oe$Bz)qD4I
z%=P3gO)_@=UY0)kiRnUO&QfO>Ws1h3#B6y~;R70D+d=oOQ%3-j;;Vg{?UB)D4`8o&
zF6gvK`?T)T4t^sI@Fizo7eLL19qf3=;%=0FF8y2qJR9&jl}3mvY4{BG1*M(c`#FKw
z0OCXNQ9CWfla1%na%*=l&*w)iXZ3p7qq0>Cf0gs|rw#IAIFj|Wg?}7j=RapDQFF}T
zg^7U9krsrgaknyyY+Xl+#L2^6t@>*@FMUWhRZVHgB-3%pim3z$iX+0r71q9e`-Tu_
z-3;o4S2R_u`Em2~5G0qgf8o*nil=m%t^RK4t@P(G=DbKjd^hqs?)NU?K?H+%7bwgy
zIOU>)#qfJCBN?{m8XJ23fb=e-{I?cDqyidB`*jm}sxN%`<RjX=Cp?wlP<muPjiyV_
zi#=U)waO{hsC=Kb;C5@T3G%fd1GsJAHHe_M4;{0J*nKPTM$WtD%rE|tR)|?kg0#Sw
z@+W)GkJe1OWc9-?j1G?O+1;#HEnm5k!xs1!iSLrTA}3;r%^;=F*P9U+md#n9L82~T
zh?z|5^$(U8G=Lk=9=L=V%<3j8BI4M~n4Wnfa|(>k@=QVW=oOm|3jo$d#dd{Rp(akL
z``Edb$wfJLBYxiEpdjE#-ot&IcUy<<y@+F%W^`mJmm6m=COk+$TZH!_YBT}EYx>M<
zlQjPFue88(aTB8K4$3W;Fy!HE{Z0$D=TQbP{L;3RO}<g~0*%<e&DM9vM@!+Z%#(uz
zLituu)9=={Y4-y*GJXB{x8rj@n!4-By_}0c&|mG3oRyBuQZwC&-OijEJmC!JJuXKJ
zsT)-lbP?$`8CfGZJvTqwqr~N(sNL_-MB}}&B!FxpGGC8C=CewFdhL2x<xyVpcu`Jq
zoZrqIa-i<4_i-aKRqo=;eCC^X1Z~2`qRlN+Paf_5{cxK^E7c;$1-*bdy};;q#=xuA
zeCy`cRe$1Osqm$fHMvf!2FJvzA|2+hdM}@5qMalqh!abdV$fGb8?zLl`CM+AuUXwR
zbrUZoucFT@JRFzsL=`q<Ndb{Ocn<enohMA|phx7j*0l@w9H2^ZrkVWM@n&Iqjrd3h
zPr7HH&5tuc^liB&`0ekI<71;(%YiIRnE|+08^OeWTrM(6*x5)@zZP)bk(koWW62x`
z@VMgg59_g8jLDLlb{B4#?==#&;nDl#8@P`R&?&A}%T(_Ma#(rNqICoc5|ne?HBRTS
z^U!f(Dc0<BYyscq0O$Ch6%>$jEt>@|q%fLsm|joTYEwrJWINL$Yv2ZCE|&2Skte8<
zJ`FlxE#ae5npZb|=4WU;MTwimy#A@gH~n3Jbh#)#?7_YM!?a~BDyTY`#bI8G(tkkf
z(8f`i;)=7q<pM{!l3lezj20MSZ+wRL8hBa$G5t`+2*@GMEj}>wWw{$81K9HYqNS(}
zA!lqET&o|+`NwkvD){-w;7TxG1B`2<N}*HnedWo5H>k__`B0|0@vV|)DzW6b0x?#R
z&A17xML=5&`YK!YhaQCjZn`#B(GxTWS|2u4`^XNE1Yc=V@TdmVy!;`RvQmi=bp34}
z&WHB?ope!Q9goMO7|z)zC$(e*9KU!=ot;wjgLwCLvRxbz)eoOi@%T)0yN8+(<mjKD
z|2c}Q;&Q{CR8ah8Vc&lopR+(@px-}iW_tc3|4V=ib*SO*kq`VhE*egJ;cR%Zjgyme
zB)!K?-(apUnQZwb2&EDR+)u}bbf`5urP2g6rKaR^z_!!$xmJ@tK8w_lYxsIwESk%V
zvn%OP6>nZkWBeo^rMVO$v&ESv07X>cE#J_h7|D%?wy%|I-xdJxllXHp>7ovm4oyLw
z(|=G~eJ?5+|2)T!`Bc)h1Y26{E^XMpN+BE0M?AE23{xrR0N*&nL{sE9#QqUG?T7Sw
za{pAM6nl4_Mri(VS5khL=I00_+0K0Wi@)BJv~Qd79opz0Q^<O`yB+q?6SxK<M7hz#
zcB*q%M|-#CPW6prZ3H;sg>nE+`1$Ot+IaeWtF7S2fT2Osz`(#4Ly=?PmvK4))hd6Y
zs+HDx^lK>&&9~lB5?{SEjkfEV7It}brmv^=5cEDxs8NR~6nDHDu#egCk1I#{+jhS=
zyP_&%sG@eKvd<}*TF;X-WrO%g`C0tzo%&wth}$n_%8RL!GwPqnS%0Y0T#>^hKA=<}
zorS>UH|6`+S~h!R#bEfH_#OMi0Er!BL+ctSd<sq`-~zii>^*u@i368>c$m~lEn(vY
zzd1EG+8JBW8*vIB{p+USJGEIf+xHD@@K<PTBD&zwvo!9d5Z~P9MexDytn^*3u)}$t
ztliIt`LG!{d6K++ob9y6fUe(-HlWH@OpNwpqq?TxMIf!{p}vxahA@18R;&_qvW@sv
zsHN5D%*lSjn0HS`8)dmPw`ILq_IX?&X@)CW_4${;WS-E6JBN@B<0(c8?)=)H7YfFd
zu`Vtx;no?BfT#X#v>hkBISB+vLEi+Fs~3(s55-coUe5n+!TLQF#cfpM2VO<1L-$p*
z_<;u{!!xh7YL?6$BXG@^_FY^g9OI%?M0O6iz=D1dQqn-T);6SWKG;6@jdWHXfgWC|
zhg^tlGY0h&fE_&ea<<q(Y;-WIPv?%<!PGz|P3vXY`a!NIIsC9p7Gs7z9!pPg{IIGJ
zMXAM84`%~D9d6RvUZRO>tpm{qU4&m`1Uh~IpoHk4`|5&-iXZqt8}P6*Hvz<4E+g)-
zGvUL}0BHZOE_DBX1Hk1T2}}_^B1*@^cm^1u$V~vrf4d=<aPJI_^JwT#uAIr9`rnBD
zKQvH8o(zzI=>kOQ&ak`uGh42IzX1T~9w7ds$^AE||3gE`Pu9Bp+388*Tf>&%>3823
zK|A{{o$Ah$G}=U{6Ph&q{YvyACi-KOR_kG6e3X3J;Ul3>g+Ei@O!Siu)8fURp`&*R
zf|~2n$hDVF>boWQ5B$z=eRZP)oHsY|<|g|vCPq_Al=V=&>m6q*1^=LJ&y_S46%^D7
zg=z(4V6_@AF7ZcDCpPCRrQl<f-qkw_cPJ~?Xrexc7#Y{L??qY|_Q^#rItO5#e?@O+
zYUUDjMyXC_V!y!i<%9!m(oX_y<0I7wr(W5(h{H3s9X!Ls0JTyi7y2z}dc$v$Tlps-
z!K97cti-6mxf@;G<*@Xf@EJXRBYc}4JTnT|X4#pp8md^VNw0j3nn(Hc;i|gQSMkyN
zBeny@Zr2BmM*aJ|X7=}@53~9>(UMlzJV)BKW9eH9>91!7a;{DJQ+h{fJ{!a_s<l+K
z-}u<2SbCY@wpz_R&7}2kl}V^QiNxkEm9^5$i5=Wrezg?k0k<rmk8Dg7l`C#rs`b!X
zEXixb@7MXQ>5mV(pm0~BsmzCp&8wRp(&J6@NYLB0Z~l#YBXeN*4s$d`f+CvSOen6z
zH)EO?N4MqQ6vta26Gd;1!sRCktLR+xJ9ISsPq4G*csFU|Hhe3lp-fZu$?z+|h>cQM
z+V&L|NXz0V;qm&jBXw}O+@D8x3A*h2M+pqUfROQ;r0Tig$&EGevwIvDLl`les!J@*
zBLmZInal<%@Q93GCKKCZOtWp<+lQSlbOs8Dt)1MMI`A1*G0o9zkWWSi>`+7Cu}{Xv
zOcKftYQjjU)3<#zd?OTWvH=eeHby4#xt*iWko>&_GrdXw5gWg`?kt7aR%u01k|`;g
z)?zHwM#{VOjOFyDP|}9=%B}v>B9)XHaGvoCH*j*z!T1_i7C!t)U}>!NLkX&c3&CJ|
zIYl!slZF)zoSWd&l>%Qzf1$_GUet<-P^Ibqt7B2%nQR?{k;Toc9uXbAJOw)F&ktJ*
z*9EKg*9p<#cl|2-e8k4ATWOwwNju4kXNscQ24e*s0S{zAE`w_1F7GAtfDM1Hw<MJb
z6V+6Vfpq^>)<QY;!cuC55hWD2D2QK~v2Z$5lqe};mo^+;=isF31vYp7McMw0Ksu9J
zZcUZCPYu#;wvFqx5w|I?4Y|C#e41|2{ow5>o3GDoEo8Q7W?rD7S8UeKS(~*LH4qZo
zh&L+uZLkr!Wbp((sbB?GYSI|m$)+Ktm<-bXYxXV|3%&J+2v$*qZUzO9WZS4j#hF}_
z04kIXUrm|Cew&`WQS0B_tmb_-dyRKZU*!u_#br_>gDb}vR_kk;(-DyRs)(E%?mKgT
zMAYk5>X_cz1DqUec|EAJL~>#KL)@!0>9eg_At2kvj2q4Jg~FapjKhTRW?ZO<ZB)ya
z8OMU<)q5ki#A;#!AbvwasBv|qqsX0BW)rDLD;%#wMfDh=5xKuQ&1u6-d+tz?C-1#Q
zK<;chmTdz;&jr5=nyxgQ_hrs--i0kjLcCP_k;?B)tEw#56js6?qpe%fh4EQoG}SEe
zq;;+Y(m6*iJ8P^{uDC_PhG#iH)GsuvgxoGgIQL<6*5tsrrhEgPae8W5cScvDwGd{u
z3(DKNJ>{|L<a%yo2gZlP)_g`LevcwNaU!=rrWJAgx<Bz%WHW3$NYC%~UnKiU+S)3*
zY$_uO2C>@DoG0^KfiePHGG3QQi^vAl28}QMU3o%5vR%k))5BNrkms4|_C+83hXf%$
z?f3pDvfG-s6ivF?>35g<`BcectfASyDp5S+Qpy%DziG7WWFCV+_9^~#VjLPF>_4ID
z0_@4bCo6n9MN?B%?sCQYB7PUqS!G?*;dc@O>ZP#ijHq)n&UBT2hp2Bc{oyWDH;E{c
zgueJB6OsU=)K~O5#x;gG37)sN2TF#7ZG&>rpAI}?{pQUIz?S#Mm+oc7r7ffC!R5J{
zQg^f(2hn_QKGBq@)6dY>eQ16s#^x#f7@HVW`66QLdeRDu%bFI-WUM}&zj)~763$(%
z3o4TbWNGVh`LBkzN5yx-%pgBkobnFN4uZ|d;@b+(B53|@ld$a%YxWGzYZXXj(S>pH
z6Ce<*e_=$dUaa14Ab|Pr)~7wFV#rcOYPT&Ax=Xno<aA1I@>_ZKJAbDcb8n$r-XO}9
zA>;i?2YIdme}t{cOyPZ7CuNS15XBKq-7973WhsLQmCB6XJFbk6Nl5{)6DOeqA?$(^
z_I<fvA_i(u36H-%Iu?16uM_~Ya%xGvhFN}TLwn0G|9GI)DLJ0<X7^u=o<g^t(2PHs
zU|aJAJmEswW1HnYU4z$rXyb;DtUjF+87V@)nZGg;@C+=&3RDHUCOl*>c8Bc9BQuh+
zOkO@*qOY&721nLlZ5d${r+RAU_5IokdRYI5)9to;RdaiF-{`h;s<PircGb035tejb
zR4CYEHn-OVy+(d~@K8UUFY}nzM|nbV{T*QV(*Cf=yO7lSO`~~9^Yo5aeK~H><6g7b
zZlDVL+Q@Fl`WLIbN}1MYN86COAiF1`M96d`X$}gM0Kyj7_Mg>O*{BO2W_lY@(4nmw
z7*J2gxg}Tc$L1K;Q75Misg@?%-XGK$l!6%173%(~%c@&+U=-trjLChz=3~GLiWYLU
zNjFi(yy?(Zqh`eQc{nm!oiDsam)>oSO=B9f&G|YLn(4+JJJa4e%<!A3Q9Vi|H*p;0
ztG*uCUODwfqq<nLWQzkp_VH6NzJ|VKr+jMwNSJGRv_IdU<mQ)YDTY8>ub~TlF3Vyj
zMGg2^rmL2l*P|&J#xUzO6%9;?(Xvw#`lg*ELibcjyyIr}lNsE-7&(@^@6AvA5`84g
zErH_Cm$)I<BhK3ZZ7e6t!8@V`Ypyr?*~*rA4A(3HroJE9ftWnG#flhWi%Gf6rdzbh
zx|;`Xw>l;PhE&bl^D#K`26=V+WsXi4eDGO{{9YF5%~91Ad4nb4a&-TQ{8gAt|1I3L
z*qG(*mO78CE7THxhVqVvd@ff%=^u=~Dc86v=ckkvr|_=gSCy))4y(ND)Kj3e4vKav
z<43an1FquLoOf}0<IQ^RGZo14;^*8HCpAJugj!8S%t=qjO76A@^GEX$2siG>OR!Av
zSwFoKA+2d=!nCend?m=@D~zWZGOW8Le5K>=#dFp9de@8BMvdK?xk3>EoX=jDv(q6!
zF*W_XH^MF)-hLax3!6%I?b5B~H=ny)_-tb`J2+#r6gVe-t~}<JO~QzOnqVWoAj@s%
z#yAtF-f(`XZbQ}b#tg#fRPJnPgV?da@Es6aL+|DUu*kb2Du$hZb=Hr@<i+h_*}xVu
z`4xvK)OC)!?T7)={RPKg#B@5V=)M&$<r6@0C@c6_fxbB;V)ty%h-FsKcswl=Nc}gV
zvmY{-P-|~?mq$%$<o)FB=-Jfp$j9Zy)l^J=5)Y*~-i{Y2Bvf)&D_iDFc0XU&J3Uqg
zU!-OJCcLJg__Ekv*pHTR=+VY^Vu64d1d@x1lx(H)ndCAO1QC>fB-tUABYi~xnw!Sg
zzMxaCa<ah<C<7G%>AF~BJM3*lH{LGEZo)P$@i8d>7M(plKXD-Fk#5cdf}2Ro*rkst
zKqf~9t-|xQFV-(tuSzaUMI>fmRr@a1u{EYq<PJ`^HW0M5zfdM_t9)xDz!axj8Th;i
z%Am^LYSG5YhP^$_3*Jbos-m4mv@{TwI{ZiK-Tx9=)hR^s7ZfSUBGxp^d}=*=#9-eX
zERGEzc?y(WjmBMpYF&3yibksQ2zn8IIm`^p0h@9^Iwxi>A5&lXJ-o<!AiMx1Kme7A
z%VX((=&^TIo}Vte?x$#(y;i`(dHE<X>Ga{@&boX<g2aigqSN#5HC(|?H<6-|H(5QE
zZYrKPQs;iiY5H`{6m?>&wsi5=;8~nD9PoCsxN>xiE~gA;EBzMB5LYJ~XP9UE2nsg(
zB<`$yTu5Obl=*0cD3y{3hNY;9*DIffqYvQGhruPk4O5K}Q;Oli=iR49yj2N~$Dvk1
zgvE8+<CG$IYUveR!%ruV3a}=Kbr`eVh{Fu@<q6Ju4J|76*`A^f)Y;~FRE(n1=rD;b
zP4#0A){y#OKeViSr!T`kdNh4}x6B7z_p=Wfjq!W!E^O2NU0<p_xcOkfroKWM9-0hE
z{2catXW%?!BrDZC+e7E;*ALeSw5G*fn~HI8IvwWBs2S1w>kxdg^MGIkrE>a~eI)xZ
zu($t6j|t5#{a&W#`AhkQ`-CFBQ$WY%*h2}PY1`M{{$GZ&r!e7A?CNm>&2f_FVe3fE
z;s*>Chxd97%dDTVF}bjYfhT&UVeK6qj1Yy@yQ-@4k&cmhw*wE`Fd&ZK(4n4VyWn8!
zYoqBRV86n(kdjmTzI^yv><1Cs72_Oz!S8AP-vhPAsmr0`J08TW+!fJR{@YheCzS>K
z(=WAMYp)H&Q8bJks1vnC)=fU#nq->{k$cuW)7v3G)OzX(k;_jVF>00Orx&dPse}oD
zSGZ=qUtRh3BrdgIS-q*ngJGiYV-sWNDlgQP0cC9b!!}|CPQtn8lW|+4ZzcsWi|lVR
z3o+O*+&o9p%0Y{0b>@#N%ZxkKp5W3sZw8H|-B)fM-MQoFcNnK!Y#Q~%RPbR?6XW!S
z1PBk7DZ8oMAl8j>O_Sc=6fKxKHaPyk`?HX%&toc8-e}8=XOd1cfn;do)AQ;yQ4KU%
zgHcW(4{wonKb*xppiWl6zWK0MMDZI<_>^hdcQi4%q@{ld96DBB8T^Cbptu1JR*5LS
zSAL=Vitk+wkoAJHe1mI|UqKe(VQs1*#~RdR9VT@GE@s%ZUp=9|>N&hz3wud+tiiD^
ztwvB#M#<8JwRQyP>07UwD2~ZfwcScAPSSr`jia4Sv@)jlMkP<zkm0r1@F0+88seJO
zHXJ>rNEu-dJs)A^sSsaF1J|r2zu2r!v;<odmPV+-WYM(9N?9vsu*rjgG_q)mQy1vL
zz$oDp)^DOLv9EV|s%NfQ9bVZ)I2%QR-C3toVpOq?Js7yI5u7*g>9%;7E2x1n4o7>`
z9KKxKGtL*-g*N#x4?^LSQ5+i%?+^HvN4`=`z^_(`pi!U2uLJeS;IwrKkdLz&#xB8e
zovxofG6*vO=hi6X6wBzzQ)1kAT33g+Wv!i9Iv@lm4<Th?8d|W74}+&hwnP4G56$F?
zbQ-MFL2})*JJ9aggD*i}il0PQ{21jgGfkt<Olk?;UNFv(3!e|DfgppL-hxFjPT1wX
zda~ntyPbu*$(2E0liq^poF<-z4;4#v7)7>76@HDZkg!OjcS>qWR1eK?#5RSML$IyG
z2uyvO!4AY|XRKqWe#fzLY_1`rmC8DI#D3OY+l%QnND@|4ILAr%6Y-1vY`DRWtI2l}
zx-|NHf!ClW^BQRw@MS-{%umF`h0!GNsCf`G;;7r4@psYx>Gmz-E%;x$0R;bcQ)2vw
z%wGn^N2nVpW&>pZZw$59lUKiI0uwv>@N76z@n1eXVgc}%45#yCN_Ic`^4!0UOm`=F
zf<9XSK=1FEk4C1g=(1t{-~SEPkN#&XG5#e3%%L5m#He*Zp<?;l?)ua_dLGRubM*qS
zdK~xn2|t{QYbh5l1{J!R9MRpl#L=N;0KY5v4{-pH|NQ=gz<&_<{{R6OvcmZhrIX#u
S>zhZjy{%__qvE>DqyGYX>j7;5

literal 27733
zcmeFZg;!M3_cwfJXb@>pDFFecrBjd)gOu))?q<kQKm?>zK<Q9==*}Sor4i`{=@?|_
zA)Y(>{e9Q_yzlc5ylXvox$tuCxhM8MXYYMJ`*Vp<S5+b<zD*1O0O`{w3NHWv2MGYs
zAwqnx#MI|j6#zKWKUH|7<vX?AO!kppH*n3+p;vFB{YH&rC{IdTVsx1mE1h_v6GR@L
z+X7NS@fiQq7YS7$*MqxOWt!22#z&~&5(;*8Sc}}#FSm`*`*^3qA_p$#`Bp?jk4Gtm
z=26o<%tz^GF^oz-H1}}}bmuoQDfOBS+OyIlvznt9r>SU3!CB*Am+_s3`Lm094P0<s
z|M&X868Qgx1YFrks0>pkTrK=5C6~4pEZi(E<|_PW{9#=c+`a$v&+x02TAkY<i_4_d
z?xE0|2mlyWl35*T9#><pVJjcqef&VQyrt9nrxrNnp_M+*Wk%C&XXR~Ki*Bmv<O#}T
zA|TW6$wAMEzgW4j5CK?8mf2%w;;F@nx<v?ui8%m&RwhswcD((zEBpj2HQB(k9D|#O
zgenj~-Q?i6yN#B=d;O<X?4wWAm9|g-?k*5FQQpZIO*jq#3vJn+@k}R9I3`1ZO!|B?
zd6|A})u9_A3c@xWQef%dtASxuUpx{t8=r0qB@7!RW8ciQERM9VbR@q{3Jg6;d|b^D
z=V6DnH1L>;hvgR(Ub+AvA!n+UQXI$(4h8`D*&Njz-&%uR%J{R&WnhbP-`|Sh$-4yr
zQ&Ib>M~a~{U>SJH(h3R|u3YeD-pBs-498LsfQ#Hgp$PwuP5rhO>6wCpwk-g!;ZI}7
zR=G!$l7?*$ygY?HvZt;w2-*?@@UgPH*?Tl#p{)LJ)srGyd;tC<Coh77HJuYXua5~<
z5j(kH?*{0QhA41gU_(5GBiR;ug5X5pKg#cylM3MgT5n+yha5Hh$wmh~p0%V-4iEc@
z0XC)UQC8qX<nLhRq@UM-p}T<*-|*PgzNvEX2R<eq6HlBdoA$mjdVi>+A?LG~YQ2}W
z2yC0x**Ms6%3Gw{c_>iilQ>FgdZtB?b^ih|lOk~sVuApfL@^4&F2n#*0e6pr1HZDS
zH!w&5O=k)9ZN$vi2BwoA;USuu{AX?aDGjMcn`*eyzK>zTv%8wwqGlhYdAGw9EpQ?b
z9&6c7PMqXOj~RCdum^(KdhB#%Nrvylod!e9vY~ZPz94*hui@dknhr=D)n_D^_czx*
zuu0>XT{~R;@iG75F7DnEa!oLG?_C=5I?;lv8!qG;*u;>ZMKb6=u8C1_4z3$<FtQQb
zh%&?Fdw)?O(X(qhsV?dMfthA9es6vHcr=B+PUF`iyzqK$4eB)0fkEPhjS_}4_bJC_
zL!UdY+!9HOyH|?NlZSKumq$AR=OP5~xyP+|)1a0BTz;VHI_!~;k|nIEVr2Let#=s_
zWCoQu`2YfG8fg~cb8n7Ye$1kOz0RrM-oh~YH{hV&Fz!%kxqEeS>rbIalFhi(SPQ95
z4Ql#M5*wgUO%TuV-*%~NDAQNlj8+s}bD(-5La-NPjaG>w%y1=v*W)I9_HFeW^f4m!
zs;p4o+UXiTEw4-B>N#35(G@PfgPPj;W|VF=JML}ZW-SERlP3n86y{9BuHLNTGYwF@
zKID8<IzUmE#iAFUEl6UpQ^5Ku<)Ya^M{A4<Ns@DZz8t+<`R%iZseug>p&4K{gAWX`
z6C!Yc9GM<6QIlj=+zZYj%2%t043X{HpQCagNo<ax<v-Ro4jO16Os2&rEFew1x6z-D
zZTcP>CW#+Uitoe#_*iLy+6})~=sUwCd;_|pre9Sf3mgmkD&Kf-?9#ITcomX}d^m}8
z7fc~X#y&ojUW~OKXf~N<fkS|QYPC+JCLCweSQba_yE6J@@O}OQhzxo(-;dF<ea<}Y
zL6SImJDTk2097k7&iw2bz-0F!$)qya?H#a%o;E@i0Jt8;m=V*Z>m(wg*suM{gfTko
z$>66@K!>@+QgvqFhrV@-<Zg#ojg_2-ZkqtRZHA*dFbyjqb99I|bY_I!1jvy9a2^Mh
zJ>`$D`RT9bF_j*foPlo_ZfM<m7q^U0K%1UxtJ(Nw^a=x?i<zOf@;?6H0O5|X>Jz4@
zuKl<zBD0i`6JMc+YWmq%@aef3BI1P$qZokvq!|<qb~U~IJUkIluavs}@$IxE1i~GQ
z=x1%RrG$#@ciL^^qS9@P?GNmZVXP-;`V4Otk61}nuFh(tVN1MS+}$3vhHzY+*{M~i
z2_5-WG~q(?+@Ipb3T&(*3*gB5$BB9>YV|hGuH$AAJ?h;^Tfv<@lbAM$*LP0vmv(@5
zv#D*ebC?~AY3A=Ma4PV5b(>F5Zgkq$d>XT;omuLG@sZF^f0#RZoGmCV?7geMYIS5j
zt*N+e>?{rT@VASoN$N29ZEjKThbp)Lzm+;2SPp8AM`7_B@%$l)>ixkZ1+CWa)S!`d
z#sL<>sR7OqxsZgx!gIY9fGN7mUE|Ls^uNy<h_#h;7TL62bWDo&gY!nX0pQ&<02B_~
z0Tl__Z*WQdy}-%+yTPitumh{+e^0R;fLD*43|RDkt`0WW!3f%le+vv*M+yKZ%y{7M
z*hP=kG<b_0>-sHxJM8_xMU1@x7sI~`oS-_xW6)!P7j}uue8JwS-#Ej*fGzlY{XeUN
zPZ^GeK)ryQ3%t6V002q$*M}^N0Dr{-4%dwikR9Zo=yEE3vaNA#D-Mw<2~HE+Ozvx%
zU8UO{5_WIF*RhkA?T%OCH3=9&FU2-3hus|08Sz@h$BX@W2sV!0IIwqBn!xka^KE}o
zOFcuC@mttduq&BgTjmR)*)_<_t?$*{-_!E=ESg8g&o=C_BLho|pr4HV-_5|zSRR{#
zedF@K0d|Rg26^|Z@I|8h_Ox$~ecWh>c*0<7XKLg*Y4wM|<kI~bolOJpy2IZV<bm4!
zjHi8$rypX?^)z$0-aLXiV6r<0)aEao|JE~@7(W`C#g64B^d{t8W(PTv(5#pimtV2$
z|5bPmI}hxj-T__wxctzY^4NLz+`-<k!XM!B-@*O>z?}~M_xI_)Dxkprw+gaeHy;6(
zgl5>e;Q##rtmEB#9mWi&z>a|&sV9u<Dl-c%1IRmU8KK1AF8v;1*Vw<dC_MiTmKj`Z
znc2`24oR1HWI;|r=fN$NnY#j4Wox<5B7`M(<2EV<7`Co1!byHE|D0!}MOIQ7z5%+(
zkqnj^7F%FIrpJVBFSa5)iwle-h!+xC-QD~u^~Pi>cLgYIwJDL_GcfPPca_ToN&TE*
z>-1;qQ9mugmTn*gDW~bGOU>y2zOR&h>}!!iIsJa(NB%i1meA}SiykPdg&!nllVj1k
zUSEOBg`UZRvV$E<R1<g0QP0N4S}#F*ERgO8X%Z`!k6@4o1+oys&vVDuE1>b8D!@SD
z5b8TMdBxsx(r(u_v`|R0AagP!TyNg3YaHa<(06s#MM}6(K!cQz;PIJO#I|rGC|&+4
z{|3zbJ8Ki&Kj{Gg!mO+hdXj}PiK8P<<A7iNo^KYqJlX7BZW|wroWIC@zBCwg(sSa{
za#$f4nwB_%Q48FQ^fWZ+#?8Czp(}D)N2`lf9ASP4C*^HDJV$PyNXqlsMF6}8T}K7W
zKOeSUggJz4UCn8FjMR*{8w6dUjA)H^Q&LKwN)Oi<)$jyDiUS-k`XzVcyG`hWcSdw$
z{nbjn=!rLUB&}Ns0tu#a_v<ozZB@?#X{vjvSN|@hy<hxX<*X5i|Ev>0c7p)t0}Yb$
zWt5Ab2|u;OT{v6SL3&eH?W`DUP@Ce~m(s&=Q&kkA4xN2c@qFN^hx5hCUB<)o8s-s<
zs1bU`?OV;=!j-i2%hbvx!xEWb&%lUg9YV7mwce9<uM^9_jmrwmucLFzkq&4xA791P
z!ueWy0%K9k<gq~O?h%R7^kyz>E!uhd_{drsNj#{NVnq_WA$EZtKf=(CwbXLi$Z*WI
z#5~&BjPj-`p={aBWo*5q5d@bmxLdfj0-Q}Pri<JMu}TKb1@7J#yfS4LUQin}$bFH`
zYK1bsq2H75j0O;Va4S^v@y}r^6@{nypBF}KYM6*Dn>o}<6XWZIVsjHmYN}HCgrWvi
z7)KmwY$N1XE;rHRGk$GiY6UwZO~0n{7%H2JR)<F&V3khB49i}8LC%~H5rs8GstA|0
z;PoxhFYN}H2QJ<^fT5wi%%%7bI>hnu#nJPT@%?)?({j^E@Udgt9qVpB4TRICloK6x
zla7r*eN8OFa|~{`3t@NbV{jW*MS7EN8nVL=4WN8Ip>j4!@v;dg{i`I;4-^M9H%ZKh
z<V^1|O?U^MwMY$2@|&3A_IS{*{ATRk;*1yl48|>)lx;y1)rcI+K4&$|hosS_&Xzkz
zcvZN$1G>|~eD2<cWB3x?aX{k9*q_NYYs#`3>FU<R_;B&YK!@j&4?z)+v1Q;BVHdb$
zcYCMm-I@}6vcSLA1IRr8*g%-bCs3I+q^MZ-+v(#%<@sD3FhFeV#L<|loYm7p`0;xJ
zt)O9>ey+MHPfEWRPa%}&562>}Mq!zC#Aw|21T(T7O%rn`wRTOY_MCfj;vH>_jmL*W
zgN$AWI*Er7c4?L-6x>9HI~`3w#vZQj2*($xuWpwo6HHD`ggT7nyaPpKDQ%4VT)dUo
zfA`pt0&64k4g@{%fOQH;DrwjNFDojSSXY0pM7h_n#Gwe+RcoPHn5$4ZEeWT1d_UD1
zouKkjq(P0yHbRZa9;3`?K=YY6O>OKK@2UnEVPEYPBqI}QC)?Ai`KT^xRO9uhQ(V)Y
zEEZiSG1JZpq{ND4TD6r5sXrZsHFjVut_c+bSDSH{LY%wJO4vb|8y8*~ZegTWwdL)*
z=(wH_+u=6P<Hkr3*H!Yql)0|3Ps>A^b<)c($2(pR`R!lcATnb}s>vfD*@td1hsfBJ
zOC4z7)DO{6A-^(uvck)GOQ6ODEpPvIM!1kjY$ii(V4@Oyi-c-G=icSA&04h<@Z79d
zlP)<&*StTd9AS-D7Gs>%tC1U*pzVFVIy|(vkk7#wW>b0E5u{hqLI$(<IxqZ5Ps}jx
zp4gfqN>+Aclkk<bRQ6Mb(sq=^l_2b$6YQUpVTJcP$ONrPF3Z5S441Dik7{FE^2RZ!
z)>fhJ6IwE<IK~gnW96HNrU-*k1k{%d^edU&xMg!6hN1<sS_?gk)r}&=TA>vy-_J(2
zlpg~rpFTc02+O6(B<|Or=@WXA{Nj7AUPZPp<vZ`b%ZL5b_G>j(7g0;<jVZEPD|W4M
zNqmkM1@Vp#=cORU&-&w2<erkTRIHh4-kH2~#Q6CxWJp5mFt}wgY%h<cn}jZrwDUn-
z`>3gd#D#qqOl@hb%vr){J?1ppMTUMJlVuv=65OHk2jSDq9du~u96cVm(Uu!?=rKPV
zw|kY)>+-a={A4$&8+CG$^7Hs&Wh}OdOPYO0vy^FSUv_%>T=Z(472LCXA5%hK9yJ~K
z4O=B8tlpdtaN;Sv&n41&b~dhwO9B85@_-Fm+36NlCb32$@&myOsES43YPM4tAVQW;
zBuiw%6~xBp`CV{kTMEg(er{P+@TN+Q$b{<X^5F_z&GDhEtdp4saS=nGWC;O|ci)-O
zni-lH!?-O4;jTQC|5oKGB~juxtpxaF0Aqioe7X)!vS|nCZPujnZoCPeMd-#-eWFa)
zc+_&zYwB@v>-E7Usf+S)meY}OFf0HY*w~mD_}8&eOn-N~JVRaDpSKs;YbI@!)|i*B
z83{@Tou@F-*UB_s{n<e=anMf>2dV9tWTaOfMSvTR6`n$i%-BGw#i9&*lUT6<f&^4A
ztLa8bO6|Ky39F>|xEG365z-gJYPnMJ24kGGTUW*TBi;usM`<)&elmt>`t?=GYPu#W
zM9yJ2(?@jTwb^p|Q!#QWmA&^<4aJ-He?6NiB&}E+pse4=<@%)uH3;^)oE&m()}eb6
zw?$tyyDh%ywLXJD9DYW*4W@_0$UEii6d`_DXE{+<E2iM?z3voYuPJ<a;bvt)N10-1
z1)-N<gbA^!9@g{iDg)u6nSmlF-)EPly8KXGx=k;Cu{z8d!CoCsN~8Rp79TjDg?RnJ
zqwRmPv&h%#F=K<m%v}7b9}HCGEJov&UG|X7#2k&(R61#~K#azMG?T$y2?iP9ItByY
z*fs%Tvuh3^KusG)O^VENQpz;euiLxq6~tEwuS_8qH>Y#HYu+%WCD9Ds;T095)Vtw9
zH0=kSP$+w7xVM=UvwQVkoc3!XEekga(FD3(b2)LYpvv|kxtdC-Ui<XrAhAPrv~o8i
zWv!oScZrjOIAXarc21O{RD|~xP!oh+raVsZKK_Oiee_L-Xko`C!18>T&gGr1iI4I5
zr0L~~5UtO8b*akyv2@zL`)(a(*Rx)2#!cxw$ES()vd7rxYp#)AGsmlwMMLL^tCJSY
zYs^m!-3^{+Nh5zS=_4$V;+g5g)`RDN0@15qF?M(P^e{i&rrjR;c90fajBT0F8kxYF
zGJ;mPmfN;U)l{6~`*-?@%@|sb;-wkWq6Rd(F_$SWjN^&+(|p&i;l@77`Za|;Z-Sw*
z9u2Om?H;490)RQ{NQL-z<L<GV8VlZLky>s?FI5gabkKToHaC>L9G@8_VBVt$)q6eO
z)a-|#H*F4DF1`MnG4Du&FIXqtbiRYGhtF9A*YC#y*H4l7W4)|NffZ?+=4E?9lJP`4
zakOg@!v)GXYgzLy95GK{@}za+rKyzqFIq!pI9ot9f+QWCdeRWZ7c(f0**-~}tXzIR
zAjwDL-$LHJRamry9u&7ZIJvujSJl*gSn<!OpiS=9dUeg$ohR$37{A{~)5~@?X$j8q
zm?8J6m^nU5WFW0koU@_#GF#G@>7fS7WyLji=7Pg{*Tc~b2~lG|JHJ#vmxUfK%`BJR
z%kkPKwxGq+>g+g!$CzJN9_hzT2bI?DaGAqM-7jl=BM<qKO`Z>*j^dGYIk95mWV>^$
zXibB}|06*=JlE#7Mi>7X39E8xQu<060QCuIai1g6e3Uz*-<)`?B_{xeb^CX31da$$
zrcp)&Jtzh>%A(t{P(4npnZ6EtGGR~088EsoafrLOU;W%ZVemsM<&FSD<(xmtW=^EU
z$@7x3$>6bt@lIiYb+1QyJNY{2amvqwZ$F65U~(!G$$6SAzZ5KVfZn^G*k<~oINKav
zzev|<=5WbZD96o&J!T`Xo+&D+v#9E+OdNNJ7?BA;r+9#&TDlfh@qWXzd(TqOSVYu-
z=dKt=Jy`x>%VqMK?vifrshp09Wpmz9*#(GgNr+HQ?;A`Xp|*=gNr&C^48IG~pFR8y
z!$wV>WT0^_j>6q5$Hzy^z6_ovf;gJj7d<>(bwd@s@OT2OeU?i~=-6`U0C#e7fqEh=
z#dI%QKWDL%eIl|@UNqTqS~+Eu3c0^N(0Y-)ARm&%9q^~FrrzoY>2hLxl334gTD4ce
zZgtQ|O^cX5gj+2KH(h2YZrdk`mz3BnqH|jW6!1v}Gm<j4<$KdwvcaqFKrY=FL)F(B
zOX}JDYCtbKg;Y_;xBOu*iOmt7Yku1A#cFi?!Y}tJYj5!gtw520wKP&9voO`IYTQ5(
zdc!rlZmvHimU~I@c?R>{FY~nIz*&BbdU2zzy^IJHdRZb{jc|GJ_6xGTc@B}(30Vs!
zR4C|U@|bQoCVZ5K>amQun^%{}<+9;dZegH$+Mfb7=Srnof_M=yIEN;@M+&+BqE-%=
zKJx6FEJ*zr%Z+l@@b%3{j!_euwa%w@;>@_3N~P~afoFpok@RQEbJN8@BAf&qB3t;r
zUB4h0O=b76zrcOo&fi!Z>hV45HYIYtX)S%mLWgpf-QYsqMi4=V*PaBL&M+xa&KLcH
zh;VXy4_L!<9o(V}@KE^oycv#9J3>d^q5T7LN#K$x&C?jrh*w7R)zO@T%Hhx*zEZC3
zT#V{>x{E8}kjR?Sk2qAxnoRB$)e7xVem!&C_a@ToX&o1;J{_nLsXOc9>VlOA7QulM
zzrTCi<QFXm7d+=Raqqr57!_Sj(IR2fd$pxIqeZK!9B_F|wUvB^6<%3lKUKt8pMsNZ
z{dUkMky%<^@o?lg<-8wa$*|=PZ#))=!A9pLhIms<zpgYDarYupUwQwsgA@;~-BTBy
z#I<8pEbH^%B54PE*?-Aq!X|=F)M(>gnY^K`KK3vwQ6r{=uPO?+jM#c3n5K<bJFG-h
zQHu!A^%wl+t}x{M7;ChB!O8Zulm_UA35#;V<xO6qfs}E*Y;{;$)^Zv7wl!`U3?4Ow
z#B~*+pCtQ{NT8>U$dT3H43>%ZgRhY4e)nGY<yM*^dz4hGw}TMrd!vAL(Bw#CR=6-3
zVznnN^5RXgZCb{5(*xsN+W~V!cFE&XWi-CSrEx!`81^20ly@3Q=GfShlKY65baOnR
zSf<3zEOXWk!X2NdZXy$`ZJ`A#)u7VOWHYMl6=j86l?IO&d2l^Sac#aJ6{T^O&zh!0
zN-zfVnq!o|HGdp;82z%f0&q1Mp7ytl>t8uYw&;~+0wvE{@2i-m76UpE&ahdLWE`v>
zU`3PkW<=%@_FUHz4nv=rtr9K7x$3N}=eN<DX<PC3Ktxauw&K0QHFi;;dN5KcTgB*s
znyeMZX;X)y_e2ZQ*Nm}K{U8w037$Y@f=*sdGR*sE#hH4KG@)N-2dtDDr3SSW2V3uY
zJKZv!*_2{xK;iv4SWETlYPm6g&?MNo+pTNLIPco;5yH~21g+a@(n`yRI^mVxT{rQ+
zVz5(OYvLS&b+ft^*ad5;Om$jeeX`+cn}L#ejl_)|HRgUlwQg<d%k3zu2(z@1T&tfV
zcT>Frh{un(w8yEC$>~qG@?Ddfy6m|kmK?urJ;p7YQrx<4)b#n;C<8fi2m;yGwH7fi
zl$yYH1A?J)u>PE)`w4g7A;c23#l}R6vnwu>Idtl46ty#*3hzpGSr^JWh?~Y)7s+n<
zR!hU2FQm+1F*||iIS}C<%cVTOl!u@Nw%Xt*HeEV94D+xu1&A)<y6O@xa4;rQwJv0P
zyck^9B3!_puAMmMb!K210U#DLGAL8$?yWx4Q{&uJXbw4FsL<c=zaYs-B6fhiT7isV
zMg}fL?dZOHIQI5-6dyl48t4Tft%YIxA<C%z^B$a{`#}{@y>FS3O-Vh7QGuS3Q3ofb
z(iG_%M0yP2omI;1y3-}11Z6H;N^=Rst`RCu@=%>M8;f7cYXz27EG81I+YcNJ`GWfo
zbGmcXw;jLx<~vnP*X(RP3Yl|R4IoF3(jqTsngmh^#ue<qtbxb=v(Bet&rhBT+51nz
z;7m=6Z!{hi79=^A7<0W$;D9>?S%lF#V9r`U!{A;<l*tCV(*mzHqij~@>~A?4lHpRP
zJEBQ3u=?me97j}vv{(9(?4z{|>Blt9&zP>Mx$l}{Avb8<$0N~sKYdQ2m7Ubc3#9?f
z?X&HnahJEH4d*kSw<1Q1>k@36K^W-|7Buq0D;v=4?Hys*Uk`HcU)k8#FE0wmv1dZW
z0=veLV*W+{x#KB8cWa*C6OoGMqXM|D;-I}#BQl36upRxT=qEPW>CJ`q5StMhILUk9
z7HwAc)1<C>CD!V_Rx{Bs6|--hQqxhkZ{6>*mv%CJEiSq9A|B9rQrn)w=Et_nlPc~o
zm3zc7%&F=B@;Jxx&$MxO;rJxfz+Q==w6khp<oMjWmbTjL@62Rjx3;Yy+>0FMH!0&O
z12Zo65(>f(nvYGAS3BQy=16@t9BaL2tU5O(bLzvVQkzFVJ>*SCgA^b#<v}MK@`=gM
zB(M9=?$D0WAkT`%LrOCeFn45`$0zw+VWFcBt&X9r@M$hM&5Pn8Gng=sjZQ*Z!f~Ox
zY3E(&O#@bV0_Jw|<0t8(_iRjNq#!e#f5x5(LbgdZD?WFYH}!o;!_b0|=ul3`s|u0@
zhtgEWdGF<Sf^%0#v?VIdMU=rkA*1f>Iv478L`E3pV48tqua6mYR#LT86i5LlO;{s)
zOQ0LqpQ0<a8qn-2G)UD~%=_CrYdU?2vx8+*Ae*`12+AsAb48Qgx=y}1P|;PY!1Hr^
z$&9+?m|<5lm@|!i@!q@?A1~C`on5VVN+;bm%qUzghXOqEtHU6UCK@zvdi><sf)cJ8
zP_?EKXD$2IY|aT8TT$}O9H_EpjtBP8EE?#^VQGGZ9oLJMD8sO)DP^NqiePT%#g^XT
zrBzbu2i_b@gszvtoGGI6%BMsgI4%QfpemdvUs6qJs^k<{;91pBy|6T)i<p`fTFduJ
z0x7LgfOFd9uV?YS;R8Bde*+&{)@Dw)w(PTRvGej4H<Zj_8<#tYG7pn)5GM=GZSF^f
zD{~+Y`MS6I8F>D#cCz}0Aaa($!hBZqxBQ-R=2s?U(p;vl-5PM<z;#6tfvDQG9U5d1
zV-bjfNW<7FM_5LwJPso@R1)q7>#mLUoqD!Y?-r*zz~&5jg0SLP$+3wt(_hRhej@y*
zaFC5RuyXM34K_k_XoY*YAsd`0bxNv?*)0XcW~h)sa}_Zv^RaSB6~f-<sY&5Rt0)jt
z!GasJcj4u`6*ov0f*QcI3e@*S_I<7wY)^7tpTbmZ3*9}_zYCW-a^aS_$5p4UFot(J
ziBLDB1J@&F&>8+Zx6jge4!&la{1^DvA^r=fFO2!YdDd#?nvkmy9cR}@DI{fOJc&jL
z?c8=ah^%RRsxhI}{wjj<_HOk3AA}r4zd>}|$PMCHkI;uWSa4ELamN?jkH4$TLomS?
znLslPMnqFJiSd~w9PkTuTbTQW)&A-!7?=$8xC{^n)0{*?6LSCIlh?qQbon1J0zjmg
zHB}KY4<wHforp*UyG^FniV99SE@eHMj|uV)r}dQ4iIPQo<|NV1TEM*f#c6@M@Q1R?
zsk~Cvwae<ki?ZJ=5XY>cnqb4n2?*^`gYH7~;o$QthoFUfHtA+XP=vbee^UcFgg3B;
z>oru5J)UkK*@NMt;QpYiJ;JaN9PzxL!m+pDc2)Zauad+Nu6W0#Y6^(aOUen#QbmvR
z)fFb2q*D-8`szVEZ9~~9;E(XQ78bY_7!kAz0kJniGui(jt*&8sWlbp}2#q5_n8gZ@
zwpe9o{s7xYc`j73RLxYPTtf9bq6$9~O`arSCnfVq7*v<}hXF6wyFmY?Eb%t0-}O4X
z`ysv7Us;TE&lg;ruakHo_!h6)5-R^II&4xz9ft3(4?Hh^ws2p`n`P_S6VNizeB`7o
z(B>!dt5(za!~Ne$V^b#lH}l~@;*Z{<p@r=Ondnb)Z>vk1z6B9hH1+J4=;)spN>j63
z4h8bvyC`S*r*JHy2XYo5Gw}N;ZI+_~GLzwh24ba}Y)#6Jo~vl1#li}Im95XAP42-(
z3*WFH$p2(u09n>|2Ms{teO+BxC6&G|R71Q`LO1NiI9Gu7*F77Wfx`Cxy%RIe;3r&c
z@N#=PY&Hm+e$k61{Lgy-o5uN1>gDkD|3sW%ckBO62mMd3=WoWQK@mV@HA4O;A@nHx
zZ*#RI3%4TDzWkrcTRLO@zp1EcyuF#u>my)_ioN@NXD)Vbu3iMQ<1+`@T770V23IM;
z_ZfY+oT?O&p0ju0hSRjP#@_mz-u!){#<V<}4i^;SSOdU#4V#y8HPqi3pzC0_EULE}
zrY(PVAdHZa^8wRX*zAeP(MyE)+U%Cd#|a-Q41r78>2haK{Dcjq<Ysd)cllNF#G0*W
zCtqN>Qw>`ojUzEpn`Q(<to>;*0p)bcL`i4O@Hp{g>V!eVZIJ7sw;rVa7m+UP0ui6b
z)v0wu0H(Hi%c6y<V{%34WR85)eGAB}?(-l^y?q$xocn`#7&XcQ(q+ut`y%btZ1bw+
z0lt<ESb<nunRjxDAg=3R)Le1hXtkNie9o?@vxoKP4AwUg3C`ESCU=4khwMfAwZET>
zyc-7qKguvh9;ZJdKf>F;TZMX;mC7ERF%Q(*%#FCD5?@{z4@g|r9Pxk0wM`)$*s3-C
z@)>04Xg(2gbQ$sf5rTb1hwRH$s|1U;wif#LS;mg%7GD9HTyf5#NgddsX}e0^@X4dX
ze8%u(Jk`Ye{D=wwDHyYkTJJ2bgX|p|Gvilq>6@cXwHPRlBPJTtoa%KYUO1`<zy~51
zm|#~KvV<A0_JhcVz;q(Q%0uA~5s;7XbN7f(Lo7p=ac)u^I_}<icq*f4jzR?_(`H(-
zOblLV2VGqcbtSLvy$wnTl$y8b-N;rz_OnJlX2Uk%dnN3>ccYb#;^|`lNYl<q#zixx
zC>tIkBq-ah;Ci$uDd#H{l{4k3F;edca(H6Xd3nFy0y0DIT{+#oEo0o%F?>S4hUYxV
z0Quv<GI<q^LE9FukM{K)Dcy91R)J9d#LCJHYp4U+HuYK4>t1YfI@9OV7XGW%EaOGe
z>&LLy!tU9JOgZQDi)nM-YXtZUA<j%9Jd_#_fSsK9cGYI?P^SKKYX~4q$GnCQ^dO<4
z3!}(mS5NDhU8&>xhzURK^a~3;7|tHv@Pt$c2kZW8NYB3E&~v#unZmFL%}i<_Q(mSa
zoH9jG6F^e4zVbto2B4c11Lv;fH7-uGnVei(rzxjt9&qpja&_qZ+%~{e6p&q;_&725
z7PbbMZQ8Axr^;NNq}y_L`(%4O{y=aIP7ZRM7|koG+I(L_G9#sK3-A8H148$-Mrap(
zK?a!nZz3JB11zm;s&D@W+2s@)+@{fq@-``)+?ggSdrHfx_mmR?<T7e2N~cde!`6eh
zzYCwu^m4!hkJCC_a&Mr*0O8_~ih=0L#JxiZ@R30K5kod8_iqPmH8Qu0>ZJ5Qj*eI%
z%-#YY0oHuVn3L<iY<?S%#nbDI6$X^wv#H8XQ7e%cG+lVF0!1S2CAN<CY;xHU^7iPT
zw4<xM<3dVBCy^k5;8oa`ZF1b#Yv(}bQxUPno080vF>SUSk!I4HY2mp%pZj%5;N&Ip
z!3y8(K^j~(le2Wa)_RN_t&fDcve+Gfy8P~Kl(^IJoyyk!wVZm1*m|`2oGK7nwt2fR
z+WtCJdV55^B}7OXkoC!OMbc<EZGJKSJh&wBm%Z0qyUngfIAV<@@=dGsZkkV+i!%BN
zlv`1Z(EVeYA*n}H(1d>(63XJg@o?^hV#_moHNN`Nyh)z#aLVLIX+|Jc+yU9YwPbxP
z!m^4b+)MZKMdRk$?%W2L!My?iv)|5a&wt5Q=B|sK<qT-OD(Myw^>rQ(=mxOL1PKe*
zb2#&+n_n$;+1jrWqB^CJ(La+WAU;yW5hndB(En7j7vL+GpF_IZ5yccJL-lN(hnQV}
z=Ja0t|MW6SjpWElPV#Vm8dKm1ozPokyrItUKSQ9g($FFa;U%%6LH?)Hzw`$=FdhL}
z9vxDkg;j4W<I#Z0eTV#OZ)l`A+Fp|$AqUi^9`5=kJa2yeoD^V|dU{4_cx&{hX5^>U
z#6zbWrp#ai2Le4ivzw%=BH9a|FgfmhI5Wz0F6b%W=R(yZPav{hVP&}nlDk2*WDWC)
zc6i<S1Sv{V{_jh#gRlA})H?%Kb3ayuo=y{#<Qe;;V(sT{f&vxoxpr*WJmDY6UCt)n
zOU7Q4Qc4KczZ02Q|4M6HVNWXg3oG|Kdy|`V_xN(20_5$a0{uJP!GT{Ed|rBJp-(us
zVb@J5u!H05ZGM#8zGgjim%%DmR6X~-Fd*m4a*x1Q*FrMqoP1q6f<bjVU-G(QI=`AY
z_67QpSy@{Kl?PwR-LJ#R)9=wy(M8xZE}V+@UQ@ITJI<9XZ;C3#D$b80k{<$SnG%xK
z?})a`Y8A<Yg#f_tc<$}xyF=kR=U^=a=TLw4(o3mKa7s4AE-!0dv_@_*5OPb7IL)iM
zX_Oa#2*A=8hY+?4l@B;=Vo)ri<kQQOW+7WTPK*oI>RGq7y|h<!+z-JSPR@I_TC|#=
zjupylhEbOpt3l62d`oGd(w(~4ZfBpEYN3g3;nmfl-L>rYQjVobxO*(3w$ZcmLA+Mr
zuIR3?EzV3>#nEBz*x0QMs^yU%VJiT}9v%DGC=6qVzAl$o2YHV#R|rV7hIWhn#`lk!
z$#jx{`clJ!d>TEpTIT$C?ZAe@gZMDnQwNXrYY66g4Z(O2$o#2{?lj-V*R~3ra+!;2
zj$nwipNn|B#<J@TahzXaM>WoT18xA!Mg(8g)n}Q&H~e1ftKR)Q?kfKyR=2x$!XL3A
zb#w<lXcpnGPTm*}+PJ@4V;z>**!I5jrz~D<>*oz|zo!5R%<K1k)S3W+Ea8X{*bX2(
zCQ+`1_gDZ&oW@%mq^A65GkVf-4pfU5t~3;`e`xooBc0xjZSZF_1AtI0uLy4GN1GY~
zo`~H-#3nzeUX%A&&uX&=eH63u2>4i5G}~yB)tMZ(xj(>#ytrQW^E?&6{0=)Lc*&!=
zmJ#PNL1how_Q+1v28SgxtpRb6?D}`J5AomrzWuH%S1kL4>ZH$ONz~iIH;x@5OL&}5
zZn6l*Fmg4oGeGL;K5Oipxr=ONDEljbIGFJde(PCAsyz_u%15+FGY7NOOJ{x!0iN~!
zwB>F(l(h&HdipF_fo5F_e^$7X1Oj@2-3QF6s_{OjO_EE7Nf)=@L<<_zQfS_T0w2@s
zRr|iDh^DRHl=;5Mt|PXWrYH!=#u6<a%-tzRU(QR!m@g}j<5>~_aC`o6b}S9*PUycZ
zJcx7+iB+<;uY;y~mg_%-nR4ng#E==)k7P~Vq~1xx^q|e>rEbTPB)}jVqSfrvh|w^S
z_qYR}_DwqtnN^`stN=0_L;piH`be+h=J}n@ll$vaa-@^Bu~y1+gPmGYmTr2WL5c8h
z%nQgy=rcxx)%Xjw1MqQOIrLH|G{)a_v$mrknUeo)h&(Lq;RY#h&Ex7lE!)(~w;<RY
zmHTvRrKC-h;#)b8c_#Na_65cEUE&z0m|x31DC-(dmlsIl^?XJC_k;n!DFvj<(;|4X
zv7|BPzsE!H22|^Ro`c+FNgNHH7v?vxF%d<(F*6)xAo$+kbBx`oQjknge<2T+407*f
z2_3!q0&(FR;_Ar*qrw}_ppxOlgo`EQNZP&zmTCcpk>{v7zKg%d*tqajboKq1njw0g
zJeh1_&&J_%BqqE3wUdJ#C2+4E?3xvf*s+Eqy)t?ZF!K*3sB;RTceY@tPZ#wcN5|yf
z_IL%Abs;v#o=8Bc4?X(GRWAwhL?2XNgVq`9t>Ty4qdOw{K|`1sDp$9LyC?Y&-QgQ_
zHNCvnx|i&kHmS?^&eZFQ>Q6Es6J700W9#1XNup@Ly_PDMw)G>v3?HSYg9}q}%M_Or
zWbj+Q#?>*;TRc|{$Jek(@4~f@tgv4fWsFgT{fdAOQ(y#x>-ec-G7j+UUa0>wVE*bP
zqifCB*Dl~le64G|b^r39iOpyf--EWr+_U~TXv0PG)i$5cGE#DRZJ_R+vCix9#K1!w
zwXZ1SfYaxiZQO2%!zv~$Aa+vhDpQCdCm>wlee9vPe1QkAAYM$TMD8!7dyQ39$yHvp
zC=^Y#6^f+f_v^T|_;i#U1oD)Qqi&tq1?<9TbC-0lrrmvlPqvQIutzU5dSa@y$AVaL
zV<wNBuLQKtI;8avtsSQMca8txi87cC?$R|nE<89a?3am53S4(6;FvH~HUByFrai^!
z>}#C5NO?5&z$6RElS-fH%Ypld4s>QWv_6hr!`=IHqSAU4T{UZRI@TSM(HoUA`({kP
zX=&N+q!I+0np*&oSN8^8z5PX7ok_uye`Yvy=Pk&!<;mYIvGMsWpp7$Qk@LNKyXdhD
zDa42hiGw<E-1DI6sBrp@Q*5DQaGB~c7|U1h9<(Vw*1!yANtdMlyah+IuCnOGSxD3T
zx*$i!f^k9M!OiG?e}tUA2e_DQv&hF>dIp;Z)3?1KO-u2!c7{#oCDm<%+6&K2%r1g=
z5XbK#ty(3j_5(nI*XFQB?!Cm%kv3Ri`H{@ReH1N0m!I_%7`WNQ=pCqF;ftpN1$Zdi
zgIAj`!!V5vNnjEJM$;a!_?7RWWe+Qt0f_lj@enNyc`C*0J}^i(H6_Q?w+p5RV~LWP
z-OgP~GqJ0GI`M5O;dgrar&md}Y89y8;J|;7ECwG2>GmD)`#r4%lU#;rO5YuKO;*sG
z0i_M6C7ut>s9KXNo@5Phe*AiTX5wwrkP2?0KwCPI>Ud(KNz5wGSkT>yYGWr;#cC{7
zrumheq*^^w-$g_}IQq?sDN<E*6X+hI_cL&o#+8TJ(Ty4aZ7N!fY$sbZP$(^L{L0A0
zyfrRCs&Ta~p=@mbtSHWAg?LL4&BDb!g<JVquE5Ej4P274K9y~akZVf56+p6i)|My$
zP_d<8wo+hWv5zgk-EWiwKz0<$DZLqu4i<KXH76?Rj?mhvE;v4^3R8CAyvvg_WRtR{
zyJep;=`~mL$A6<jB=CK%jzFvcRzQs|P2JhawAd(2qBE)G;H&U4m=z^k9Y~|g@ZYTu
zV;s)EktLjC_>XS+>Di~BUsDg1zz9-6K@<E;Wbh$oyF~%F+dAXySKcM;aC7uZil3i+
z?XATMNih9C_#u<doN-|@Tk0%i`13ah0C@aV0TpBlgl});Wn6aWrTcB79`47-o*z!n
z9o5K3-QYQE34MU2KH&h=Ib{XaLO9Ty679LR#jlH6WSZIl{uqUc0pHcnHt7fscxB?-
z#pRJ)m46gDI8;me=PIw2Gl+S5?qVuAhZ}Rsp(4PL<=u8KH;^^~e(o~Y86(UUkals5
z9*}ggR3H?>dhG93R$3`?k7V8uP;TXbUSjBhP{z@NW9dy785QV|@ij8CK^WL0KBb|s
zkP!9uGIriw#h+B>FyrjsP_Y?7XB(3gie(_20mzbv897IE5!<{|pazxGp_K{Q+O_4r
zn=BsEn1QF^<b3!rIlD0qsS>)rs<6GQe98E1TkG)`XCg#W(^X2u!bK81fAlPmj=c3s
z%>sSy56&Jdig!$|C@W+%@aBbd+|=(gOPT)R(e+2mLE}CYNE-8(FJD@-sMFr9k)o*G
z`q0WH-@9=E7t<C)XRse3Ud}4Hj~VVJN~ccL{63s|IT`jND37D`sx0P2I_(d4k{sZ0
zITJTqZT<V5ctA=yLHbFhr{q~wrXtv_P|t_mZj`MBiQRQv{*U;$8poBB7}8Y??|sU~
zo^BO|{9I-UM)I^qxh*!iD!x-k<BB;9oA-yE0C89#vZ?OJmUPyk)*k0+fX>3j<PS{n
zEy@;?w+CkHbNr)FG0snwC)*wa(OADgbz^Mm%_WO1)(b@o^pmz*4^t=Pg672x&Y6{p
z!r2wQ36a7JIPEn}FAA7Z5Gql<eE9jCG!nkJxTyF_{dY*j&X8XOf)J6%|GQK5O;eRB
zp^N=*v9!HeN9JFu+h>cvT3t~t*NRPUL!>a9VSg4}&cEf)9#5p74ET_Jqcu5OIzao2
zZp(p=5PQZNkPX@SEF}MR_&CoVgPwK3btQ0RoHXWT68-qxU#u!!E`3E`+sj&4uV+s8
z$-V_mRgb<)1683CrCWn>R-b_hN=@Np^V5gGi<;0z^fOF%3y+Q9R|;g(U?c0vWCd9u
z&&7GyD<3RO2X+Q5>n-7P-OlIB6zA+c>KucWQXr`mmb6aG_uDy{L@8c(z%10wzug-4
z)iVEX(7m$H%QuyTUVldD@<;x&l|)R_a>@eisZ_>ZDC%vf%c`$;{owJ9x0^pn7BEa#
zBbh*=(g|DbES=0%*mx&4HaMhiJ&3`)K)J;OL8zolk)Rbrrr5tOSNe0);3WSRUa4_f
zvedBdY{2;XLr?n2rr*M*4-=iyKU?rN+-XfOf1a%PAfo354@TU2d9J>rx&!$dJv>{-
z=ls+fE{1~G&b^$c#(o|L<6$EOd{0Z=I)-#s_~y^GvvPdyLVD%l2K#Ij>aC4VxVgBB
zCQ}k?<2=<{n+eNUX%QZ!PF{xFx0C1dX~zsvW+wMMSW?4(8#^Du8um5?LrWK%kl}%)
zo};*Bp)2Q?wRst>8{;hx&Ms$}F8u<=^haJi;>;>o&S=~t-EarJfIg=?8h4LoyqPml
zZAo)$_Pjy3;O3}*3*p$G^$U*yX_=s5($>^nrEL9PJG#pU_WI3yZbeSdK23{nc<_ks
z#SG@6Ha@w)I>LYM*kL5dB8-DuDO=Xkear*q!jf`>vFbx8h5%d@EQZfN09v<6XTqBv
z^0<s&OaAIkCJ-=kTvw;tsuZD3JJxuY!qdTM0(CuN0LtvJbo_-XYucExbRR~rKSsj*
zfSa#E?jt(1STa3l7bQV^U3z6+H(yUjAFnJly)(mw5>A;}8njU0*4t}Yv{IR_N7cJu
z^#&9|rOESyvn@MG&YBexL#pci?X%uwcu==ZkeKR(^|U%v7xlcUWa>P}6SGf_F)_d3
zd&E8LEH`=N(4Bw0BM90n<nLk4Md{%QY9$BIN0vOQM{*cnJp{jk`5<?=K1pu7_Jb#R
z%*Mo48YZ*l`_RM9!v8DP6h;v5tIk@)Z=H<Bq~*q<XceQ|5bjsDS#8$)F^>m6a8lUy
zayg1=QTKM{!=k`^@@vhdiTT9O3i+M+eDLaEG`o#r){eZ1DT6=A53#5D^WsU3RIh>3
zh=kQ~qwlxwZl^)qGNvAt>!3Mx(4!ue+dSy-<}QTMX8Lc$=0j(rz;li6MF2s+hQ5%O
z%1U$V{^LT6ihZ{aSE9C?cUJNm>Rr}GDUkamyE<a!E6dM**BJOp@VPy)<?4iq35Gix
z64KQ6IAl0eBD2VCBc8#659^!qE^Sbk?XjAV?3lZgjKqVr_}7TcDrsW3RiztysuSP|
zdHTIiJ#FMO(F$2R9qvI<1A|f{5?#efhKmDdeN8j$@cXavfFT2|`28x3#s>ml5tW~Z
z{A8{umc=hZ1i1nsHJaq_n;K&{eC*P1I<gzp&z0Z*sBiuYhKER9JN}f?Zrj}cRg$JB
zRdZBaw7ZrTx9qb*VPd@Nr~{E{nCzBxgf4>XK@n72gMkc;fDY3;D?*Fh!&kCKz1cb8
z33NuDL7W3$y{h;wm;`#!Skqk<zOqZ860&3`M1b}58WbCa41Cp~?fkOisY#I5Lse1O
zw7u_s%*CYZF=Ov{ho}!UrQ$ncIxAbx)*CEml8CJ4v~#_^Msp<Z2Y}GNitIDb9<;;a
z&qDGYKAX8EDM-`03X_T{my9S~MKSq$1ff}kZN%D;8`oXK?)(4~#0SI)y#UrDV(u`J
zL#~0}QNp?ReOF=9#uM)G9JQ9>6<)Y2OHJz55zmPR1gh(cCT5;48s36%mm+X;rD}SL
z687Ff!-`+(5KXx|RYE6-^{hPLPK95=j?fY|-w^K62&br3fy6a~H5>7M?4bx`vQ!Z$
z2H(T8c&>2w$)NdZ9r3A(V@@an{hl#NUF+L2eO9g&S#L;TfRVP8>X>0}L5KtmCpTXe
z)w?1uDHw}MR^NbR^COxs91?5J1WZ!OiV`pEaLYP#V>(15jA(NAzvXlmsl0lb@M(pn
zrm(kV0i*$<JA0@c6B5{@c*uNMpeL_5F1Zm}2q(R_HJ6*!bE4&lo>7V2>G|_=tzU*g
zm2;ZTt~JC$phC=+aAv}UaPGjF;lzvjJn##RSe;wD*1w-}f2vs<hVqrjxjjc4W|7;4
z2{b~r{bzqY&gnMvHs2yK3bXW?=m6!EYO^1+d2(I=*FyFXo9IKhXny$3`oB?<PX!rL
zj4#8u!9}CFLcx`4fZi{RON4z+0rST&-yN~@<(iF8%5^COQ=&wc^Q_nd#wRgO-^yuH
zSBf?`@P_=%No=Vknks@P=V@UWmG<+Ma+OQxc$=}6<#cbT+jCp#B)THv-s#_p+7C-o
z8f!ciDf+q69>B6{H=BC-=bc&G$K3;HR^I`PF3I~GFS9lx`+i>}EF{zk4;DG~j(y0}
zF1@JtVf(^nQk_n$_IV+JR=?N4xva*Van<qAE?B(PqI&h#m^a(o%8Zm|r{&|H8}U^}
z_c-)0JRQ_eKt1O#WsYSm<!7)z0z9Zf=zmL3Q$)k=iYSIEB;mtEwd?f~Szqej@O6*v
zaWGg#Yu>A*n(u(6YtW`QkH8Q~I{nL%ir)~NV6w{nHmHcg*STU6D?w#PY$D<8ufQ{X
z*2AsrKO;HJuO+!XwLkq>nQ-=)n_NCDywPZ+2Meqf<J)_&vh3Zku9fpz{j|LhNTc6M
zcf98@Nvx@|)R<}lS^USISBD8r+=}RG5~Hqxz^(P^N3)eghNuyWOG;s%_H&8c(Ian~
z>L?=!_T@eog>og+5L@ZoJeqn>+)1?9QYk<JhOl5{3h${Ly?BzQ?8w#+0jOTyP~mqo
zI$ZQp-QIDBx}+}jQYcp%sct<E6E2eTxP^8@$Bj?I%EGCCrn2tq-tFD?7VqB2_1US;
zCAdvPaqtf?N%+cFsO@ens|jXb7*iy^6V(f6SsC5);Aa|-Xw7maKcy_=HS+hd;1F1A
z$WdbS?o$m74*sTw^PglQ06kEWPL$tu*RE|0m?{1qCCubxD@~JL5irxay27KY{T@w6
zNE9%xvvm-cIUQD-wCrE}?sV*5-{5C!Zq$+fQiU`>3`|$3;%_G0^IGzZ4pmN<B~@-^
zr3gS0HLGYBJf8Wop0URH+~L_*M3z-*l41J1%08~{eXYi@cAu&`?Qin+|KOr$v2v-R
zBiDxRUQlRfnlC-M;~d!)xn02GW`%!2X|Gzw@PkM#J*jfeK1{MVXEOS<aMv99LbQ3P
z1fGQPoLrkod$u^urugr}Dd1Uj?pv{qpm+Fo*KNJyI#jN)|9GFjN;Fpe#eSG1@5RR_
zpCnwq;?9g^Wo5MtRYd4b(&kGw_0kj?jB_#e(Z>g~#1%Ek?_{5kIg`w%o6$*6g|*ZE
z6<X#mTR?z18fN+?XR1mG{1k3oDA_O|qcNSDvbjc6(pxd<I__$$aBqr*t*j>b)4GGm
z%#r#A3*&vG-9aj+vzZlcJ|;#+>$wwv_;jq}Jug+uKWTntblmlkk<DX~Y6W*~ff9?m
zhtMifx;k%hBtiX#M`A;^hN02D-6i_+8sQJIjr0A?MRr~~hjko2;92Os_r$I5#xZPf
z>K&sthPODHMU5V!Vzjo+KDjjT-joDn^KQNEYA20VP<F#5G`mOJOKCW>{Vd|9Axh3k
z-egA40*rz?D^_)Px|TF~$dMhNy`^^LKC?v<d|%<Y(UQ1alx-sIeO8oHzAkXBw{rCS
z1=!*QrFPi@m`}~(zzda%3*l9UrJx5&1}Gfpxbp<c<p;JJ729>8q3Sbk*{y1eKU6b!
z`cs1Sc5<z%98GwIev_D@{APwiRLZAj>G-){zBL8b?~Tlm4GJYg$&u<JGeUB()4B>C
zSbNTM^nH%#-dST*Q*AenQ$vW3ee>Q<`;rdmB0%xu@>9QkeT%nKFTK;t<l(M44M2=o
zj^zHjSX1(IUk3(9wP1D`#*KYuP3Hs9{iT^!DM9&VLUcXb`+lPNakPu`A3FNY11J|s
zz~y|%pa07HC({Em{*bHqc(X%aS_?YbiIS!rJlxMmZv2JPuESMM)Vt5s^=cV;>mqyo
zUy4J06G^O0BKRGq<=>cx@&N$ym-(m`87r7gqmg@#t}Wzr7Z{rVNLaAL%cQIQ!6$r7
z!~A}4x7S=(e+g%0Q#_iT-z$!oH(J3GPwR0uV@iVxqu1Kg`FPE}Ev-2mB5;auXGKlk
z?dY!65u;}x09gvk9N0*;7_;H;AJRjM9SO(BUog=lE&e^ri9ce;aNZi1JehbQ_j&qk
z&%DO}t)K#UNC!TKUv|bQTB2=vzdQy1RDiR9ujzu^hjF_*d?+UirPNOnlm>$<qKqD+
zuWK8ch7&qEI-;lzBo*^=Hm0vDSuzi!i+D?n(ht~=(^C7240c)?6ZW$`w0%@h{JtSn
zLHvje?1OPDJGomIM=tE{K<-lz{vqvKDd!=tP)wicppi5VQ*ep02mg-C^$0!MXX&Co
z4~8XIC|js&p&<B4(J`!NGL!rEehko%{PNDj%u`q6Kdce?I6=0KCP4`F(yl8GMz|0t
zhFsw8yY(s*c$g&Arl5@-`$Gj#I`=BkxXb3LQ{hw&6fNL5R;=~4NN|iEYswP*4KLlb
zI-e{ec=J5`VtggimxVvZO=TnvlI(obHZ<9EcNd-=A&Mv%s?gC=9#I%}Uul;Pl|2DR
z^^ra@LpBctJARPle*JOBzd2WZm|A4gbwbMR_r6bfLTnMtgXTyX^2M#sd)#VTdYZE0
z$8nho^Y5&1N@|rt_8-SnN?hP@u<VvcM%NdYI`PrOx7pggOl5`Aye;f$!(!O`7=4@y
zSuRs`9Qjd@5cG{HAD<Uw0@TSR$LJQHdrDWojypqG!3E&XT8ba00aASg?s^M-@;<F5
z5Y!y)Jd>(Q-*=t$E8<~F>MdmBj<HYJ^9p2Cb9`E9G2X9xo}bd8m$l;W(IQX7X!w<Q
zTF75G)Fro$hHMWU)UzHI(M-vmO9EM-_SVV*=e0@L>DWp{s`4Y&%H@HMMxIgu!73V>
z_fs^{{ShWNDR=gL4y744-*Zl?a|iqYQ^df%2M*cg_hYE1lwQ$+jX>6ZFu0ArkHu3M
zYM}q~adqE5#yH|-JLhwsv=~*2TKAP6LphQH${LQC-)-|-g^qk2AL|>$TpqU5g6SR>
z+p~A^wvLfG{S=z?5NMs<U9;j%X8~YN3yiXv<6`~4hqXD6iJVLou>}cP{W?3`3f>At
z`Og;&2CNDmHRI>qdhzIiG&28xwey`(O*dP=K{O~5K|rNQ02M(|KxtA!M^wbbhbA4A
zDov?EAb^N8X`-kg{h<jYNDD0#L1_Y^MruGhfrK7N2;4uO^WJ;zde{5m+>dvie9Nr=
z?Ad$Io;@>r@A>VNBc%5EK9ZsK!U4d=|6Z(HAIs-PJhzUxBc~cj{`E#1*=x5dkFWTr
z_}cUwL7<UjY+-J>)$|!LH{I^5%Xin^f}Q!e6`=C<veC$B&Bz<@OYai)^Fud4s*KHk
z=}U++Z<p4ehp%hAoo(-oNP7aTX@xZY)fpo}SVr4PSvWdog^X04t*3U?T;@<8kM;<-
zq6Gwe5w0|uAJI>3@F3h(kFyF)p4VDauuASyMN$rs2$9cD?H$o6yz9TK6%u`45So+E
zGu5euwI(08%SCI1{n>Pb&mP7xf=eSu6gZ_>WsOwOb>4o$?VLB#e!*tHnfg{SQTUXr
z$742T1l#;}o?obT8>+OHPrh(hyL71U_xm&T+24y_OdeJ&fb?TE;NzP&^E_LA_I_3;
zznLlfJ~QnjNpnl2ys%u5K1X)@-nOl~dWll(@?5NJwzSjd((PjuR#vNTqW}+In!mJE
z_OT&E%)Q6MIK?Ecc|V$JV>RwJo9Jov?q_pKg{-gNfV=fXeAo<m-8p5HM()i*_!v4H
z@zh=2t=z>MoY{ND)s#&6VBYukH%gx4aK)a{Vpa@_$`+A1VW772^j^ZWg5}u2dP@f$
zkKa3WoL5X(;>e`hgQJa+EtT&lrGQLF2R)C|tV`aw+xf(y+eW}-@FRji!bj##Vxs}%
za(dwQu!!4Ix~K)Jc-;j)7ilOO3`gy6q#v}ms%(GNj8k53Gp?wwY|be6O~4uv)E1<v
zlQZSgC#J4PLY6Y`v_H@!>>*^ftvz7G<$-wPDWJ>`^d%e|(Rxv1B||#2ZPD-jGu&!_
z#%v_l2?46R(>&AbZ7XBo$anhcxsHIAXi!^9vZH#~1&|D-CO0GHJ9gY;@4Qv6EZ|o1
zRXADmQXPNsK6E)|8ho_C!_ngV7(_zH4WoA^QPg&PQ-iaqwj$QU&*A~)8yF{fd~%|0
z!e{o?&Gdl^EpE_#qaFXSo+12AfTKbCGOotsU`JNNj;@r6=E!knIGXi4Tlr!MP@{O|
znS)5B!OKhY8v^7J#f-(mw<Kr76PlkgzkT~~{?Ne5>Y4e`PT=DS5fLgM;%aX*f3xMN
z>Yts?Wp19?D#iPA3O{%w#_gThIWMr#IG}!fGAcXX*0>Al>M`!3w_E~KPAGvC>u*Zs
z>Y$q6Uwm`Rxz`<fxRyZ~x(SYm2WDvwdZ7(R;N%-!L8hhp8X#jH`M|*fgqWvC@k%>#
zvTwR5?nl%)bcVv^xD*x0pJ{wPBeIaq>(6Cu;+NCeI=<xL8s~T9iAA>>B8@oSon7en
z*9WC0b0c^DBULS8aiiMYN3$P{$@0~Th1wXmBh@W?W$rw*8ao?f7&-A9MX`DL3<nsj
zfnZoFS$Fx4*0El+mT(5^jqXCklCra~B)ZO(<&4{ih+YUtA|V1HR)&noLd<Deifwe`
z75z*4nlpbUYI`0vQ`gjUBIqQ(TJs2y@8tso91o9z2ms~xC#+eU4S43;El9J|(Dg!M
zhd#e)kKcHuQ)8a;J-<oC_&B9An@Ve=J%cyBZ%rYu&WA*^{=F8Q1-s_eutCGACh!PP
z+e|qV=I%nP0J2`^Iv~<<jp*YP_k!nBnJ3LZuDv}kT&pZ8NH`JgU4F?+?aog`O9&8G
zQt>6s3V+b4e~p-n&0PHEQ$=JzWLOLj0ge1acqc$@-_&_uB)O<19e)|K-cb`UHqEPE
zt5j~ezF*f;d1v8^P<*cc!$EUX?vXI9!j{4obY~}Q!K%;?Dx>VI-|dks#ON9eUIm=R
z0%}|PiSRRBr`Yb_-`;(wDhPVnUwKRY`RyDtQ3;v6D{1^<(ZRR)SnYh+-DV6gmL9zq
zt;?%^xO;jjaN<}l%!Roqv6}e+p;ov0zJA`!XEN@vc_yfVira*Y7HCDwas)ViqqMna
zW?$8sds>W|iClh1)E!XI=?%<uxbV`e_`;zV_h;5f6TRXhi-)^})qQOzif$a$YE<$u
z@JzaDZZP=4Nl)x#l=3reJa<PxV}skqoY!S{Y$0AVb~^IP_bg{<P4#)APPGw02$bAt
zcy}WGS0o~{KpFEPWzMc(-E-}Yp2FdMW21$Fn5<D*LGNDopVSohhDB$6HDQW1#HAmN
zGJ~w20qS<V<fFN!U#ExGF>&Td2>QnGi><VYcTZovLf@@odFzdJ2BK9Pe+}euZq6t-
z`mbgo{KIY*{`JC<cYYU^#R6lsgF>N}EzButT7W&H(;bt7JG2WBgS^0+kvAcMB}<RV
zwB8b~?V7#zI`?Fhp@Kqr+N)A6Chb6uMmrrsNv9z3x5g*N*oJ^P7{L<8>K^sOo;ANk
z#*gND`%veb&~**B4X{K?mP8MAFhl2?fkKqqz3AfP4LNvQ&F(Wjwzlbt(XgQ0i5s(2
z4_@yxq|cM@SDrH-$5GQ<T+eNV=O|?UjC#b=u>oQ}iVv7>wMZYf+79(jBkKRz5+`gd
zAG3^G&)Pojtl71dZEWvseeVPvJ0Fr!?J@t5Bgf$vUkr?+qpZvD*6FZIwc#*lLlI?%
zPoL2E<Zl~<>Z`wB%{Oa3w7CY8G97Cy)!$F~^6k|h!sKR;@;&vHo1*?tL|@JuF21@Z
zXgnb<FF9>5kL$=hBCNFBg4S9^b+#HxWaqls;MpySVw?^4xE92xLuwVWjcX8dj8BNU
z{+R`hcCzj|Cl>bdhoAp^?+h^IxF#9-Hhg1XEwvtpy?*hHZd@)$$Hs3(GvHOQLqgn1
zh)}|dQZ<mfBq^l!vGef$vqrtl3ZNugq(*YZli{SB66T&fU05*V=mYr732S}()%qqJ
zMyf(qKk%7baOopU@i0dqs?VEG(cOpkq-+>bYC~|W`YRq2Xz%sCt8wSx66L`No=wRy
zqIRkZkG8U-sqnd#64~l*y2sIy^<m$9RgOWBh}P~#As7EPZLmjlB+u(0zNBl&rmb-4
zC$rF@t9H1{eTrz_*B;s?&N+KxIHLdr@6HHUhn4f64BaQ(KNu!Nrs_^!mG2GPrfh)M
zhvdcXA2WP{;zng$qT3AEs+4e58>I$$Caj9I9-g-3<HM<x>}SX4BU?=6gz);_ewMQ#
z-q0`CyQPu8W`$0L5A_RKrdfU{tm^U$X0bS(HXINp6*d#5E{TyAA|@H@)$x87m8T;X
zGQ?*p6?>T35FRL42mJaY!rwa#aY_ijXOLoU!E$&RQp2nPiGVIY`Y3U~0fXBf!3#B~
z)fBE8Hm4c*Jr55LpXWY4ob`FkH9#DpUTTBa$vQ9jUaP>6r|0CjZ=k1XpViq*oyEN%
z3(JYmD-d9!A?-Jr?^hhN2!=j|igPp`xDTj3uP)lza>3Bf{y9p9m#ktWQESmovxJb4
z5P$t@m!62R#r66xk774|0I?sF6h%jO#|Hm(@)yZM){V3C$1J~4+pAx)CKiKna$YO7
z9CoV8yKy)b*?ySN$nsob_v@SPd7m;_R--M?3{&Kv#nID`IZ2B<0oXjjP|o_{rmc?m
z;;j&gZbeejPM@x145nu3%R%;6q(SE~=$4~Gk3rfw<3T&$-Vwa!jtyQlx^B^QtT{_h
zt_yMDC7eF>F)0sS9;{}iIHU2IP=3LjFXKYsUG{g}hHG)&TC3}k5mpYZ5lMh4F9=Vi
zu+<$53bF<K=1RY#y~?7p8u9{2m)74>Nh-tfcBkYt?PmKYt0*hiMHGZ)gnyM<=-R&B
zCz*69@b{hk9=m9R0!mfe@vS@&wr-{$kyD5?22uM{bqGIq!&fT~;2;I^zq6AZxE5`-
zr#%@68T0Lr0zooEYOdx{O%lX0l8icQ4wd`;O!ptLxwnr|P7R*M9lRT337Y(pi^(tn
ziXu7|Zf}bjm32zgF1Lq6{T<V1cjO+ktL#krlIu3Qi8yi%sq%h`+{(1Y&}BBS1>cp*
zm`H&t;DYXhnmTE9YtXTQzU-h%FOzUTM}r1p1OoMramkAG6|}te?m;dU<i$Ebm-joT
z<5c&97A;@&z^DO%`+K`^DuTb40x)ka#PMX>b$fYu%@sR-mi^SJAL)BDqNGzTn1+3t
zn>!cy=w@wYvd288>UY#mtP(kbOZa@yX0~7q*NyY@S{85i)7d5#k!r-042x$?$DFK?
zJ5%A)*t*&4YsJ`!k&}T@C>9WYdcnz|Zne_5g|a)T^YuKEQUh6Q=2tnby4?<Mg)`>n
ze*=5kbLMp&IhEe`^TniZ5HK{S5Kqbdrm~aJ`Wq4#cy)h<3;sPt6)OVupW~%L@l;b=
zXO%rtIWyxFusB(mX;Z4J@}gfayAU%E1Sk{K<`=DK)hORUYERAjd2b6To($sq_Wj>^
zs?iMxs{5DsC5Z=}JN(26u7i2iJ&8c}1tbqZ3B<!@%?4iZ<@xUoarNOgn@S)Mn3?B?
zbucQtm-??={vR5EQEn5nDSwDsO9kHmIJDV>W&HaMH0bNYsRUT(31y-Q{NF@D|9%6&
z2Tvd%?jh0OCeS~n4gU8V00rG{U<Lug+5AJP|C^{<f2GG@@{1`~%<+*G21ZYnSWjn}
z9@<?(Q|8edOClI}+^$m4{`BPj=6)@dR`G(Yi;nI|le><~Ts)9vSLF;kz!PNy#^CPb
zryD#bz1KD*s-(tW?@!e146bp(50GGH1Px_85N@kGu`{>B)v$YikBIVkJm&AO>Ygf3
zY`D5|&W}E}H;c&)9HIUE87=XEPBN}v(}4(5(;D`i_8ONeo)ZTNBU>M~t#Elg3rNIv
zJwVP2?$?S`<qq0Fswz*T60zOR<Qk=YJVq57L<!n+eHJv5M9v;^@FF7Hx8#4Yt8Opu
zu!P6S2aMHVor305gZ8WT%?9QdeSwIVwUBj9=2O*7e!86}`aI5tE<ZeVuv7f7x4<r-
zUvJp0+hl5QH|QY!HVcunkWa?hI-@Cgq8}s-zeV46mq*!q9q<LztxddNv>L6f?6d}T
zj8Tf%3wmtn;}Cfwr|SF|fRt5(W^9$$(VkQiO|0HKfhd@47TqOx+VU~UI^`8fMO9Zb
zdhfOj561T=alh%{jb#1Iu|*%Zn%PP(rBaexokAcyozaxOA5qVeLq;x%*N`=-%C+?(
zH@D(DhI*UDYB6^7)N$VdY$+Afs!E;hRmly9FQrg%fm``JMygL|nlNOiq1H>2D`^f5
zTs5M7e+)`3@krG|L0M$~@+6G%3rcGf?d$Pw#!@f6md(dQlxLpzad{PIHwD4i-?`D&
z746ciNEMJDK_t>aSQF@-C1`#{huH}!HKQ6(s_yHUDuCQq7I@_>a4?lvXX+1UrWEOz
zyd2c>hQU{1?gIC*Tv4U*!KY66(4g-gg66j}>*ya&STnjLFe*9qIX#0qdn#yD4l<8s
z?;`-)8&u>h*KRGWcVRCmdu+m<Q*_`%Zx*EqfIy)kxf<8KFLon4%z@Yb_YFq+SNubL
zKY@SOTp0}>1y5OxR7(2_KyH=4skDOMa*XGsnOn}qpZlq7!#AUQo`76JGj&q-_kBeN
z=0+;FGXn=l<G}JJaD~v2C8`oEzqcY;U`Ot1Fe4nke{%~=*%rDR#9-`%?jjUJk{;f&
z>s7Gm^)(#9Y^V^_tl0C`zo~g&8^-q`h`k<uQ-5#W54=kva50addMOtIG0A~&DnG;R
z9ODOpq<IsTzlE8-z;q4B0wodrx6`23i_ni$I{HaPxVbhXYocC|5tHYMYpm(!$DMO3
zl1e}(5Yq>?x4zX>+{Y0ChjJ+ViSc-^=KkQpajCwPGVu4BHSvHiK%UaQFzM_0hTCAu
z<z(;v!LEnQOs;v3sx?=JYMDrLyww~_Me?2CGkklr-3WhR>713YUrE@CD6kk%nd>Ue
zBR_obsG_A#rEK-##!*{pqO0ghY~mg4>^tTz>kJy>0ihOsvC}=y+#uBN{r!)!ec>*X
zBrASEJC(7n#;t!*ni3-?{h4i3b$Wv>C-RF{4T37v>pxl2r*ceNV}~^mgYM;@vu<lJ
zKV>BCtYiSyVU!E!ESK2Ji@QX)uelh~PcmZh)Gq|;=4wAWy)CEBmacg*@D3q#Xt08i
zfBgLwWmD3wrP+Ai60D>hdB=WxK)NB(t+T=1;X9TVe}KP3S+txvIJFp1O69FRXA)7t
zu-v6q#Qz$)F-#fnlOLCNQ+*m*#DjevUN>H8{?P2u{CU`9U>x`^{I?kI>^>pHZ)5o@
zCelZKDc|F}FSms2+rJL)rAjTn9_uJ^g}m@)Q%uXs>puH5m%jo$!T0Rr&ZZ^+W%X44
z(@^i)(@{Q`&W-m1Vxuv{mdZ%TnTt1j&^S>hvS33!Kd?mD1vJYh?7_^l=U<VMOIR+?
z#SAnH@e2VqHt3*--zD4zFhw-tD`H!M4_2RENb9Z(scI?c)`vcgoX8SmwU}14EH3mk
z7M4i;0B#>TdpWqmg3+Ci$v+sjHuHOD0)J2R@&DzJnXBmT3Mb{qwU@G!%iXpAc2w<B
zd67kVUq;y_1e4`!w)eu*Vpu2Z@H75L9?_|kM4y#8?W?j+YOp5VB~VtUlo6}mP=2~V
z2~qgKa>i<-=3Ieln-_clcZZ?-*s{Sa6NynN3)Gz~93LDyD{DueC|UHJ9vP!$Z)aCt
zr>$fVnSe)uj<nZTn34o;b$V%bsNC%qf0@HyeWtvxt25}HEAw4for4r7wW5^5S>X|g
z)FwCT=Gpa9r;O~BuiJ~!HsiJxpTTv0E4G#w_=RlK14cDL#OT~7_{j+m=t^YJ!WG>1
z%1Jxtjdp_~dnrUcDv#6#Ew^oE?vj3grV)Uky=>~;Wy^w>i{GTDYNex*y3%->oLa@K
z+57N3=OG&Q)6rrrO}V0nffr|P47o?b#MS})u0g>8Gr`Vn3ofytq$TRo!7x)r#aCEB
zDIqfi7Kj-MgbVLyIyXYS>;WW^<4MZtXL&PJX3mwDB7wv>6$W$c-LfN@)Yn^F?DALG
zxZj$^eXN0KLPVr*(qkf@ldLj*IwqojW~Zz?L8TjwF2Mrl^7wbzeHnPS7{O&r7j0Tp
zU&;co2T2t)1%vZzn8MO70Wb!f^>SS=!AvzF4!A<O_@B}c@LmYA@K{N@LxHQ=g2#+r
z=i|_GNKQe{l(|oGP0j!=+S^=)Eo`1|M=LF_OT%1K|F2)Wqe9Ii0a<>rY~YSz$~7+)
zFUX^W&%n!8sFj5?pJTX241=U>%Ne@gh#Nfe3tXj$63C7nt#eUy3u?p=6O_Ler~vO?
zk3AF9Xn}eS2V2mGb{!iozs-KRXGcu5bA^6kS0fhs5c_3$Iy|xAe`z22g{eW)(@}Y4
z6NYq1kF-T%4Z#+ZV06OT>eZ6X2jzTJ71l~f_oYn7m7`AVO=lvfh|#5|FPycTiZ+9d
z4Iz{2ts9&&Io!;KSV<-oE{DFZ+*Qh2zNPMn(3VDq$j?2FFLg&$OxR1#G_{?Ay6hT-
zshtZmA9<eQFjVU_XDVlPllwt2Q)PObSmx9``$&zpJ^L}f_FBMHaHtPk_g~jz{Dtv+
z0cJEcM<rqQ5)((LWoLt{eSL4FmaU_8@xINVqxZEfTId#&D$6Yj_6PK@VNLOq(UsoO
zKfhVHnkAkQ*~EEFY^;0OW`i{{ym9yT=JZY^%`+w4<*=vtZ3ma15yo#lef*2jqFfd;
z7G1>t=(v}q0DD6!_v;l^d}+a8)K8kz#jw`@nr^q>en4eJ!flUW+5C#8vh>b=N2c`U
zO1>*Eb2y&BVtQUbv1?9<epL>>fRZ(>b$U9Pm4a$pj;w^7kNToZdhKR2xZli_a^ZHX
zvAgQ=N%FGqSvTJGvBQna4?SpA`mJI(<nORu!bzBcSPuH2u1*6|zU9}u`FPHvZ!HC6
z6x2;(mpcxiCm98f<m%|Zs6G(t7&1)n7!7Bn2?ZnJAhQAeiwcc3_Sfr(%71rpH?jJq
zX%@(vWEMGN^Y5ghj7x2P4ATp>iu4Q}sb8~@31M>1M85{nZKc0e+`o%5ejCX-Yd$=v
zWc;Z&UkPP`<qSe@D1EFrpLRRi`fkbHg}e7@6Zrs+iywjnX>t8@XquJ{Q7-wW#V4%!
zt9GWGP{<v9H1`SXlemE!rVmOay_RwKuZ1gnP6|MTc$g9eZuc3NGd<e5?pJo2r|Z-u
z@9{zYh|#YzFqsW(Vwd}=Gwr47rKr$#sQ<3M763VfTF9YQSXDhZlD80&{wi#Rg=q{I
z2xs@vBqUp4W6m~}vZRirrDydOfhy@G=&r0QLCeCP4^L~2#-@*OBv-Z{E!p}IpFi}~
zmZI(Fn#pox$$kA==iZo&>QP0n<t0znpl#1THI(?Frr_BNv?*iGXGWQo092$;{~F6j
z05E|wx+aozTYwXDSx8n$?2DTdGxzwirf`;=@0Tz&XM6@f7OXR@ESmDR3Cs$>Z(Y9e
zxWDY9PKV&5g}qJG_Re*KpGT#SR4LI@{T`PRlEI(5j6y2!kxenc5W;07IP>&!MFHax
z`FX;*dn6|X0r-N=TksD#1lF@WKcYy!D{Avmw>^x>g`Mp3RJK#Ri2AGxC4OJ(VsI^%
zGAyHlDrT`L^I4IXhP)kT*`v>B0S_Qa;bcQp#iGCE<BgW9T1uB*7Vp0bQ!`V)J?^l#
zk3Oh~Y3m%l4j|0Ny)!nqrw%MPhb_}NaWu#Pt}pfwR|4cJ$hIS|2)QYHE8ejzix;Sj
z3StG<?!vV|X6jc{qVCEE7GqW=kgVwGLV3}wbmxMVU%QJ=<&gLafuP2z@OMi=so{`h
zMu7x?N5lU}E2QLE!%hSM<wn>Y0sW+!3J2Gg5!)|qFRRC)^<iFpYEl?huU^!$deQ;H
z@dEQ*h(<BHvxUHi?Luc_)WNHDsHQ&dQH5EgjYa=b10Tq2N;yc06RqejzLbL!J?-XM
zG!j|@V8yXx_YOvDv&YIq#MrV;46JDQEnD7k|1E7?Uz^7pVLYc-te2rkmRfw!T<pr%
zc`<^|yuQw|f45(1=`HNbQPkY!MojfaforyFF=hM5tIFQ?aapcOpShm`9QJwm>s*uG
z9;V$LW|VBIoUuOzCMYnRx)#tawCG2pj{vzSscJHDD`M+fYd-t0SZ$Jt$cM{~(vd-C
z5<6ACquBLf=S@>j!6|35m4q*7Ea$ZQ?-7s;*3hZMC1d<SF#kJA$o-YYl^e3ZA*Hh4
z7y-FX6V6%ujd=-aC!F<mC$s}%A7Gc=Q-09<Ha2%Y3H3aoyAWVAvfvLY(U-}xM(Gw!
z)nM!7luyqFjuvA)=cEa20X<`SmQNo!-*aY5;qK{vU#-{qiLIh*^8h(!en0oM4^EUS
z%k`?BJ=X?h<|a_-JGhjMd_x7wuUQut{AkD&G5CY|r#O;{5Nxi`;UOvx+JEUqY6Ml0
zQJ02NOyBM0JUL9SA0{bP3kd2p@)golh!fH@m)DAKm5m)G!^;@sr7Q2E*T2RZ!i*`4
z%ZzFyyIws(+{ns5?MId@1?FSXtn{R}*P)jr=VpX-u-~e^S#6nGPZ%Q$)o&qn$sif#
zyh8OLiiWc1-*%La?t^ST<+umF_4cJfar3(ma(G|Vk5z;^Sy*8$n3YL=>6zVf69-Fv
zws9C+Oe#Op*>zrK+{|Z4C5!AW>r>6FCcWAY)4?WADtN!37+lWbopi1yZ8G-Vb?#sr
z(zE}rv>2Y=A13|$99x3U<HF>fqO5Qjd9XB|lx2o&%QC0hk6n2nJ5wg%fNWv~I;&Kh
zVJ5~35@*qSdS~O%=4jiv(K3SRxCxS2Gf*n8`!H?xji`t(NV)1XC0}3XWy((F<-8vO
zL#MBHf#TXNbW%+n2#SQEC@i@c95A$hb$I&5urrIk^NJZ}WCojx8x@ZiuV$VMOJU04
zRU^M!Zclrw1Zd=*bnw`f;Y1if*%AECUX48SpgnE*%At4}GRz)%w(xCRc)I{78R!<T
zB!X=FuWmxV_qOBzPq#yYhu!dO{~+^^0S^C*bp-=t|EB>#)%vBP$a`eapAW}|yZ`0G
z!y$n2-;FV4@FJ3#fG@-Ul{5BXeGe9ZwiEad&wm8!3T}e`^Z%9VL?uvHa39-0$N(~6
z@N9cKyQJx8tAdIViGNB5P+z?|aex{Y_cowpUHCKP;kSJpdqzu%eaG8U-@*<D0^*AQ
l`Ta)&|Ixtz_Zlz@0xevd!dqTvbvu;xuJ!{hw1)M|{{_vCQN;iN

diff --git a/doc/images/load-balancing.svg b/doc/images/load-balancing.svg
index 425a9d33aa..18d836d345 100644
--- a/doc/images/load-balancing.svg
+++ b/doc/images/load-balancing.svg
@@ -1,4 +1,4 @@
 <?xml version="1.0" standalone="yes"?>
 
-<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,3.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path fill="#000000" d="m268.05804 127.32641l1.609375 0.25q0.109375 0.7500076 0.578125 1.0937576q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.2812576q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.2656326q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.3906326zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm18.65625 0l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm3.5198364 4.765625l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.191681 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.879181 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.110107 5.875l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm14.031982 -1.5l0.234375 1.484375q-0.703125 0.140625 -1.265625 0.140625q-0.90625 0 -1.40625 -0.28125q-0.5 -0.296875 -0.703125 -0.75q-0.203125 -0.46875 -0.203125 -1.984375l0 -5.65625l-1.234375 0l0 -1.3125l1.234375 0l0 -2.4375l1.65625 -1.0l0 3.4375l1.6875 0l0 1.3125l-1.6875 0l0 5.75q0 0.71875 0.078125 0.921875q0.09375 0.203125 0.296875 0.328125q0.203125 0.125 0.578125 0.125q0.265625 0 0.734375 -0.078125z" fill-rule="nonzero"></path><path fill="#93c47d" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path fill="#000000" d="m273.87787 196.37569l1.453125 0.21875q0.09375 0.671875 0.515625 0.96875q0.546875 0.421875 1.515625 0.421875q1.03125 0 1.59375 -0.421875q0.5625 -0.40625 0.765625 -1.15625q0.125 -0.453125 0.109375 -1.921875q-0.984375 1.15625 -2.4375 1.15625q-1.8125 0 -2.8125 -1.3125q-1.0 -1.3125 -1.0 -3.140625q0 -1.265625 0.453125 -2.328125q0.46875 -1.078125 1.328125 -1.65625q0.875 -0.578125 2.03125 -0.578125q1.5625 0 2.578125 1.265625l0 -1.0625l1.375 0l0 7.609375q0 2.0625 -0.421875 2.921875q-0.40625 0.859375 -1.328125 1.359375q-0.90625 0.5 -2.234375 0.5q-1.578125 0 -2.546875 -0.71875q-0.96875 -0.703125 -0.9375 -2.125zm1.234375 -5.296875q0 1.734375 0.6875 2.53125q0.703125 0.796875 1.734375 0.796875q1.03125 0 1.71875 -0.796875q0.703125 -0.796875 0.703125 -2.484375q0 -1.625 -0.71875 -2.4375q-0.71875 -0.828125 -1.734375 -0.828125q-0.984375 0 -1.6875 0.8125q-0.703125 0.8125 -0.703125 2.40625zm8.90271 4.5625l0 -12.171875l5.390625 0q1.625 0 2.46875 0.328125q0.84375 0.328125 1.34375 1.15625q0.515625 0.828125 0.515625 1.84375q0 1.296875 -0.84375 2.1875q-0.828125 0.875 -2.578125 1.125q0.640625 0.296875 0.96875 0.59375q0.703125 0.65625 1.328125 1.625l2.125 3.3125l-2.03125 0l-1.609375 -2.53125q-0.703125 -1.09375 -1.15625 -1.671875q-0.453125 -0.59375 -0.828125 -0.8125q-0.359375 -0.234375 -0.71875 -0.328125q-0.28125 -0.0625 -0.90625 -0.0625l-1.859375 0l0 5.40625l-1.609375 0zm1.609375 -6.796875l3.453125 0q1.109375 0 1.71875 -0.21875q0.625 -0.234375 0.953125 -0.734375q0.328125 -0.515625 0.328125 -1.09375q0 -0.875 -0.625 -1.421875q-0.625 -0.5625 -1.984375 -0.5625l-3.84375 0l0 4.03125zm10.873199 6.796875l0 -12.171875l4.59375 0q1.203125 0 1.84375 0.125q0.90625 0.140625 1.5 0.5625q0.609375 0.421875 0.96875 1.1875q0.375 0.75 0.375 1.640625q0 1.5625 -0.984375 2.640625q-0.984375 1.0625 -3.5625 1.0625l-3.125 0l0 4.953125l-1.609375 0zm1.609375 -6.390625l3.140625 0q1.5625 0 2.21875 -0.578125q0.65625 -0.578125 0.65625 -1.625q0 -0.765625 -0.390625 -1.3125q-0.375 -0.546875 -1.015625 -0.71875q-0.40625 -0.109375 -1.5 -0.109375l-3.109375 0l0 4.34375zm18.635834 2.125l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm17.328156 0l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm3.6075745 4.265625l0 -12.171875l1.484375 0l0 12.171875l-1.484375 0zm3.881012 -10.453125l0 -1.71875l1.5 0l0 1.71875l-1.5 0zm0 10.453125l0 -8.8125l1.5 0l0 8.8125l-1.5 0zm9.881012 -2.84375l1.546875 0.203125q-0.375 1.34375 -1.359375 2.09375q-0.984375 0.75 -2.515625 0.75q-1.9375 0 -3.078125 -1.1875q-1.125 -1.203125 -1.125 -3.34375q0 -2.234375 1.140625 -3.453125q1.140625 -1.234375 2.96875 -1.234375q1.78125 0 2.890625 1.203125q1.125 1.203125 1.125 3.390625q0 0.125 -0.015625 0.390625l-6.5625 0q0.078125 1.453125 0.8125 2.234375q0.75 0.765625 1.84375 0.765625q0.828125 0 1.40625 -0.421875q0.578125 -0.4375 0.921875 -1.390625zm-4.90625 -2.40625l4.921875 0q-0.09375 -1.109375 -0.5625 -1.671875q-0.71875 -0.859375 -1.859375 -0.859375q-1.015625 0 -1.71875 0.6875q-0.703125 0.6875 -0.78125 1.84375zm8.512085 5.25l0 -8.8125l1.34375 0l0 1.25q0.96875 -1.453125 2.796875 -1.453125q0.796875 0 1.46875 0.296875q0.671875 0.28125 1.0 0.75q0.328125 0.453125 0.46875 1.09375q0.078125 0.421875 0.078125 1.453125l0 5.421875l-1.484375 0l0 -5.359375q0 -0.921875 -0.1875 -1.375q-0.171875 -0.453125 -0.625 -0.71875q-0.4375 -0.265625 -1.03125 -0.265625q-0.953125 0 -1.65625 0.609375q-0.6875 0.59375 -0.6875 2.296875l0 4.8125l-1.484375 0zm12.90271 -1.34375l0.203125 1.328125q-0.625 0.125 -1.125 0.125q-0.8125 0 -1.265625 -0.25q-0.4375 -0.265625 -0.625 -0.671875q-0.1875 -0.421875 -0.1875 -1.765625l0 -5.078125l-1.09375 0l0 -1.15625l1.09375 0l0 -2.1875l1.484375 -0.890625l0 3.078125l1.515625 0l0 1.15625l-1.515625 0l0 5.15625q0 0.640625 0.078125 0.828125q0.078125 0.171875 0.25 0.28125q0.1875 0.109375 0.53125 0.109375q0.234375 0 0.65625 -0.0625z" fill-rule="nonzero"></path><path fill="#f1c232" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path fill="#000000" d="m45.465923 185.42131l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm19.707325 -1.21875q-0.9375 0.796875 -1.7968788 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.0312538 -0.25 2.9843788 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.6406288 -0.5625 -1.9062538 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.2656288 0 2.0468788 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.7343788 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.7500038 -0.4375 1.1093788 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.078842 4.9375l0 -9.859375l1.5 0l0 1.390625q0.453125 -0.71875 1.21875 -1.15625q0.78125 -0.453125 1.765625 -0.453125q1.09375 0 1.796875 0.453125q0.703125 0.453125 0.984375 1.28125q1.171875 -1.734375 3.046875 -1.734375q1.46875 0 2.25 0.8125q0.796875 0.8125 0.796875 2.5l0 6.765625l-1.671875 0l0 -6.203125q0 -1.0 -0.15625 -1.4375q-0.15625 -0.453125 -0.59375 -0.71875q-0.421875 -0.265625 -1.0 -0.265625q-1.03125 0 -1.71875 0.6875q-0.6875 0.6875 -0.6875 2.21875l0 5.71875l-1.671875 0l0 -6.40625q0 -1.109375 -0.40625 -1.65625q-0.40625 -0.5625 -1.34375 -0.5625q-0.703125 0 -1.3125 0.375q-0.59375 0.359375 -0.859375 1.078125q-0.265625 0.71875 -0.265625 2.0625l0 5.109375l-1.671875 0zm22.290802 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm14.543396 5.875l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm18.176071 4.421875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.438217 2.9375l1.65625 -0.265625q0.140625 1.0 0.765625 1.53125q0.640625 0.515625 1.78125 0.515625q1.15625 0 1.703125 -0.46875q0.5625 -0.46875 0.5625 -1.09375q0 -0.5625 -0.484375 -0.890625q-0.34375 -0.21875 -1.703125 -0.5625q-1.84375 -0.46875 -2.5625 -0.796875q-0.703125 -0.34375 -1.078125 -0.9375q-0.359375 -0.609375 -0.359375 -1.328125q0 -0.65625 0.296875 -1.21875q0.3125 -0.5625 0.828125 -0.9375q0.390625 -0.28125 1.0625 -0.484375q0.671875 -0.203125 1.4375 -0.203125q1.171875 0 2.046875 0.34375q0.875 0.328125 1.28125 0.90625q0.421875 0.5625 0.578125 1.515625l-1.625 0.21875q-0.109375 -0.75 -0.65625 -1.171875q-0.53125 -0.4375 -1.5 -0.4375q-1.15625 0 -1.640625 0.390625q-0.484375 0.375 -0.484375 0.875q0 0.328125 0.203125 0.59375q0.203125 0.265625 0.640625 0.4375q0.25 0.09375 1.46875 0.4375q1.765625 0.46875 2.46875 0.765625q0.703125 0.296875 1.09375 0.875q0.40625 0.578125 0.40625 1.4375q0 0.828125 -0.484375 1.578125q-0.484375 0.734375 -1.40625 1.140625q-0.921875 0.390625 -2.078125 0.390625q-1.921875 0 -2.9375 -0.796875q-1.0 -0.796875 -1.28125 -2.359375zm9.375 -1.984375q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250717 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm6.910446 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" d="m73.85669 211.42131q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm9.775177 -7.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.813217 6.6875l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm14.699646 5.109375l0 -13.59375l4.6875 0q1.578125 0 2.421875 0.1875q1.15625 0.265625 1.984375 0.96875q1.078125 0.921875 1.609375 2.34375q0.53125 1.40625 0.53125 3.21875q0 1.546875 -0.359375 2.75q-0.359375 1.1875 -0.921875 1.984375q-0.5625 0.78125 -1.234375 1.234375q-0.671875 0.4375 -1.625 0.671875q-0.953125 0.234375 -2.1875 0.234375l-4.90625 0zm1.796875 -1.609375l2.90625 0q1.34375 0 2.109375 -0.25q0.765625 -0.25 1.21875 -0.703125q0.640625 -0.640625 1.0 -1.71875q0.359375 -1.078125 0.359375 -2.625q0 -2.125 -0.703125 -3.265625q-0.703125 -1.15625 -1.703125 -1.546875q-0.71875 -0.28125 -2.328125 -0.28125l-2.859375 0l0 10.390625zm11.660446 1.609375l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm12.879196 -4.375l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm13.927948 8.375l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m248.70341 189.50131l-62.29921 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m236.70341 189.50131l-38.29921 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m236.70341 192.80478l9.076187 -3.3034668l-9.076187 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m198.4042 186.19785l-9.076202 3.3034668l9.076202 3.3034668z" fill-rule="evenodd"></path><path fill="#e06666" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m492.37677 197.23381l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.281952 5.109375l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm6.228302 3.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm15.297607 1.265625l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.859375 3.609375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm5.7229614 0l-1.546875 0l0 -13.59375l1.65625 0l0 4.84375q1.0625 -1.328125 2.703125 -1.328125q0.90625 0 1.71875 0.375q0.8125 0.359375 1.328125 1.03125q0.53125 0.65625 0.828125 1.59375q0.296875 0.9375 0.296875 2.0q0 2.53125 -1.25 3.921875q-1.25 1.375 -3.0 1.375q-1.75 0 -2.734375 -1.453125l0 1.234375zm-0.015625 -5.0q0 1.765625 0.46875 2.5625q0.796875 1.28125 2.140625 1.28125q1.09375 0 1.890625 -0.9375q0.796875 -0.953125 0.796875 -2.84375q0 -1.921875 -0.765625 -2.84375q-0.765625 -0.921875 -1.84375 -0.921875q-1.09375 0 -1.890625 0.953125q-0.796875 0.953125 -0.796875 2.75zm14.027771 8.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm8.235046 -0.046875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250732 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.1917114 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.566711 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.8125 7.40625l-0.171875 -1.5625q0.546875 0.140625 0.953125 0.140625q0.546875 0 0.875 -0.1875q0.34375 -0.1875 0.5625 -0.515625q0.15625 -0.25 0.5 -1.25q0.046875 -0.140625 0.15625 -0.40625l-3.734375 -9.875l1.796875 0l2.046875 5.71875q0.40625 1.078125 0.71875 2.28125q0.28125 -1.15625 0.6875 -2.25l2.09375 -5.75l1.671875 0l-3.75 10.03125q-0.59375 1.625 -0.9375 2.234375q-0.4375 0.828125 -1.015625 1.203125q-0.578125 0.390625 -1.375 0.390625q-0.484375 0 -1.078125 -0.203125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m195.75066 158.99738l27.716537 0l0 32.53543l-27.716537 0z" fill-rule="nonzero"></path><path fill="#000000" d="m210.74643 180.79738l-1.140625 0l0 -7.28125q-0.421875 0.390625 -1.09375 0.796875q-0.65625 0.390625 -1.1875 0.578125l0 -1.109375q0.953125 -0.4375 1.671875 -1.078125q0.71875 -0.640625 1.015625 -1.25l0.734375 0l0 9.34375z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m392.7034 189.50131l82.39371 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m404.7034 189.50131l58.393707 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m404.7034 186.19785l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m463.0971 192.80478l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m489.2755 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644836 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349792 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.34375 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584229 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094421 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.9627075 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m266.83298 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.3437805 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094452 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962677 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l-215.08661 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m311.25372 227.40143l-196.18726 153.55408" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m313.28983 230.00282l5.1111755 -8.195496l-9.18335 2.9927216z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m113.030396 378.35413l-5.111183 8.195496l9.18335 -2.9927063z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l0.12600708 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m320.7124 232.00525l0.10800171 144.34647" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m324.01587 232.00278l-3.3102722 -9.07373l-3.2966614 9.078674z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m317.51694 376.3542l3.3102722 9.07373l3.2966614 -9.078674z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l222.58267 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m330.27423 227.24397l203.44104 153.869" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m332.267 224.60924l-9.231659 -2.840271l5.246155 8.109756z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m531.72253 383.7477l9.231628 2.840271l-5.246155 -8.109741z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m412.22308 158.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m434.8905 179.70363l0 1.09375l-6.15625 0q-0.015625 -0.40625 0.140625 -0.796875q0.234375 -0.625 0.75 -1.234375q0.515625 -0.609375 1.5 -1.40625q1.515625 -1.25 2.046875 -1.96875q0.53125 -0.734375 0.53125 -1.375q0 -0.6875 -0.484375 -1.140625q-0.484375 -0.46875 -1.265625 -0.46875q-0.828125 0 -1.328125 0.5q-0.484375 0.484375 -0.5 1.359375l-1.171875 -0.125q0.125 -1.3125 0.90625 -2.0q0.78125 -0.6875 2.109375 -0.6875q1.34375 0 2.125 0.75q0.78125 0.734375 0.78125 1.828125q0 0.5625 -0.234375 1.109375q-0.21875 0.53125 -0.75 1.140625q-0.53125 0.59375 -1.765625 1.625q-1.03125 0.859375 -1.328125 1.171875q-0.28125 0.3125 -0.46875 0.625l4.5625 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m287.22308 247.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m303.8905 267.35986l1.1875 -0.109375q0.140625 0.890625 0.625 1.328125q0.484375 0.4375 1.171875 0.4375q0.828125 0 1.390625 -0.625q0.578125 -0.625 0.578125 -1.640625q0 -0.984375 -0.546875 -1.546875q-0.546875 -0.5625 -1.4375 -0.5625q-0.5625 0 -1.015625 0.25q-0.4375 0.25 -0.6875 0.640625l-1.0625 -0.140625l0.890625 -4.765625l4.625 0l0 1.078125l-3.703125 0l-0.5 2.5q0.828125 -0.578125 1.75 -0.578125q1.21875 0 2.046875 0.84375q0.84375 0.84375 0.84375 2.171875q0 1.265625 -0.734375 2.1875q-0.890625 1.125 -2.4375 1.125q-1.265625 0 -2.078125 -0.703125q-0.796875 -0.71875 -0.90625 -1.890625z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m629.2467 241.13911l39.653564 0l0 32.535416l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m638.7936 260.486l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875153q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.2500153l-1.140625 -0.203125q0.21875 -1.1406403 0.953125 -1.7656403q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.2031403q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625zm8.021851 2.453125l0 -1.296875l1.296875 0l0 1.296875q0 0.71875 -0.25 1.15625q-0.25 0.4375 -0.8125 0.6875l-0.3125 -0.484375q0.359375 -0.171875 0.53125 -0.484375q0.171875 -0.296875 0.1875 -0.875l-0.640625 0zm3.093628 -2.4375l1.1875 -0.109375q0.140625 0.890625 0.625 1.328125q0.484375 0.4375 1.171875 0.4375q0.828125 0 1.390625 -0.625q0.578125 -0.625 0.578125 -1.640625q0 -0.984375 -0.546875 -1.546875q-0.546875 -0.5625 -1.4375 -0.5625q-0.5625 0 -1.015625 0.25q-0.4375 0.25 -0.6875 0.640625l-1.0625 -0.140625l0.890625 -4.7656403l4.625 0l0 1.078125l-3.703125 0l-0.5 2.5000153q0.828125 -0.578125 1.75 -0.578125q1.21875 0 2.046875 0.84375q0.84375 0.84375 0.84375 2.171875q0 1.265625 -0.734375 2.1875q-0.890625 1.125 -2.4375 1.125q-1.265625 0 -2.078125 -0.703125q-0.796875 -0.71875 -0.90625 -1.890625z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m44.392044 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547592 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644821 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.343758 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962669 0l-3.7499924 -9.859375l1.7656174 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#6d9eeb" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m760.14105 300.09717l0 -13.59375l1.796875 0l0 11.984375l6.703125 0l0 1.609375l-8.5 0zm9.610046 -4.921875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.031311 0 3.312561 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375061 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.250061 0 2.062561 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.062561 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm15.719482 3.703125q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm10.469482 4.9375l0 -1.25q-0.9375 1.46875 -2.75 1.46875q-1.171875 0 -2.171875 -0.640625q-0.984375 -0.65625 -1.53125 -1.8125q-0.53125 -1.171875 -0.53125 -2.6875q0 -1.46875 0.484375 -2.671875q0.5 -1.203125 1.46875 -1.84375q0.984375 -0.640625 2.203125 -0.640625q0.890625 0 1.578125 0.375q0.703125 0.375 1.140625 0.984375l0 -4.875l1.65625 0l0 13.59375l-1.546875 0zm-5.28125 -4.921875q0 1.890625 0.796875 2.828125q0.8125 0.9375 1.890625 0.9375q1.09375 0 1.859375 -0.890625q0.765625 -0.890625 0.765625 -2.734375q0 -2.015625 -0.78125 -2.953125q-0.78125 -0.953125 -1.921875 -0.953125q-1.109375 0 -1.859375 0.90625q-0.75 0.90625 -0.75 2.859375z" fill-rule="nonzero"></path><path fill="#000000" d="m744.0764 322.09717l0 -13.59375l5.109375 0q1.546875 0 2.484375 0.40625q0.953125 0.40625 1.484375 1.265625q0.53125 0.859375 0.53125 1.796875q0 0.875 -0.46875 1.65625q-0.46875 0.765625 -1.4375 1.234375q1.234375 0.359375 1.890625 1.234375q0.671875 0.875 0.671875 2.0625q0 0.953125 -0.40625 1.78125q-0.390625 0.8125 -0.984375 1.265625q-0.59375 0.4375 -1.5 0.671875q-0.890625 0.21875 -2.1875 0.21875l-5.1875 0zm1.796875 -7.890625l2.9375 0q1.203125 0 1.71875 -0.15625q0.6875 -0.203125 1.03125 -0.671875q0.359375 -0.46875 0.359375 -1.1875q0 -0.671875 -0.328125 -1.1875q-0.328125 -0.515625 -0.9375 -0.703125q-0.59375 -0.203125 -2.0625 -0.203125l-2.71875 0l0 4.109375zm0 6.28125l3.390625 0q0.875 0 1.21875 -0.0625q0.625 -0.109375 1.046875 -0.359375q0.421875 -0.265625 0.6875 -0.765625q0.265625 -0.5 0.265625 -1.140625q0 -0.765625 -0.390625 -1.328125q-0.390625 -0.5625 -1.078125 -0.78125q-0.6875 -0.234375 -1.984375 -0.234375l-3.15625 0l0 4.671875zm16.943604 0.390625q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0476074 4.9375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm10.613525 -1.21875q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0788574 4.9375l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm16.813232 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm9.640625 0.4375l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 -84.15747" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m700.5833 298.80334l-146.57245 -73.40985" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m699.104 301.75708l9.5946045 1.1107483l-6.6359253 -7.0181885z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m555.49023 222.43977l-9.5946045 -1.1107635l6.6359253 7.0181885z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-612.9134 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.4244 305.80954l-589.1365 80.89273" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m699.8737 309.0823l8.54248 -4.507416l-9.441223 -2.0381165z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m109.83856 383.4295l-8.54245 4.507416l9.4412 2.0381165z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-390.4882 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.5822 306.70535l-367.02686 79.101105" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m700.27814 309.93466l8.176514 -5.14151l-9.568481 -1.3171387z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m331.85934 382.57715l-8.176483 5.14151l9.568451 1.3171387z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m700.5833 309.55096l-146.57245 73.40988" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m702.0627 312.50467l6.6359253 -7.0181885l-9.5946045 1.1107788z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m552.53156 380.00714l-6.6359253 7.0181885l9.5946045 -1.1107788z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m538.70605 294.4908l39.653503 0l0 32.53543l-39.653503 0z" fill-rule="nonzero"></path><path fill="#000000" d="m559.0297 316.2908l0 -2.234375l-4.03125 0l0 -1.046875l4.234375 -6.03125l0.9375 0l0 6.03125l1.265625 0l0 1.046875l-1.265625 0l0 2.234375l-1.140625 0zm0 -3.28125l0 -4.1875l-2.921875 4.1875l2.921875 0z" fill-rule="nonzero"></path></g></svg>
+<svg version="1.1" viewBox="0.0 0.0 960.0 720.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l960.0 0l0 720.0l-960.0 0l0 -720.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l960.0 0l0 720.0l-960.0 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,3.0" d="m7.624672 117.129105l0 0c0 -13.695778 11.102621 -24.798393 24.798397 -24.798393l572.00946 0c6.5769653 0 12.8845215 2.6126785 17.535156 7.263283c4.6505737 4.6505966 7.2632446 10.958168 7.2632446 17.53511l0 99.19061c0 13.69577 -11.1026 24.798386 -24.7984 24.798386l-572.00946 0c-13.695776 0 -24.798397 -11.102615 -24.798397 -24.798386z" fill-rule="nonzero"></path><path fill="#000000" d="m268.05804 127.32641l1.609375 0.25q0.109375 0.7500076 0.578125 1.0937576q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.2812576q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.2656326q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.3906326zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm18.65625 0l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm3.5198364 4.765625l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.191681 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.879181 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.110107 5.875l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm14.031982 -1.5l0.234375 1.484375q-0.703125 0.140625 -1.265625 0.140625q-0.90625 0 -1.40625 -0.28125q-0.5 -0.296875 -0.703125 -0.75q-0.203125 -0.46875 -0.203125 -1.984375l0 -5.65625l-1.234375 0l0 -1.3125l1.234375 0l0 -2.4375l1.65625 -1.0l0 3.4375l1.6875 0l0 1.3125l-1.6875 0l0 5.75q0 0.71875 0.078125 0.921875q0.09375 0.203125 0.296875 0.328125q0.203125 0.125 0.578125 0.125q0.265625 0 0.734375 -0.078125z" fill-rule="nonzero"></path><path fill="#93c47d" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m248.70341 158.99738l143.99998 0l0 61.007874l-143.99998 0z" fill-rule="nonzero"></path><path fill="#000000" d="m273.87787 196.37569l1.453125 0.21875q0.09375 0.671875 0.515625 0.96875q0.546875 0.421875 1.515625 0.421875q1.03125 0 1.59375 -0.421875q0.5625 -0.40625 0.765625 -1.15625q0.125 -0.453125 0.109375 -1.921875q-0.984375 1.15625 -2.4375 1.15625q-1.8125 0 -2.8125 -1.3125q-1.0 -1.3125 -1.0 -3.140625q0 -1.265625 0.453125 -2.328125q0.46875 -1.078125 1.328125 -1.65625q0.875 -0.578125 2.03125 -0.578125q1.5625 0 2.578125 1.265625l0 -1.0625l1.375 0l0 7.609375q0 2.0625 -0.421875 2.921875q-0.40625 0.859375 -1.328125 1.359375q-0.90625 0.5 -2.234375 0.5q-1.578125 0 -2.546875 -0.71875q-0.96875 -0.703125 -0.9375 -2.125zm1.234375 -5.296875q0 1.734375 0.6875 2.53125q0.703125 0.796875 1.734375 0.796875q1.03125 0 1.71875 -0.796875q0.703125 -0.796875 0.703125 -2.484375q0 -1.625 -0.71875 -2.4375q-0.71875 -0.828125 -1.734375 -0.828125q-0.984375 0 -1.6875 0.8125q-0.703125 0.8125 -0.703125 2.40625zm8.90271 4.5625l0 -12.171875l5.390625 0q1.625 0 2.46875 0.328125q0.84375 0.328125 1.34375 1.15625q0.515625 0.828125 0.515625 1.84375q0 1.296875 -0.84375 2.1875q-0.828125 0.875 -2.578125 1.125q0.640625 0.296875 0.96875 0.59375q0.703125 0.65625 1.328125 1.625l2.125 3.3125l-2.03125 0l-1.609375 -2.53125q-0.703125 -1.09375 -1.15625 -1.671875q-0.453125 -0.59375 -0.828125 -0.8125q-0.359375 -0.234375 -0.71875 -0.328125q-0.28125 -0.0625 -0.90625 -0.0625l-1.859375 0l0 5.40625l-1.609375 0zm1.609375 -6.796875l3.453125 0q1.109375 0 1.71875 -0.21875q0.625 -0.234375 0.953125 -0.734375q0.328125 -0.515625 0.328125 -1.09375q0 -0.875 -0.625 -1.421875q-0.625 -0.5625 -1.984375 -0.5625l-3.84375 0l0 4.03125zm10.873199 6.796875l0 -12.171875l4.59375 0q1.203125 0 1.84375 0.125q0.90625 0.140625 1.5 0.5625q0.609375 0.421875 0.96875 1.1875q0.375 0.75 0.375 1.640625q0 1.5625 -0.984375 2.640625q-0.984375 1.0625 -3.5625 1.0625l-3.125 0l0 4.953125l-1.609375 0zm1.609375 -6.390625l3.140625 0q1.5625 0 2.21875 -0.578125q0.65625 -0.578125 0.65625 -1.625q0 -0.765625 -0.390625 -1.3125q-0.375 -0.546875 -1.015625 -0.71875q-0.40625 -0.109375 -1.5 -0.109375l-3.109375 0l0 4.34375zm18.635834 2.125l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm17.328156 0l1.609375 0.40625q-0.515625 1.984375 -1.828125 3.03125q-1.3125 1.03125 -3.21875 1.03125q-1.96875 0 -3.203125 -0.796875q-1.21875 -0.796875 -1.875 -2.3125q-0.640625 -1.53125 -0.640625 -3.265625q0 -1.90625 0.71875 -3.3125q0.734375 -1.421875 2.078125 -2.15625q1.34375 -0.734375 2.953125 -0.734375q1.828125 0 3.0625 0.9375q1.25 0.921875 1.734375 2.609375l-1.578125 0.375q-0.421875 -1.328125 -1.234375 -1.9375q-0.796875 -0.609375 -2.015625 -0.609375q-1.40625 0 -2.359375 0.671875q-0.9375 0.671875 -1.328125 1.8125q-0.375 1.125 -0.375 2.328125q0 1.5625 0.453125 2.71875q0.453125 1.15625 1.40625 1.734375q0.96875 0.5625 2.078125 0.5625q1.34375 0 2.28125 -0.78125q0.9375 -0.78125 1.28125 -2.3125zm3.6075745 4.265625l0 -12.171875l1.484375 0l0 12.171875l-1.484375 0zm3.881012 -10.453125l0 -1.71875l1.5 0l0 1.71875l-1.5 0zm0 10.453125l0 -8.8125l1.5 0l0 8.8125l-1.5 0zm9.881012 -2.84375l1.546875 0.203125q-0.375 1.34375 -1.359375 2.09375q-0.984375 0.75 -2.515625 0.75q-1.9375 0 -3.078125 -1.1875q-1.125 -1.203125 -1.125 -3.34375q0 -2.234375 1.140625 -3.453125q1.140625 -1.234375 2.96875 -1.234375q1.78125 0 2.890625 1.203125q1.125 1.203125 1.125 3.390625q0 0.125 -0.015625 0.390625l-6.5625 0q0.078125 1.453125 0.8125 2.234375q0.75 0.765625 1.84375 0.765625q0.828125 0 1.40625 -0.421875q0.578125 -0.4375 0.921875 -1.390625zm-4.90625 -2.40625l4.921875 0q-0.09375 -1.109375 -0.5625 -1.671875q-0.71875 -0.859375 -1.859375 -0.859375q-1.015625 0 -1.71875 0.6875q-0.703125 0.6875 -0.78125 1.84375zm8.512085 5.25l0 -8.8125l1.34375 0l0 1.25q0.96875 -1.453125 2.796875 -1.453125q0.796875 0 1.46875 0.296875q0.671875 0.28125 1.0 0.75q0.328125 0.453125 0.46875 1.09375q0.078125 0.421875 0.078125 1.453125l0 5.421875l-1.484375 0l0 -5.359375q0 -0.921875 -0.1875 -1.375q-0.171875 -0.453125 -0.625 -0.71875q-0.4375 -0.265625 -1.03125 -0.265625q-0.953125 0 -1.65625 0.609375q-0.6875 0.59375 -0.6875 2.296875l0 4.8125l-1.484375 0zm12.90271 -1.34375l0.203125 1.328125q-0.625 0.125 -1.125 0.125q-0.8125 0 -1.265625 -0.25q-0.4375 -0.265625 -0.625 -0.671875q-0.1875 -0.421875 -0.1875 -1.765625l0 -5.078125l-1.09375 0l0 -1.15625l1.09375 0l0 -2.1875l1.484375 -0.890625l0 3.078125l1.515625 0l0 1.15625l-1.515625 0l0 5.15625q0 0.640625 0.078125 0.828125q0.078125 0.171875 0.25 0.28125q0.1875 0.109375 0.53125 0.109375q0.234375 0 0.65625 -0.0625z" fill-rule="nonzero"></path><path fill="#f1c232" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.199474 154.00525l156.18898 0l0 70.99213l-156.18898 0z" fill-rule="nonzero"></path><path fill="#000000" d="m45.465923 185.42131l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm19.707325 -1.21875q-0.9375 0.796875 -1.7968788 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.0312538 -0.25 2.9843788 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.6406288 -0.5625 -1.9062538 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.2656288 0 2.0468788 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.7343788 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.7500038 -0.4375 1.1093788 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.078842 4.9375l0 -9.859375l1.5 0l0 1.390625q0.453125 -0.71875 1.21875 -1.15625q0.78125 -0.453125 1.765625 -0.453125q1.09375 0 1.796875 0.453125q0.703125 0.453125 0.984375 1.28125q1.171875 -1.734375 3.046875 -1.734375q1.46875 0 2.25 0.8125q0.796875 0.8125 0.796875 2.5l0 6.765625l-1.671875 0l0 -6.203125q0 -1.0 -0.15625 -1.4375q-0.15625 -0.453125 -0.59375 -0.71875q-0.421875 -0.265625 -1.0 -0.265625q-1.03125 0 -1.71875 0.6875q-0.6875 0.6875 -0.6875 2.21875l0 5.71875l-1.671875 0l0 -6.40625q0 -1.109375 -0.40625 -1.65625q-0.40625 -0.5625 -1.34375 -0.5625q-0.703125 0 -1.3125 0.375q-0.59375 0.359375 -0.859375 1.078125q-0.265625 0.71875 -0.265625 2.0625l0 5.109375l-1.671875 0zm22.290802 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm14.543396 5.875l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm18.176071 4.421875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.438217 2.9375l1.65625 -0.265625q0.140625 1.0 0.765625 1.53125q0.640625 0.515625 1.78125 0.515625q1.15625 0 1.703125 -0.46875q0.5625 -0.46875 0.5625 -1.09375q0 -0.5625 -0.484375 -0.890625q-0.34375 -0.21875 -1.703125 -0.5625q-1.84375 -0.46875 -2.5625 -0.796875q-0.703125 -0.34375 -1.078125 -0.9375q-0.359375 -0.609375 -0.359375 -1.328125q0 -0.65625 0.296875 -1.21875q0.3125 -0.5625 0.828125 -0.9375q0.390625 -0.28125 1.0625 -0.484375q0.671875 -0.203125 1.4375 -0.203125q1.171875 0 2.046875 0.34375q0.875 0.328125 1.28125 0.90625q0.421875 0.5625 0.578125 1.515625l-1.625 0.21875q-0.109375 -0.75 -0.65625 -1.171875q-0.53125 -0.4375 -1.5 -0.4375q-1.15625 0 -1.640625 0.390625q-0.484375 0.375 -0.484375 0.875q0 0.328125 0.203125 0.59375q0.203125 0.265625 0.640625 0.4375q0.25 0.09375 1.46875 0.4375q1.765625 0.46875 2.46875 0.765625q0.703125 0.296875 1.09375 0.875q0.40625 0.578125 0.40625 1.4375q0 0.828125 -0.484375 1.578125q-0.484375 0.734375 -1.40625 1.140625q-0.921875 0.390625 -2.078125 0.390625q-1.921875 0 -2.9375 -0.796875q-1.0 -0.796875 -1.28125 -2.359375zm9.375 -1.984375q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250717 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm6.910446 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" d="m73.85669 211.42131q-1.375 -1.75 -2.328125 -4.078125q-0.953125 -2.34375 -0.953125 -4.84375q0 -2.21875 0.703125 -4.234375q0.84375 -2.34375 2.578125 -4.671875l1.203125 0q-1.125 1.921875 -1.484375 2.75q-0.5625 1.28125 -0.890625 2.671875q-0.40625 1.734375 -0.40625 3.484375q0 4.46875 2.78125 8.921875l-1.203125 0zm9.775177 -7.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm8.813217 6.6875l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm14.699646 5.109375l0 -13.59375l4.6875 0q1.578125 0 2.421875 0.1875q1.15625 0.265625 1.984375 0.96875q1.078125 0.921875 1.609375 2.34375q0.53125 1.40625 0.53125 3.21875q0 1.546875 -0.359375 2.75q-0.359375 1.1875 -0.921875 1.984375q-0.5625 0.78125 -1.234375 1.234375q-0.671875 0.4375 -1.625 0.671875q-0.953125 0.234375 -2.1875 0.234375l-4.90625 0zm1.796875 -1.609375l2.90625 0q1.34375 0 2.109375 -0.25q0.765625 -0.25 1.21875 -0.703125q0.640625 -0.640625 1.0 -1.71875q0.359375 -1.078125 0.359375 -2.625q0 -2.125 -0.703125 -3.265625q-0.703125 -1.15625 -1.703125 -1.546875q-0.71875 -0.28125 -2.328125 -0.28125l-2.859375 0l0 10.390625zm11.660446 1.609375l0 -13.59375l1.84375 0l7.140625 10.671875l0 -10.671875l1.71875 0l0 13.59375l-1.84375 0l-7.140625 -10.6875l0 10.6875l-1.71875 0zm12.879196 -4.375l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm13.927948 8.375l-1.1875 0q2.765625 -4.453125 2.765625 -8.921875q0 -1.734375 -0.390625 -3.453125q-0.328125 -1.390625 -0.890625 -2.671875q-0.359375 -0.84375 -1.484375 -2.78125l1.1875 0q1.75 2.328125 2.578125 4.671875q0.71875 2.015625 0.71875 4.234375q0 2.5 -0.96875 4.84375q-0.953125 2.328125 -2.328125 4.078125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m248.70341 189.50131l-62.29921 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m236.70341 189.50131l-38.29921 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m236.70341 192.80478l9.076187 -3.3034668l-9.076187 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m198.4042 186.19785l-9.076202 3.3034668l9.076202 3.3034668z" fill-rule="evenodd"></path><path fill="#e06666" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.08136 158.99738l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m492.37677 197.23381l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.281952 5.109375l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm6.228302 3.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm15.297607 1.265625l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.859375 3.609375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm5.7229614 0l-1.546875 0l0 -13.59375l1.65625 0l0 4.84375q1.0625 -1.328125 2.703125 -1.328125q0.90625 0 1.71875 0.375q0.8125 0.359375 1.328125 1.03125q0.53125 0.65625 0.828125 1.59375q0.296875 0.9375 0.296875 2.0q0 2.53125 -1.25 3.921875q-1.25 1.375 -3.0 1.375q-1.75 0 -2.734375 -1.453125l0 1.234375zm-0.015625 -5.0q0 1.765625 0.46875 2.5625q0.796875 1.28125 2.140625 1.28125q1.09375 0 1.890625 -0.9375q0.796875 -0.953125 0.796875 -2.84375q0 -1.921875 -0.765625 -2.84375q-0.765625 -0.921875 -1.84375 -0.921875q-1.09375 0 -1.890625 0.953125q-0.796875 0.953125 -0.796875 2.75zm14.027771 8.78125l0 -13.640625l1.53125 0l0 1.28125q0.53125 -0.75 1.203125 -1.125q0.6875 -0.375 1.640625 -0.375q1.265625 0 2.234375 0.65625q0.96875 0.640625 1.453125 1.828125q0.5 1.1875 0.5 2.59375q0 1.515625 -0.546875 2.734375q-0.546875 1.203125 -1.578125 1.84375q-1.03125 0.640625 -2.171875 0.640625q-0.84375 0 -1.515625 -0.34375q-0.65625 -0.359375 -1.078125 -0.890625l0 4.796875l-1.671875 0zm1.515625 -8.65625q0 1.90625 0.765625 2.8125q0.78125 0.90625 1.875 0.90625q1.109375 0 1.890625 -0.9375q0.796875 -0.9375 0.796875 -2.921875q0 -1.875 -0.78125 -2.8125q-0.765625 -0.9375 -1.84375 -0.9375q-1.0625 0 -1.890625 1.0q-0.8125 1.0 -0.8125 2.890625zm8.235046 -0.046875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.03125 0 3.3125 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.25 0 2.0625 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.0625 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm9.250732 4.921875l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm4.1917114 -11.6875l0 -1.90625l1.671875 0l0 1.90625l-1.671875 0zm0 11.6875l0 -9.859375l1.671875 0l0 9.859375l-1.671875 0zm10.566711 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm2.8125 7.40625l-0.171875 -1.5625q0.546875 0.140625 0.953125 0.140625q0.546875 0 0.875 -0.1875q0.34375 -0.1875 0.5625 -0.515625q0.15625 -0.25 0.5 -1.25q0.046875 -0.140625 0.15625 -0.40625l-3.734375 -9.875l1.796875 0l2.046875 5.71875q0.40625 1.078125 0.71875 2.28125q0.28125 -1.15625 0.6875 -2.25l2.09375 -5.75l1.671875 0l-3.75 10.03125q-0.59375 1.625 -0.9375 2.234375q-0.4375 0.828125 -1.015625 1.203125q-0.578125 0.390625 -1.375 0.390625q-0.484375 0 -1.078125 -0.203125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m195.75066 158.99738l27.716537 0l0 32.53543l-27.716537 0z" fill-rule="nonzero"></path><path fill="#000000" d="m210.74643 180.79738l-1.140625 0l0 -7.28125q-0.421875 0.390625 -1.09375 0.796875q-0.65625 0.390625 -1.1875 0.578125l0 -1.109375q0.953125 -0.4375 1.671875 -1.078125q0.71875 -0.640625 1.015625 -1.25l0.734375 0l0 9.34375z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m392.7034 189.50131l82.39371 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m404.7034 189.50131l58.393707 0" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m404.7034 186.19785l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m463.0971 192.80478l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m475.0819 388.34384l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m489.2755 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644836 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349792 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.34375 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584229 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094421 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.9627075 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m252.63937 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m266.83298 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547607 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644806 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.3437805 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094452 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962677 0l-3.75 -9.859375l1.765625 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l-215.08661 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m311.25372 227.40143l-196.18726 153.55408" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m313.28983 230.00282l5.1111755 -8.195496l-9.18335 2.9927216z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m113.030396 378.35413l-5.111183 8.195496l9.18335 -2.9927063z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l0.12600708 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m320.7124 232.00525l0.10800171 144.34647" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m324.01587 232.00278l-3.3102722 -9.07373l-3.2966614 9.078674z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m317.51694 376.3542l3.3102722 9.07373l3.2966614 -9.078674z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m320.7034 220.00525l222.58267 168.34647" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m330.27423 227.24397l203.44104 153.869" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m332.267 224.60924l-9.231659 -2.840271l5.246155 8.109756z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m531.72253 383.7477l9.231628 2.840271l-5.246155 -8.109741z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m412.22308 158.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m429.33276 179.70363l0 1.09375l-6.15625 0q-0.015625 -0.40625 0.140625 -0.796875q0.234375 -0.625 0.75 -1.234375q0.515625 -0.609375 1.5 -1.40625q1.515625 -1.25 2.046875 -1.96875q0.53125 -0.734375 0.53125 -1.375q0 -0.6875 -0.484375 -1.140625q-0.484375 -0.46875 -1.265625 -0.46875q-0.828125 0 -1.328125 0.5q-0.484375 0.484375 -0.5 1.359375l-1.171875 -0.125q0.125 -1.3125 0.90625 -2.0q0.78125 -0.6875 2.109375 -0.6875q1.34375 0 2.125 0.75q0.78125 0.734375 0.78125 1.828125q0 0.5625 -0.234375 1.109375q-0.21875 0.53125 -0.75 1.140625q-0.53125 0.59375 -1.765625 1.625q-1.03125 0.859375 -1.328125 1.171875q-0.28125 0.3125 -0.46875 0.625l4.5625 0zm2.0218506 1.09375l0 -1.296875l1.296875 0l0 1.296875q0 0.71875 -0.25 1.15625q-0.25 0.4375 -0.8125 0.6875l-0.3125 -0.484375q0.359375 -0.171875 0.53125 -0.484375q0.171875 -0.296875 0.1875 -0.875l-0.640625 0zm3.093628 -2.453125l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.25l-1.140625 -0.203125q0.21875 -1.140625 0.953125 -1.765625q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.203125q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m287.22308 247.99738l39.653564 0l0 32.53543l-39.653564 0z" fill-rule="nonzero"></path><path fill="#000000" d="m307.54675 269.79736l0 -2.234375l-4.03125 0l0 -1.046875l4.234375 -6.03125l0.9375 0l0 6.03125l1.265625 0l0 1.046875l-1.265625 0l0 2.234375l-1.140625 0zm0 -3.28125l0 -4.1875l-2.921875 4.1875l2.921875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m629.2467 241.13911l53.480347 0l0 32.535416l-53.480347 0z" fill-rule="nonzero"></path><path fill="#000000" d="m638.7936 260.486l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875153q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.2500153l-1.140625 -0.203125q0.21875 -1.1406403 0.953125 -1.7656403q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.2031403q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625zm12.115601 1.625q-0.625 0.53125 -1.21875 0.765625q-0.578125 0.21875 -1.25 0.21875q-1.125 0 -1.71875 -0.546875q-0.59375 -0.546875 -0.59375 -1.390625q0 -0.484375 0.21875 -0.890625q0.234375 -0.421875 0.59375 -0.671875q0.375 -0.25 0.828125 -0.375q0.328125 -0.078125 1.015625 -0.171875q1.375 -0.15625 2.03125 -0.390625q0.015625 -0.234375 0.015625 -0.296875q0 -0.703125 -0.328125 -0.984375q-0.4375 -0.390625 -1.296875 -0.390625q-0.8125 0 -1.203125 0.28125q-0.375 0.28125 -0.5625 1.0l-1.109375 -0.140625q0.140625 -0.71875 0.484375 -1.15625q0.359375 -0.453125 1.015625 -0.6875q0.671875 -0.234375 1.53125 -0.234375q0.875 0 1.40625 0.203125q0.546875 0.203125 0.796875 0.515625q0.25 0.296875 0.359375 0.765625q0.046875 0.296875 0.046875 1.0625l0 1.515625q0 1.59375 0.078125 2.015625q0.078125 0.421875 0.28125 0.8125l-1.1875 0q-0.171875 -0.359375 -0.234375 -0.828125zm-0.09375 -2.5625q-0.625 0.265625 -1.859375 0.4375q-0.703125 0.109375 -1.0 0.234375q-0.296875 0.125 -0.453125 0.375q-0.15625 0.234375 -0.15625 0.53125q0 0.453125 0.34375 0.765625q0.34375 0.296875 1.015625 0.296875q0.65625 0 1.171875 -0.28125q0.515625 -0.296875 0.765625 -0.796875q0.171875 -0.375 0.171875 -1.140625l0 -0.421875zm3.4124756 3.390625l0 -1.296875l1.296875 0l0 1.296875q0 0.71875 -0.25 1.15625q-0.25 0.4375 -0.8125 0.6875l-0.3125 -0.484375q0.359375 -0.171875 0.53125 -0.484375q0.171875 -0.296875 0.1875 -0.875l-0.640625 0zm3.093628 -2.453125l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875153q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.2500153l-1.140625 -0.203125q0.21875 -1.1406403 0.953125 -1.7656403q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.2031403q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625zm12.115601 -0.015625l1.125 0.140625q-0.171875 1.171875 -0.9375 1.828125q-0.765625 0.65625 -1.859375 0.65625q-1.390625 0 -2.234375 -0.90625q-0.828125 -0.90625 -0.828125 -2.59375q0 -1.09375 0.359375 -1.90625q0.359375 -0.828125 1.09375 -1.234375q0.734375 -0.40625 1.609375 -0.40625q1.09375 0 1.796875 0.5625q0.703125 0.546875 0.890625 1.5625l-1.109375 0.171875q-0.15625 -0.671875 -0.5625 -1.015625q-0.390625 -0.34375 -0.96875 -0.34375q-0.859375 0 -1.40625 0.625q-0.53125 0.609375 -0.53125 1.953125q0 1.359375 0.515625 1.984375q0.515625 0.609375 1.359375 0.609375q0.671875 0 1.125 -0.40625q0.453125 -0.421875 0.5625 -1.28125z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m30.19843 388.34384l136.37796 0l0 61.007874l-136.37796 0z" fill-rule="nonzero"></path><path fill="#000000" d="m44.392044 426.58026l1.609375 0.25q0.109375 0.75 0.578125 1.09375q0.609375 0.453125 1.6875 0.453125q1.171875 0 1.796875 -0.46875q0.625 -0.453125 0.859375 -1.28125q0.125 -0.515625 0.109375 -2.15625q-1.09375 1.296875 -2.71875 1.296875q-2.03125 0 -3.15625 -1.46875q-1.109375 -1.46875 -1.109375 -3.515625q0 -1.40625 0.515625 -2.59375q0.515625 -1.203125 1.484375 -1.84375q0.96875 -0.65625 2.265625 -0.65625q1.75 0 2.875 1.40625l0 -1.1875l1.546875 0l0 8.515625q0 2.3125 -0.46875 3.265625q-0.46875 0.96875 -1.484375 1.515625q-1.015625 0.5625 -2.5 0.5625q-1.765625 0 -2.859375 -0.796875q-1.078125 -0.796875 -1.03125 -2.390625zm1.375 -5.921875q0 1.953125 0.765625 2.84375q0.78125 0.890625 1.9375 0.890625q1.140625 0 1.921875 -0.890625q0.78125 -0.890625 0.78125 -2.78125q0 -1.8125 -0.8125 -2.71875q-0.796875 -0.921875 -1.921875 -0.921875q-1.109375 0 -1.890625 0.90625q-0.78125 0.890625 -0.78125 2.671875zm9.547592 5.109375l0 -13.59375l6.03125 0q1.8125 0 2.75 0.359375q0.953125 0.359375 1.515625 1.296875q0.5625 0.921875 0.5625 2.046875q0 1.453125 -0.9375 2.453125q-0.921875 0.984375 -2.890625 1.25q0.71875 0.34375 1.09375 0.671875q0.78125 0.734375 1.484375 1.8125l2.375 3.703125l-2.265625 0l-1.796875 -2.828125q-0.796875 -1.21875 -1.3125 -1.875q-0.5 -0.65625 -0.90625 -0.90625q-0.40625 -0.265625 -0.8125 -0.359375q-0.3125 -0.078125 -1.015625 -0.078125l-2.078125 0l0 6.046875l-1.796875 0zm1.796875 -7.59375l3.859375 0q1.234375 0 1.921875 -0.25q0.703125 -0.265625 1.0625 -0.828125q0.375 -0.5625 0.375 -1.21875q0 -0.96875 -0.703125 -1.578125q-0.703125 -0.625 -2.21875 -0.625l-4.296875 0l0 4.5zm11.644821 7.59375l0 -13.59375l5.125 0q1.359375 0 2.078125 0.125q1.0 0.171875 1.671875 0.640625q0.671875 0.46875 1.078125 1.3125q0.421875 0.84375 0.421875 1.84375q0 1.734375 -1.109375 2.9375q-1.09375 1.203125 -3.984375 1.203125l-3.484375 0l0 5.53125l-1.796875 0zm1.796875 -7.140625l3.515625 0q1.75 0 2.46875 -0.640625q0.734375 -0.65625 0.734375 -1.828125q0 -0.859375 -0.4375 -1.46875q-0.421875 -0.609375 -1.125 -0.796875q-0.453125 -0.125 -1.671875 -0.125l-3.484375 0l0 4.859375zm20.349823 2.375l1.796875 0.453125q-0.5625 2.21875 -2.03125 3.390625q-1.46875 1.15625 -3.59375 1.15625q-2.203125 0 -3.578125 -0.890625q-1.375 -0.90625 -2.09375 -2.59375q-0.71875 -1.703125 -0.71875 -3.65625q0 -2.125 0.796875 -3.703125q0.8125 -1.578125 2.3125 -2.390625q1.5 -0.828125 3.296875 -0.828125q2.046875 0 3.4375 1.046875q1.390625 1.03125 1.9375 2.90625l-1.765625 0.421875q-0.46875 -1.484375 -1.375 -2.15625q-0.90625 -0.6875 -2.265625 -0.6875q-1.5625 0 -2.625 0.75q-1.046875 0.75 -1.484375 2.03125q-0.421875 1.265625 -0.421875 2.609375q0 1.734375 0.5 3.03125q0.515625 1.28125 1.578125 1.921875q1.078125 0.640625 2.3125 0.640625q1.515625 0 2.5625 -0.859375q1.046875 -0.875 1.421875 -2.59375zm8.343758 0.390625l1.6875 -0.140625q0.125 1.015625 0.5625 1.671875q0.4375 0.65625 1.359375 1.0625q0.9375 0.40625 2.09375 0.40625q1.03125 0 1.8125 -0.3125q0.796875 -0.3125 1.1875 -0.84375q0.390625 -0.53125 0.390625 -1.15625q0 -0.640625 -0.375 -1.109375q-0.375 -0.484375 -1.234375 -0.8125q-0.546875 -0.21875 -2.421875 -0.65625q-1.875 -0.453125 -2.625 -0.859375q-0.96875 -0.515625 -1.453125 -1.265625q-0.46875 -0.75 -0.46875 -1.6875q0 -1.03125 0.578125 -1.921875q0.59375 -0.90625 1.703125 -1.359375q1.125 -0.46875 2.5 -0.46875q1.515625 0 2.671875 0.484375q1.15625 0.484375 1.765625 1.4375q0.625 0.9375 0.671875 2.140625l-1.71875 0.125q-0.140625 -1.28125 -0.953125 -1.9375q-0.796875 -0.671875 -2.359375 -0.671875q-1.625 0 -2.375 0.609375q-0.75 0.59375 -0.75 1.4375q0 0.734375 0.53125 1.203125q0.515625 0.46875 2.703125 0.96875q2.203125 0.5 3.015625 0.875q1.1875 0.546875 1.75 1.390625q0.578125 0.828125 0.578125 1.921875q0 1.09375 -0.625 2.0625q-0.625 0.953125 -1.796875 1.484375q-1.15625 0.53125 -2.609375 0.53125q-1.84375 0 -3.09375 -0.53125q-1.25 -0.546875 -1.96875 -1.625q-0.703125 -1.078125 -0.734375 -2.453125zm19.584198 1.203125l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0zm8.962669 0l-3.7499924 -9.859375l1.7656174 0l2.125 5.90625q0.34375 0.953125 0.625 1.984375q0.21875 -0.78125 0.625 -1.875l2.1875 -6.015625l1.71875 0l-3.734375 9.859375l-1.5625 0zm13.34375 -3.171875l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094467 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#6d9eeb" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m711.31287 273.67322l136.37793 0l0 61.007874l-136.37793 0z" fill-rule="nonzero"></path><path fill="#000000" d="m760.14105 300.09717l0 -13.59375l1.796875 0l0 11.984375l6.703125 0l0 1.609375l-8.5 0zm9.610046 -4.921875q0 -2.734375 1.53125 -4.0625q1.265625 -1.09375 3.09375 -1.09375q2.031311 0 3.312561 1.34375q1.296875 1.328125 1.296875 3.671875q0 1.90625 -0.578125 3.0q-0.5625 1.078125 -1.65625 1.6875q-1.078125 0.59375 -2.375061 0.59375q-2.0625 0 -3.34375 -1.328125q-1.28125 -1.328125 -1.28125 -3.8125zm1.71875 0q0 1.890625 0.828125 2.828125q0.828125 0.9375 2.078125 0.9375q1.250061 0 2.062561 -0.9375q0.828125 -0.953125 0.828125 -2.890625q0 -1.828125 -0.828125 -2.765625q-0.828125 -0.9375 -2.062561 -0.9375q-1.25 0 -2.078125 0.9375q-0.828125 0.9375 -0.828125 2.828125zm15.719482 3.703125q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm10.469482 4.9375l0 -1.25q-0.9375 1.46875 -2.75 1.46875q-1.171875 0 -2.171875 -0.640625q-0.984375 -0.65625 -1.53125 -1.8125q-0.53125 -1.171875 -0.53125 -2.6875q0 -1.46875 0.484375 -2.671875q0.5 -1.203125 1.46875 -1.84375q0.984375 -0.640625 2.203125 -0.640625q0.890625 0 1.578125 0.375q0.703125 0.375 1.140625 0.984375l0 -4.875l1.65625 0l0 13.59375l-1.546875 0zm-5.28125 -4.921875q0 1.890625 0.796875 2.828125q0.8125 0.9375 1.890625 0.9375q1.09375 0 1.859375 -0.890625q0.765625 -0.890625 0.765625 -2.734375q0 -2.015625 -0.78125 -2.953125q-0.78125 -0.953125 -1.921875 -0.953125q-1.109375 0 -1.859375 0.90625q-0.75 0.90625 -0.75 2.859375z" fill-rule="nonzero"></path><path fill="#000000" d="m744.0764 322.09717l0 -13.59375l5.109375 0q1.546875 0 2.484375 0.40625q0.953125 0.40625 1.484375 1.265625q0.53125 0.859375 0.53125 1.796875q0 0.875 -0.46875 1.65625q-0.46875 0.765625 -1.4375 1.234375q1.234375 0.359375 1.890625 1.234375q0.671875 0.875 0.671875 2.0625q0 0.953125 -0.40625 1.78125q-0.390625 0.8125 -0.984375 1.265625q-0.59375 0.4375 -1.5 0.671875q-0.890625 0.21875 -2.1875 0.21875l-5.1875 0zm1.796875 -7.890625l2.9375 0q1.203125 0 1.71875 -0.15625q0.6875 -0.203125 1.03125 -0.671875q0.359375 -0.46875 0.359375 -1.1875q0 -0.671875 -0.328125 -1.1875q-0.328125 -0.515625 -0.9375 -0.703125q-0.59375 -0.203125 -2.0625 -0.203125l-2.71875 0l0 4.109375zm0 6.28125l3.390625 0q0.875 0 1.21875 -0.0625q0.625 -0.109375 1.046875 -0.359375q0.421875 -0.265625 0.6875 -0.765625q0.265625 -0.5 0.265625 -1.140625q0 -0.765625 -0.390625 -1.328125q-0.390625 -0.5625 -1.078125 -0.78125q-0.6875 -0.234375 -1.984375 -0.234375l-3.15625 0l0 4.671875zm16.943604 0.390625q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0476074 4.9375l0 -13.59375l1.671875 0l0 13.59375l-1.671875 0zm10.613525 -1.21875q-0.9375 0.796875 -1.796875 1.125q-0.859375 0.3125 -1.84375 0.3125q-1.609375 0 -2.484375 -0.78125q-0.875 -0.796875 -0.875 -2.03125q0 -0.734375 0.328125 -1.328125q0.328125 -0.59375 0.859375 -0.953125q0.53125 -0.359375 1.203125 -0.546875q0.5 -0.140625 1.484375 -0.25q2.03125 -0.25 2.984375 -0.578125q0 -0.34375 0 -0.4375q0 -1.015625 -0.46875 -1.4375q-0.640625 -0.5625 -1.90625 -0.5625q-1.171875 0 -1.734375 0.40625q-0.5625 0.40625 -0.828125 1.46875l-1.640625 -0.234375q0.234375 -1.046875 0.734375 -1.6875q0.515625 -0.640625 1.46875 -0.984375q0.96875 -0.359375 2.25 -0.359375q1.265625 0 2.046875 0.296875q0.78125 0.296875 1.15625 0.75q0.375 0.453125 0.515625 1.140625q0.09375 0.421875 0.09375 1.53125l0 2.234375q0 2.328125 0.09375 2.953125q0.109375 0.609375 0.4375 1.171875l-1.75 0q-0.265625 -0.515625 -0.328125 -1.21875zm-0.140625 -3.71875q-0.90625 0.359375 -2.734375 0.625q-1.03125 0.140625 -1.453125 0.328125q-0.421875 0.1875 -0.65625 0.546875q-0.234375 0.359375 -0.234375 0.796875q0 0.671875 0.5 1.125q0.515625 0.4375 1.484375 0.4375q0.96875 0 1.71875 -0.421875q0.75 -0.4375 1.109375 -1.15625q0.265625 -0.578125 0.265625 -1.671875l0 -0.609375zm4.0788574 4.9375l0 -9.859375l1.5 0l0 1.40625q1.09375 -1.625 3.140625 -1.625q0.890625 0 1.640625 0.328125q0.75 0.3125 1.109375 0.84375q0.375 0.515625 0.53125 1.21875q0.09375 0.46875 0.09375 1.625l0 6.0625l-1.671875 0l0 -6.0q0 -1.015625 -0.203125 -1.515625q-0.1875 -0.515625 -0.6875 -0.8125q-0.5 -0.296875 -1.171875 -0.296875q-1.0625 0 -1.84375 0.671875q-0.765625 0.671875 -0.765625 2.578125l0 5.375l-1.671875 0zm16.813232 -3.609375l1.640625 0.21875q-0.265625 1.6875 -1.375 2.65625q-1.109375 0.953125 -2.734375 0.953125q-2.015625 0 -3.25 -1.3125q-1.21875 -1.328125 -1.21875 -3.796875q0 -1.59375 0.515625 -2.78125q0.53125 -1.203125 1.609375 -1.796875q1.09375 -0.609375 2.359375 -0.609375q1.609375 0 2.625 0.8125q1.015625 0.8125 1.3125 2.3125l-1.625 0.25q-0.234375 -1.0 -0.828125 -1.5q-0.59375 -0.5 -1.421875 -0.5q-1.265625 0 -2.0625 0.90625q-0.78125 0.90625 -0.78125 2.859375q0 1.984375 0.765625 2.890625q0.765625 0.890625 1.984375 0.890625q0.984375 0 1.640625 -0.59375q0.65625 -0.609375 0.84375 -1.859375zm9.640625 0.4375l1.71875 0.21875q-0.40625 1.5 -1.515625 2.34375q-1.09375 0.828125 -2.8125 0.828125q-2.15625 0 -3.421875 -1.328125q-1.265625 -1.328125 -1.265625 -3.734375q0 -2.484375 1.265625 -3.859375q1.28125 -1.375 3.328125 -1.375q1.984375 0 3.234375 1.34375q1.25 1.34375 1.25 3.796875q0 0.140625 -0.015625 0.4375l-7.34375 0q0.09375 1.625 0.921875 2.484375q0.828125 0.859375 2.0625 0.859375q0.90625 0 1.546875 -0.46875q0.65625 -0.484375 1.046875 -1.546875zm-5.484375 -2.703125l5.5 0q-0.109375 -1.234375 -0.625 -1.859375q-0.796875 -0.96875 -2.078125 -0.96875q-1.140625 0 -1.9375 0.78125q-0.78125 0.765625 -0.859375 2.046875zm9.094482 5.875l0 -9.859375l1.5 0l0 1.5q0.578125 -1.046875 1.0625 -1.375q0.484375 -0.34375 1.078125 -0.34375q0.84375 0 1.71875 0.546875l-0.578125 1.546875q-0.609375 -0.359375 -1.234375 -0.359375q-0.546875 0 -0.984375 0.328125q-0.421875 0.328125 -0.609375 0.90625q-0.28125 0.890625 -0.28125 1.953125l0 5.15625l-1.671875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 -84.15747" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m700.5833 298.80334l-146.57245 -73.40985" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m699.104 301.75708l9.5946045 1.1107483l-6.6359253 -7.0181885z" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m555.49023 222.43977l-9.5946045 -1.1107635l6.6359253 7.0181885z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-612.9134 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.4244 305.80954l-589.1365 80.89273" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m699.8737 309.0823l8.54248 -4.507416l-9.441223 -2.0381165z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m109.83856 383.4295l-8.54245 4.507416l9.4412 2.0381165z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-390.4882 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m699.5822 306.70535l-367.02686 79.101105" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m700.27814 309.93466l8.176514 -5.14151l-9.568481 -1.3171387z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m331.85934 382.57715l-8.176483 5.14151l9.568451 1.3171387z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m711.31287 304.17715l-168.0315 84.1575" fill-rule="nonzero"></path><path stroke="#999999" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" stroke-dasharray="8.0,6.0" d="m700.5833 309.55096l-146.57245 73.40988" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m702.0627 312.50467l6.6359253 -7.0181885l-9.5946045 1.1107788z" fill-rule="evenodd"></path><path fill="#999999" stroke="#999999" stroke-width="2.0" stroke-linecap="butt" d="m552.53156 380.00714l-6.6359253 7.0181885l9.5946045 -1.1107788z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m538.70605 294.4908l39.653503 0l0 32.53543l-39.653503 0z" fill-rule="nonzero"></path><path fill="#000000" d="m551.66724 313.83768l1.140625 -0.15625q0.203125 0.96875 0.671875 1.40625q0.46875 0.421875 1.15625 0.421875q0.796875 0 1.34375 -0.546875q0.5625 -0.5625 0.5625 -1.390625q0 -0.796875 -0.515625 -1.296875q-0.5 -0.515625 -1.296875 -0.515625q-0.328125 0 -0.8125 0.125l0.125 -1.0q0.125 0.015625 0.1875 0.015625q0.734375 0 1.3125 -0.375q0.59375 -0.390625 0.59375 -1.1875q0 -0.625 -0.4375 -1.03125q-0.421875 -0.421875 -1.09375 -0.421875q-0.671875 0 -1.109375 0.421875q-0.4375 0.421875 -0.578125 1.25l-1.140625 -0.203125q0.21875 -1.140625 0.953125 -1.765625q0.75 -0.640625 1.84375 -0.640625q0.765625 0 1.40625 0.328125q0.640625 0.328125 0.984375 0.890625q0.34375 0.5625 0.34375 1.203125q0 0.59375 -0.328125 1.09375q-0.328125 0.5 -0.953125 0.78125q0.8125 0.203125 1.265625 0.796875q0.46875 0.59375 0.46875 1.5q0 1.21875 -0.890625 2.078125q-0.890625 0.84375 -2.25 0.84375q-1.21875 0 -2.03125 -0.734375q-0.8125 -0.734375 -0.921875 -1.890625zm8.771851 2.453125l-1.0625 0l0 -9.3125l1.15625 0l0 3.328125q0.71875 -0.90625 1.84375 -0.90625q0.625 0 1.171875 0.25q0.5625 0.25 0.921875 0.703125q0.359375 0.453125 0.5625 1.09375q0.203125 0.640625 0.203125 1.375q0 1.734375 -0.859375 2.6875q-0.859375 0.9375 -2.0625 0.9375q-1.1875 0 -1.875 -1.0l0 0.84375zm-0.015625 -3.421875q0 1.21875 0.34375 1.75q0.53125 0.890625 1.453125 0.890625q0.75 0 1.296875 -0.65625q0.546875 -0.65625 0.546875 -1.9375q0 -1.328125 -0.53125 -1.953125q-0.515625 -0.625 -1.265625 -0.625q-0.75 0 -1.296875 0.65625q-0.546875 0.640625 -0.546875 1.875z" fill-rule="nonzero"></path></g></svg>
 
diff --git a/doc/load-balancing.md b/doc/load-balancing.md
index c5e59331c2..1071961b11 100644
--- a/doc/load-balancing.md
+++ b/doc/load-balancing.md
@@ -1,17 +1,25 @@
 Load Balancing in gRPC
-=======================
+======================
 
-# Objective
+# Scope
 
-To design a load balancing API between a gRPC client and a Load Balancer to
-instruct the client how to send load to multiple backend servers.
+This document explains the design for load balancing within gRPC.
 
 # Background
 
+## Per-Call Load Balancing
+
+It is worth noting that load-balancing within gRPC happens on a per-call
+basis, not a per-connection basis.  In other words, even if all requests
+come from a single client, we still want them to be load-balanced across
+all servers.
+
+## Approaches to Load Balancing
+
 Prior to any gRPC specifics, we explore some usual ways to approach load
 balancing.
 
-## Proxy Model
+### Proxy Model
 
 Using a proxy provides a solid trustable client that can report load to the load
 balancing system. Proxies typically require more resources to operate since they
@@ -21,7 +29,7 @@ latency to the RPCs.
 The proxy model was deemed inefficient when considering request heavy services
 like storage.
 
-## Balancing-aware Client
+### Balancing-aware Client
 
 This thicker client places more of the load balancing logic in the client. For
 example, the client could contain many load balancing policies (Round Robin,
@@ -41,7 +49,7 @@ It would also significantly complicate the client's code: the new design hides
 the load balancing complexity of multiple layers and presents it as a simple
 list of servers to the client.
 
-## External Load Balancing Service
+### External Load Balancing Service
 
 The client load balancing code is kept simple and portable, implementing
 well-known algorithms (e.g., Round Robin) for server selection.
@@ -104,9 +112,7 @@ works:
    a load balancer address, and a [service config](service_config.md)
    that indicates which client-side load-balancing policy to use (e.g.,
    `round_robin` or `grpclb`).
-2. The client instantiates the load balancing policy, which is then
-   responsible for deciding which requests will be sent to which
-   addresses.
+2. The client instantiates the load balancing policy.
    - Note: If all addresses returned by the resolver are balancer
      addresses, then the client will use the `grpclb` policy, regardless
      of what load-balancing policy was requested by the service config.
@@ -114,19 +120,28 @@ works:
      by the service config.  If no load-balancing policy is requested
      by the service config, then the client will default to a policy
      that picks the first available server address.
-3. In the case of the `grpclb` policy, it opens a stream to one of the
-   balancer addresses returned by the resolver. It asks the balancer for
-   the server addresses to use for the server name originally requested by
-   the client (i.e., the same one originally passed to the name resolver).
-   - Note: Currently, the `grpclb` policy ignores any non-balancer
-     addresses returned by the resolver. However, in the future, it may
-     be changed to use these addresses as a fallback in case no balancers
-     can be contacted.
-4. The gRPC servers to which the load balancer is directing the client
-   may report load to the load balancers, if that information is needed
-   by the load balancer's configuration.
-5. The load balancer returns a server list to the gRPC client. If the
-   server list is empty, the call will block until a non-empty one is
-   received.
-6. The gRPC client will send RPCs to the gRPC servers contained in
-   the server list from the Load Balancer.
+3. The load balancing policy creates a subchannel to each server address.
+   - For all policies *except* `grpclb`, this means one subchannel for each
+     address returned by the resolver. Note that these policies
+     ignore any balancer addresses returned by the resolver.
+   - In the case of the `grpclb` policy, the workflow is as follows:
+     a. The policy opens a stream to one of the balancer addresses returned
+        by the resolver. It asks the balancer for the server addresses to
+        use for the server name originally requested by the client (i.e.,
+        the same one originally passed to the name resolver).
+        - Note: The `grpclb` policy currently ignores any non-balancer
+          addresses returned by the resolver. However, in the future, it
+          may be changed to use these addresses as a fallback in case no
+          balancers can be contacted.
+     b. The gRPC servers to which the load balancer is directing the client
+        may report load to the load balancers, if that information is needed
+        by the load balancer's configuration.
+     c. The load balancer returns a server list to the gRPC client's `grpclb`
+        policy. The `grpclb` policy will then create a subchannel to each of
+        server in the list.
+4. For each RPC sent, the load balancing policy decides which
+   subchannel (i.e., which server) the RPC should be sent to.
+   - In the case of the `grpclb` policy, the client will send requests
+     to the servers in the order in which they were returned by the load
+     balancer.  If the server list is empty, the call will block until a
+     non-empty one is received.
diff --git a/doc/naming.md b/doc/naming.md
index 588f611f16..676aa9f298 100644
--- a/doc/naming.md
+++ b/doc/naming.md
@@ -20,12 +20,18 @@ uses the syntax:
 scheme://authority/endpoint_name
 ```
 
-Here, `scheme` indicates the name-system to be used. Example schemes to
-be supported include:
+Here, `scheme` indicates the name-system to be used. Currently, we
+support the following schemes:
 
-* `dns`
+- `dns`
 
-* `etcd`
+- `ipv4` (IPv4 address)
+
+- `ipv6` (IPv6 address)
+
+- `unix` (path to unix domain socket -- unix systems only)
+
+In the future, additional schemes such as `etcd` could be added.
 
 The `authority` indicates some scheme-specific bootstrap information, e.g.,
 for DNS, the authority may include the IP[:port] of the DNS server to
@@ -38,7 +44,7 @@ syntax of the endpoint name is dictated by the scheme in use.
 
 ### Resolver Plugins
 
-The gRPC client library will switch on the scheme to pick the right
+The gRPC client library will use the specified scheme to pick the right
 resolver plugin and pass it the fully qualified name string.
 
 Resolvers should be able to contact the authority and get a resolution
@@ -46,7 +52,7 @@ that they return back to the gRPC client library. The returned contents
 include:
 
 - A list of resolved addresses, each of which has three attributes:
-  - The address itself, in IP:port form.
+  - The address itself, including both IP address and port.
   - A boolean indicating whether the address is a backend address (i.e.,
     the address to use to contact the server directly) or a balancer
     address (for cases where [external load balancing](load-balancing.md)
-- 
GitLab


From e860359f231cdadc9ff1c8292ef869b91b8879d4 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 18 Jan 2017 09:22:26 -0800
Subject: [PATCH 334/344] Attempt to fix formatting.

---
 doc/load-balancing.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/load-balancing.md b/doc/load-balancing.md
index 1071961b11..f56d2b0c73 100644
--- a/doc/load-balancing.md
+++ b/doc/load-balancing.md
@@ -125,7 +125,7 @@ works:
      address returned by the resolver. Note that these policies
      ignore any balancer addresses returned by the resolver.
    - In the case of the `grpclb` policy, the workflow is as follows:
-     a. The policy opens a stream to one of the balancer addresses returned
+     1. The policy opens a stream to one of the balancer addresses returned
         by the resolver. It asks the balancer for the server addresses to
         use for the server name originally requested by the client (i.e.,
         the same one originally passed to the name resolver).
@@ -133,10 +133,10 @@ works:
           addresses returned by the resolver. However, in the future, it
           may be changed to use these addresses as a fallback in case no
           balancers can be contacted.
-     b. The gRPC servers to which the load balancer is directing the client
+     2. The gRPC servers to which the load balancer is directing the client
         may report load to the load balancers, if that information is needed
         by the load balancer's configuration.
-     c. The load balancer returns a server list to the gRPC client's `grpclb`
+     3. The load balancer returns a server list to the gRPC client's `grpclb`
         policy. The `grpclb` policy will then create a subchannel to each of
         server in the list.
 4. For each RPC sent, the load balancing policy decides which
-- 
GitLab


From d0f7bf4a76be6e0f8d8212c8ce91d054f478f29c Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Wed, 18 Jan 2017 11:49:22 -0800
Subject: [PATCH 335/344] Document new args in grpc_resolver_create

---
 src/core/ext/client_channel/resolver_registry.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
index 4fb16131db..a4606463eb 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/client_channel/resolver_registry.h
@@ -60,7 +60,9 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
     return it.
     If a resolver factory was not found, return NULL.
     \a args is a set of channel arguments to be included in the result
-    (typically the set of arguments passed in from the client API). */
+    (typically the set of arguments passed in from the client API).
+    \a pollset_set is used to drive IO in the name resolution process, it
+    should not be NULL. */
 grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
                                     const grpc_channel_args *args,
                                     grpc_pollset_set *pollset_set);
-- 
GitLab


From 8ebedd11df4837ec6be377f009817e3d5870cac9 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@users.noreply.github.com>
Date: Mon, 16 Jan 2017 19:55:42 +0100
Subject: [PATCH 336/344] Improve docs on windows building

---
 INSTALL.md           | 74 ++++++++++++++++++--------------------
 vsprojects/README.md | 85 ++++++++------------------------------------
 2 files changed, 50 insertions(+), 109 deletions(-)

diff --git a/INSTALL.md b/INSTALL.md
index 686145566f..24f088ea49 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -61,49 +61,45 @@ gRPC C Core library.
 There are several ways to build under Windows, of varying complexity depending
 on experience with the tools involved.
 
-<!--
-###Visual Studio
+###Pre-generated Visual Studio solution
 
-Versions 2013 and 2015 are both supported. You can use [their respective
-community
-editions](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx).
-
-Building the C Core:
-- Open [grpc.sln](https://github.com/grpc/grpc/blob/master/vsprojects/grpc.sln).
-- Select your build target.
-- Build the `grpc` project.
+The pre-generated VS projects & solution are checked into the repository under the [vsprojects](/vsprojects) directory.
+  
+###Building using CMake (with BoringSSL)
+- Install [CMake](https://cmake.org/download/).
+- Install [Active State Perl](http://www.activestate.com/activeperl/) (`choco install activeperl`)
+- Install [Ninja](https://ninja-build.org/) (`choco install ninja`)
+- Install [Go](https://golang.org/dl/) (`choco install golang`)
+- Install [yasm](http://yasm.tortall.net/) and add it to `PATH` (`choco install yasm`)
+- Run these commands in the repo root directory
+```
+> md .build
+> cd .build
+> call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x64
+> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
+> cmake --build .
+```
+NOTE: Currently you can only use Ninja to build using cmake on Windows (because of the boringssl dependency).
 
-Building the C++ runtime:
-- You need [CMake](https://cmake.org/) on your path to build protobuf (see below
-  for building using solely CMake).
-- Run `vsprojects/build_protos.bat` (needs `cmake.exe` in your path).
-- Open [buildtests_cxx.sln]()
-- Select your build target.
-- build the `grpc++` project.
--->
+###msys2 (with mingw)
 
-###msys2
+The Makefile (and source code) should support msys2's mingw32 and mingw64
+compilers. Building with msys2's native compiler is also possible, but
+difficult.
 
 This approach requires having [msys2](https://msys2.github.io/) installed.
+  
+```
+# Install prerequisites
+MSYS2$ pacman -S autoconf automake gcc libtool mingw-w64-x86_64-toolchain perl pkg-config zlib
+MSYS2$ pacman -S mingw-w64-x86_64-gflags
+```
 
-- The Makefile (and source code) should support msys2's mingw32 and mingw64
-  compilers. Building with msys2's native compiler is also possible, but
-  difficult.
-- The Makefile is expecting the Windows versions of OpenSSL (see
-  https://slproweb.com/products/Win32OpenSSL.html). It's also possible to build
-  the Windows version of OpenSSL from scratch. The output should be `libeay32`
-  and `ssleay32`.
-- If you are not installing the above files under msys2's path, you may specify
-  it, for instance, in the following way:
-  ```CPPFLAGS=”-I/c/OpenSSL-Win32/include” LDFLAGS=”-L/c/OpenSSL-Win32/lib” make static_c```
-- [protobuf3](https://github.com/google/protobuf/blob/master/src/README.md#c-installation---windows)
-  must be installed on the msys2 path.
-
-###Cmake (experimental)
+```
+# From mingw shell
+MINGW64$ export CPPFLAGS="-D_WIN32_WINNT=0x0600"
+MINGW64$ make
+```
 
-- Install [CMake](https://cmake.org/download/).
-- Run it over [grpc's
-  CMakeLists.txt](https://github.com/grpc/grpc/blob/master/CMakeLists.txt) to
-  generate "projects" for your compiler.
-- Build with your compiler of choice. The generated build files should have the
-  protobuf3 dependency baked in.
+NOTE: While most of the make targets are buildable under Mingw, some haven't been ported to Windows yet
+and may fail to build (mostly trying to include POSIX headers not available on Mingw).
diff --git a/vsprojects/README.md b/vsprojects/README.md
index afd6430bfe..f1663d2548 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -1,8 +1,8 @@
-This directory contains MS Visual Studio project & solution files.
+#Pre-generated MS Visual Studio project & solution files
 
-#Supported Visual Studio versions
-
-Currently supported versions are Visual Studio 2013 (our primary focus).
+Versions 2013 and 2015 are both supported. You can use [their respective
+community
+editions](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx).
 
 #Building
 We are using [NuGet](http://www.nuget.org) to pull zlib and openssl dependencies.
@@ -16,8 +16,8 @@ download nuget.exe from the web and manually restore the NuGet packages.
 ```
 
 After that, you can build the solution using one of these options:
-1. open `grpc.sln` with Visual Studio and hit "Build".
-2. build from commandline using `msbuild grpc.sln /p:Configuration=Debug`
+  1. open `grpc.sln` with Visual Studio and hit "Build".
+  2. build from commandline using `msbuild grpc.sln /p:Configuration=Debug`
 
 #C/C++ Test Dependencies
    * gtest isn't available as a git repo like the other dependencies.  download it and add it to `/third_party/gtest/` (the folder will end up with `/build-aux/`, `/cmake/`, `/codegear/`, etc. folders in it).  
@@ -36,73 +36,18 @@ After that, you can build the solution using one of these options:
    * install [NuGet](http://www.nuget.org)
     * nuget should automatically bring in built versions of zlib and openssl when building grpc.sln (the versions in `/third_party/` are not used).  If it doesn't work use `tools->nuget...->manage...`.  The packages are put in `/vsprojects/packages/`
 
-#C/C++ Test Solution/Project Build Steps
-   * A basic git version of grpc only has templates for non-test items.  This checklist adds test items to grpc.sln and makes individual vs projects for them
-   * set up dependencies (above)
-   * add `"debug": true,` to the top of build.json.  This is the base file for all build tracking, see [templates](https://github.com/grpc/grpc/tree/master/templates) for more information
-    * `"debug": true,` gets picked up by `/tools/buildgen/plugins/generate_vsprojects.py`.  It tells the script to add visual studio GUIDs to all projects.  Otherwise only the projects that already have GUIDs in build.json will be built
-   * run `/templates/vsprojects/generate_debug_projects.sh` to make debug templates/projects.  This runs a regular visual studio buildgen process, which creates the `.sln` file with all of the new debug projects, then uses git diff to find the new project names from the `.sln` that need templates added.  It builds the new templates based on the diff, then re-runs the visual studio buildgen, which builds the vs projects for each of the new debug targets
-    * copy over the `/vsprojects/` folder to your windows build setup (assuming this was built on linux in order to have easy access to python/mako and shell scripts)
-   * run `/templates/vsprojects/build_test_protos.sh`
-    * this builds all `.proto` files in `/test/` in-place.  there might be a better place to put them that mirrors what happens in the linux build process (todo)
-    * each `.proto` file gets built into a `.grpc.pb.cc`, .`grpc.pb.h`, `.pb.cc`, and `.pb.h`.  These are included in each test project in lieu of the `.proto` includes specified in `build.json`.  This substitution is done by `/templates/vsprojects/vcxproj_defs.include`
-    * copy over the `/test/` folder in order to get the new files (assuming this was built on linux in order to have an easy protobuf+grpc plugin installation)
-
-#Making and running tests with `/tools/run_tests/run_tests.py` or `/vsprojects/make.bat`
-`run_tests.py` and `make.bat` both rely on `/vsprojects/grpc.mak`, an NMAKE script that includes C/C++ tests in addition to the base grpc projects.  It builds the base projects by calling grpc.sln, but most things are built with a command line similar to a makefile workflow.
-
- arguments for `/vsprojects/make.bat`:
-
- * no options or `all` or `buildtests`: builds all tests
- * `buildtests_c`: just c tests
- * `buildtests_cxx`: just c++ tests
- * names of individual tests: just those tests (example: `make.bat gpr_string_test`)
-
-using `run_tests.py` on windows:
-
- * when `run_tests.py` detects that it's running on windows it calls `make.bat` to build the tests and expects to find tests in `/vsprojects/test_bins/`
-
-`run_tests.py` options:
-
- * `run_tests.py --help`
- * `run_tests.py -l c`: run c language tests
- * `run_tests.py -l c++`: run c++ language tests
- * note: `run_tests.py` doesn't normally show build steps, so if a build fails it is best to fall back to `make.bat`
- * if `make.bat` fails, it might be easier to open up the `.sln` file in the visual studio gui (see above for how to build the test projects) and build the offending test from its project file.  The `.mak` and project file templates are slightly different, so it's possible that a project will build one way and not another.  Please report this if it happens.
-
-It can be helpful to disable the firewall when running tests so that 400 connection warnings don't pop up.
-
-Individual tests can be run by directly running the executable in `/vsprojects/run_tests/` (this is `/bins/opt/` on linux).  Many C tests have no output; they either pass or fail internally and communicate this with their exit code (`0=pass`, `nonzero=fail`)
-
-`run_tests.py` will fail if it can't build something, so not-building tests are disabled with a "platforms = posix" note in build.json.  The buildgen tools will not add a test to a windows build unless it is marked "windows" or has no platforms identified.  As tests are ported they will get this mark removed.
-
 # Building protoc plugins
 For generating service stub code, gRPC relies on plugins for `protoc` (the protocol buffer compiler). The solution `grpc_protoc_plugins.sln` allows you to build
 Windows .exe binaries of gRPC protoc plugins.
 
-1. Follow instructions in `third_party\protobuf\cmake\README.md` to create Visual Studio 2013 projects for protobuf.
-```
-$ cd third_party/protobuf/cmake
-$ mkdir build & cd build
-$ mkdir solution & cd solution
-$ cmake -G "Visual Studio 12 2013" -Dprotobuf_BUILD_TESTS=OFF ../..
-```
-
-2. Open solution `third_party\protobuf\cmake\build\solution\protobuf.sln` and build it in Release mode. That will build libraries `libprotobuf.lib` and `libprotoc.lib` needed for the next step.
+- Follow instructions in `third_party\protobuf\cmake\README.md` to create Visual Studio 2013 projects for protobuf.
+  ```
+  $ cd third_party/protobuf/cmake
+  $ mkdir build & cd build
+  $ mkdir solution & cd solution
+  $ cmake -G "Visual Studio 12 2013" -Dprotobuf_BUILD_TESTS=OFF ../..
+  ```
 
-3. Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
+- Open solution `third_party\protobuf\cmake\build\solution\protobuf.sln` and build it in Release mode. That will build libraries `libprotobuf.lib` and `libprotoc.lib` needed for the next step.
 
-#Building using CMake (with BoringSSL)
-1. Install [Active State Perl](http://www.activestate.com/activeperl/) (`choco install activeperl`)
-2. Install [Ninja](https://ninja-build.org/) (`choco install ninja`)
-2. Install [Go](https://golang.org/dl/) (`choco install golang`)
-3. Install [yasm](http://yasm.tortall.net/) and add it to `PATH` (`choco install yasm`)
-4. Update boringssl sumbodule to `master`
-5. Run this commads in grpc directory:
-```
-> md .build
-> cd .build
-> call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x64
-> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
-> cmake --build .
-```
+- Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
-- 
GitLab


From 015f9b18ef5158c980f4d83edf03689b1889a057 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@users.noreply.github.com>
Date: Mon, 16 Jan 2017 20:27:04 +0100
Subject: [PATCH 337/344] Delete generate_debug_projects.sh

---
 .../vsprojects/generate_debug_projects.sh     | 76 -------------------
 1 file changed, 76 deletions(-)
 delete mode 100755 templates/vsprojects/generate_debug_projects.sh

diff --git a/templates/vsprojects/generate_debug_projects.sh b/templates/vsprojects/generate_debug_projects.sh
deleted file mode 100755
index f103ebe01a..0000000000
--- a/templates/vsprojects/generate_debug_projects.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-# To properly use this, you'll need to add:
-#
-#    "debug": true
-#
-# to build.json
-
-cd `dirname $0`/../..
-
-git add .               #because we're using "git diff" to find changes to grpc.sln and then make files based on those changes, this prevents this file or other files from possibly being found in the diff
-
-./tools/buildgen/generate_projects-old.sh
-
-line_number=0
-
-git diff |
-grep -A2 \\+Project |       #find "Project" immediately after a backslash (escaped), plus 2 additional lines to capture the "libs = ", plus 1 line of "--".  matches will come from the generated grpc.sln
-while read p ; do
-  line_number=$((line_number + 1))
-  if [ "$line_number" -gt "4" ]; then
-    line_number=1;
-  fi
-  echo $line_number
-  echo $p
-  if [ "$line_number" -eq "1" ]; then
-    project_name=$(echo "$p" | cut -d\" -f 4)          #sed: extract line N only; cut with delimiter: ".  select only field 4
-  fi
-  if [ "$line_number" -eq "3" ]; then
-    lib_setting=$(echo "$p" | cut -d\" -f 2)          #
-    echo "project_name"
-    echo $project_name
-    echo "lib_setting"
-    echo $lib_setting
-    mkdir -p templates/vsprojects/$project_name
-    if [ "$lib_setting" = "True" ]; then
-      echo "lib: true"
-      echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$project_name'", libs)}' > templates/vsprojects/$project_name/$project_name.vcxproj.template
-    else
-      echo "lib: not true"
-      echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$project_name'", targets)}' > templates/vsprojects/$project_name/$project_name.vcxproj.template
-    fi
-  fi
- # sleep .5     #for testing
-done
-
-./tools/buildgen/generate_projects-old.sh
-- 
GitLab


From 2a8af018ca25fafcb19efe13ed7ecb71369c04f0 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@users.noreply.github.com>
Date: Mon, 16 Jan 2017 20:27:53 +0100
Subject: [PATCH 338/344] Delete generate_projects-old.sh

---
 tools/buildgen/generate_projects-old.sh | 76 -------------------------
 1 file changed, 76 deletions(-)
 delete mode 100644 tools/buildgen/generate_projects-old.sh

diff --git a/tools/buildgen/generate_projects-old.sh b/tools/buildgen/generate_projects-old.sh
deleted file mode 100644
index 55d93d4942..0000000000
--- a/tools/buildgen/generate_projects-old.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# 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.
-
-
-set -e
-
-if [ "x$TEST" = "x" ] ; then
-  TEST=false
-fi
-
-
-cd `dirname $0`/../..
-mako_renderer=tools/buildgen/mako_renderer.py
-
-if [ "x$TEST" != "x" ] ; then
-  tools/buildgen/build-cleaner.py build.yaml
-fi
-
-. tools/buildgen/generate_build_additions.sh
-
-global_plugins=`find ./tools/buildgen/plugins -name '*.py' |
-  sort | grep -v __init__ | awk ' { printf "-p %s ", $0 } '`
-
-for dir in . ; do
-  local_plugins=`find $dir/templates -name '*.py' |
-    sort | grep -v __init__ | awk ' { printf "-p %s ", $0 } '`
-
-  plugins="$global_plugins $local_plugins"
-
-  find -L $dir/templates -type f -and -name *.template | while read file ; do
-    out=${dir}/${file#$dir/templates/}  # strip templates dir prefix
-    out=${out%.*}  # strip template extension
-    echo "generating file: $out"
-    yaml_files="build.yaml $gen_build_files"
-    data=`for i in $yaml_files ; do echo $i ; done | awk ' { printf "-d %s ", $0 } '`
-    if [ "x$TEST" = "xtrue" ] ; then
-      actual_out=$out
-      out=`mktemp /tmp/gentXXXXXX`
-    fi
-    mkdir -p `dirname $out`  # make sure dest directory exist
-    $mako_renderer $plugins $data -o $out $file
-    if [ "x$TEST" = "xtrue" ] ; then
-      diff -q $out $actual_out
-      rm $out
-    fi
-  done
-done
-
-rm $gen_build_files
-- 
GitLab


From b595c172bf03b5f2cab9aaba5e3dc1994a9d0f39 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 19 Jan 2017 09:50:23 +0100
Subject: [PATCH 339/344] fix sanity

---
 tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
index 03ff179f71..05e963d1e6 100644
--- a/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_http2/Dockerfile
@@ -46,7 +46,6 @@ RUN apt-get update && apt-get install -y \
 RUN pip install pip --upgrade
 RUN pip install virtualenv
 RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
-RUN pip install twisted h2
 
 # Define the default command.
 CMD ["bash"]
-- 
GitLab


From 0a1701f17b47cd5187ad83e6508303920e8b888a Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 17 Jan 2017 19:44:08 +0100
Subject: [PATCH 340/344] enable building of tests with cmake

---
 templates/CMakeLists.txt.template | 61 +++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 7868d41229..20c1b2797d 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -65,6 +65,8 @@
       deps.append("${_gRPC_ZLIB_LIBRARIES}")
     for d in target_dict.get('deps', []):
       deps.append(d)
+    if target_dict.build == 'test' and target_dict.language == 'c++':
+      deps.append("${_gRPC_GFLAGS_LIBRARIES}")
     return deps
   %>
 
@@ -76,6 +78,9 @@
   set(PACKAGE_TARNAME   "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>")
   set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
   project(<%text>${PACKAGE_NAME}</%text> C CXX)
+  
+  # Options
+  option(gRPC_BUILD_TESTS "Build tests" OFF)
 
   if (NOT MSVC)
     set(gRPC_INSTALL ON CACHE BOOL "Generate installation target")
@@ -91,7 +96,10 @@
 
   set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library")
   set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")
-
+  
+  set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "Provider of gflags library")
+  set_property(CACHE gRPC_GFLAGS_PROVIDER PROPERTY STRINGS "module" "package")
+  
   set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
   if (MSVC)
@@ -195,6 +203,26 @@
     endif()
     set(_gRPC_FIND_SSL "if(NOT OpenSSL_FOUND)\n  find_package(OpenSSL)\nendif()")
   endif()
+  
+  if("<%text>${gRPC_GFLAGS_PROVIDER}</%text>" STREQUAL "module")
+    if(NOT GFLAGS_ROOT_DIR)
+      set(GFLAGS_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/gflags)
+    endif()
+    if(EXISTS "<%text>${GFLAGS_ROOT_DIR}</%text>/CMakeLists.txt")
+        add_subdirectory(<%text>${GFLAGS_ROOT_DIR}</%text> third_party/gflags)
+        if(TARGET gflags-static)
+            set(_gRPC_GFLAGS_LIBRARIES gflags-static)
+        endif()
+    else()
+        message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong")
+    endif()
+  elseif("<%text>${gRPC_GFLAGS_PROVIDER}</%text>" STREQUAL "package")
+    find_package(gflags)
+    if(TARGET gflags::gflags)
+      set(_gRPC_GFLAGS_LIBRARIES gflags::gflags)
+    endif()
+    set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n  find_package(gflags)\nendif()")
+  endif()
 
   if(NOT MSVC)
     set(CMAKE_C_FLAGS   "<%text>${CMAKE_C_FLAGS}</%text>   -std=c11")
@@ -260,17 +288,31 @@
   endfunction()
   
   % for lib in libs:
-  % if lib.build in ["all", "protoc", "tool"] and lib.language in ['c', 'c++']:
+  % if lib.build in ["all", "protoc", "tool", "test", "private"] and lib.language in ['c', 'c++']:
+  % if not lib.get('build_system', []) or 'cmake' in lib.get('build_system', []):
+  % if lib.build in ["test", "private"]:
+  if (gRPC_BUILD_TESTS)
+  ${cc_library(lib)}
+  endif (gRPC_BUILD_TESTS)
+  % else:
   ${cc_library(lib)}
   ${cc_install(lib)}
   % endif
+  % endif
+  % endif
   % endfor
 
   % for tgt in targets:
-  % if tgt.build in ["all", "protoc", "tool"] and tgt.language in ['c', 'c++']:
+  % if tgt.build in ["all", "protoc", "tool", "test", "private"] and tgt.language in ['c', 'c++']:
+  % if tgt.build in ["test", "private"]:
+  if (gRPC_BUILD_TESTS)
+  ${cc_binary(tgt)}
+  endif (gRPC_BUILD_TESTS)
+  % else:
   ${cc_binary(tgt)}
   ${cc_install(tgt)}
   % endif
+  % endif
   % endfor
 
   <%def name="cc_library(lib)">
@@ -302,6 +344,11 @@
     PRIVATE <%text>${PROTOBUF_ROOT_DIR}</%text>/src
     PRIVATE <%text>${ZLIB_INCLUDE_DIR}</%text>
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/zlib
+    PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
+  % if lib.build in ['test', 'private'] and lib.language == 'c++':
+    PRIVATE third_party/googletest/include
+    PRIVATE third_party/googletest
+  % endif
   % if any(proto_re.match(src) for src in lib.src):
     PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
   % endif
@@ -335,6 +382,9 @@
   % for src in tgt.src:
     ${src}
   % endfor
+  % if tgt.build == 'test' and tgt.language == 'c++':
+    third_party/googletest/src/gtest-all.cc
+  % endif
   )
 
   target_include_directories(${tgt.name}
@@ -344,6 +394,11 @@
     PRIVATE <%text>${PROTOBUF_ROOT_DIR}</%text>/src
     PRIVATE <%text>${ZLIB_ROOT_DIR}</%text>
     PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/zlib
+    PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}</%text>/third_party/gflags/include
+  % if tgt.build in ['test', 'private'] and tgt.language == 'c++':
+    PRIVATE third_party/googletest/include
+    PRIVATE third_party/googletest
+  % endif
   )
 
   % if len(get_deps(tgt)) > 0:
-- 
GitLab


From 1985a6273ffe00215f082fc7ef3a27005f9c434c Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 18 Jan 2017 15:21:54 +0100
Subject: [PATCH 341/344] upgrade third_party/gflags to v2.2.0

---
 third_party/gflags                         | 2 +-
 tools/run_tests/sanity/check_submodules.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/third_party/gflags b/third_party/gflags
index 05b155ff59..f8a0efe03a 160000
--- a/third_party/gflags
+++ b/third_party/gflags
@@ -1 +1 @@
-Subproject commit 05b155ff59114735ec8cd089f669c4c3d8f59029
+Subproject commit f8a0efe03aa69b3336d8e228b37d4ccb17324b88
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 61e8185854..a484b26716 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -44,7 +44,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules
  44c25c892a6229b20db7cd9dc05584ea865896de third_party/benchmark (v0.1.0-343-g44c25c8)
  c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9 third_party/boringssl (c880e42)
  886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7)
- 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
+ f8a0efe03aa69b3336d8e228b37d4ccb17324b88 third_party/gflags (v2.2.0)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
  a428e42072765993ff674fda72863c9f1aa2d268 third_party/protobuf (v3.1.0-alpha-1)
  bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift (bcad917)
-- 
GitLab


From 87a5d655882059439e69f304488f0b29e92ff7e3 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Wed, 18 Jan 2017 16:22:40 +0100
Subject: [PATCH 342/344] gflags library target renamed in v2.2.0

---
 templates/CMakeLists.txt.template | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 20c1b2797d..a326f36fe9 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -210,8 +210,8 @@
     endif()
     if(EXISTS "<%text>${GFLAGS_ROOT_DIR}</%text>/CMakeLists.txt")
         add_subdirectory(<%text>${GFLAGS_ROOT_DIR}</%text> third_party/gflags)
-        if(TARGET gflags-static)
-            set(_gRPC_GFLAGS_LIBRARIES gflags-static)
+        if(TARGET gflags_static)
+            set(_gRPC_GFLAGS_LIBRARIES gflags_static)
         endif()
     else()
         message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong")
-- 
GitLab


From 36cda4c3fa446ffa8c1f09b1ff1cfd27897ff6ca Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 17 Jan 2017 20:00:12 +0100
Subject: [PATCH 343/344] regenerate

---
 CMakeLists.txt | 9705 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 9523 insertions(+), 182 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cce0528def..c5a1927c92 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,9 @@ set(PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
 project(${PACKAGE_NAME} C CXX)
 
+# Options
+option(gRPC_BUILD_TESTS "Build tests" OFF)
+
 if (NOT MSVC)
   set(gRPC_INSTALL ON CACHE BOOL "Generate installation target")
 else()
@@ -63,6 +66,9 @@ set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package")
 set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library")
 set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")
 
+set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "Provider of gflags library")
+set_property(CACHE gRPC_GFLAGS_PROVIDER PROPERTY STRINGS "module" "package")
+
 set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
 if (MSVC)
@@ -167,6 +173,26 @@ elseif("${gRPC_SSL_PROVIDER}" STREQUAL "package")
   set(_gRPC_FIND_SSL "if(NOT OpenSSL_FOUND)\n  find_package(OpenSSL)\nendif()")
 endif()
 
+if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module")
+  if(NOT GFLAGS_ROOT_DIR)
+    set(GFLAGS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gflags)
+  endif()
+  if(EXISTS "${GFLAGS_ROOT_DIR}/CMakeLists.txt")
+      add_subdirectory(${GFLAGS_ROOT_DIR} third_party/gflags)
+      if(TARGET gflags_static)
+          set(_gRPC_GFLAGS_LIBRARIES gflags_static)
+      endif()
+  else()
+      message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong")
+  endif()
+elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package")
+  find_package(gflags)
+  if(TARGET gflags::gflags)
+    set(_gRPC_GFLAGS_LIBRARIES gflags::gflags)
+  endif()
+  set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n  find_package(gflags)\nendif()")
+endif()
+
 if(NOT MSVC)
   set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -std=c11")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
@@ -286,6 +312,7 @@ target_include_directories(gpr
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 
@@ -345,6 +372,29 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
+
+add_library(gpr_test_util
+  test/core/util/test_config.c
+)
+
+
+target_include_directories(gpr_test_util
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
 
 add_library(grpc
   src/core/lib/surface/init.c
@@ -574,6 +624,7 @@ target_include_directories(grpc
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc
@@ -831,6 +882,7 @@ target_include_directories(grpc_cronet
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc_cronet
@@ -887,6 +939,240 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc_test_util
+  test/core/end2end/data/client_certs.c
+  test/core/end2end/data/server1_cert.c
+  test/core/end2end/data/server1_key.c
+  test/core/end2end/data/test_root_cert.c
+  test/core/security/oauth2_utils.c
+  test/core/end2end/cq_verifier.c
+  test/core/end2end/fake_resolver.c
+  test/core/end2end/fixtures/http_proxy.c
+  test/core/end2end/fixtures/proxy.c
+  test/core/iomgr/endpoint_tests.c
+  test/core/util/grpc_profiler.c
+  test/core/util/memory_counters.c
+  test/core/util/mock_endpoint.c
+  test/core/util/parse_hexstring.c
+  test/core/util/passthru_endpoint.c
+  test/core/util/port_posix.c
+  test/core/util/port_server_client.c
+  test/core/util/port_uv.c
+  test/core/util/port_windows.c
+  test/core/util/slice_splitter.c
+  src/core/lib/channel/channel_args.c
+  src/core/lib/channel/channel_stack.c
+  src/core/lib/channel/channel_stack_builder.c
+  src/core/lib/channel/compress_filter.c
+  src/core/lib/channel/connected_channel.c
+  src/core/lib/channel/deadline_filter.c
+  src/core/lib/channel/handshaker.c
+  src/core/lib/channel/handshaker_factory.c
+  src/core/lib/channel/handshaker_registry.c
+  src/core/lib/channel/http_client_filter.c
+  src/core/lib/channel/http_server_filter.c
+  src/core/lib/channel/message_size_filter.c
+  src/core/lib/compression/compression.c
+  src/core/lib/compression/message_compress.c
+  src/core/lib/debug/trace.c
+  src/core/lib/http/format_request.c
+  src/core/lib/http/httpcli.c
+  src/core/lib/http/parser.c
+  src/core/lib/iomgr/closure.c
+  src/core/lib/iomgr/combiner.c
+  src/core/lib/iomgr/endpoint.c
+  src/core/lib/iomgr/endpoint_pair_posix.c
+  src/core/lib/iomgr/endpoint_pair_uv.c
+  src/core/lib/iomgr/endpoint_pair_windows.c
+  src/core/lib/iomgr/error.c
+  src/core/lib/iomgr/ev_epoll_linux.c
+  src/core/lib/iomgr/ev_poll_posix.c
+  src/core/lib/iomgr/ev_posix.c
+  src/core/lib/iomgr/exec_ctx.c
+  src/core/lib/iomgr/executor.c
+  src/core/lib/iomgr/iocp_windows.c
+  src/core/lib/iomgr/iomgr.c
+  src/core/lib/iomgr/iomgr_posix.c
+  src/core/lib/iomgr/iomgr_uv.c
+  src/core/lib/iomgr/iomgr_windows.c
+  src/core/lib/iomgr/load_file.c
+  src/core/lib/iomgr/network_status_tracker.c
+  src/core/lib/iomgr/polling_entity.c
+  src/core/lib/iomgr/pollset_set_uv.c
+  src/core/lib/iomgr/pollset_set_windows.c
+  src/core/lib/iomgr/pollset_uv.c
+  src/core/lib/iomgr/pollset_windows.c
+  src/core/lib/iomgr/resolve_address_posix.c
+  src/core/lib/iomgr/resolve_address_uv.c
+  src/core/lib/iomgr/resolve_address_windows.c
+  src/core/lib/iomgr/resource_quota.c
+  src/core/lib/iomgr/sockaddr_utils.c
+  src/core/lib/iomgr/socket_mutator.c
+  src/core/lib/iomgr/socket_utils_common_posix.c
+  src/core/lib/iomgr/socket_utils_linux.c
+  src/core/lib/iomgr/socket_utils_posix.c
+  src/core/lib/iomgr/socket_utils_uv.c
+  src/core/lib/iomgr/socket_utils_windows.c
+  src/core/lib/iomgr/socket_windows.c
+  src/core/lib/iomgr/tcp_client_posix.c
+  src/core/lib/iomgr/tcp_client_uv.c
+  src/core/lib/iomgr/tcp_client_windows.c
+  src/core/lib/iomgr/tcp_posix.c
+  src/core/lib/iomgr/tcp_server_posix.c
+  src/core/lib/iomgr/tcp_server_uv.c
+  src/core/lib/iomgr/tcp_server_windows.c
+  src/core/lib/iomgr/tcp_uv.c
+  src/core/lib/iomgr/tcp_windows.c
+  src/core/lib/iomgr/time_averaged_stats.c
+  src/core/lib/iomgr/timer_generic.c
+  src/core/lib/iomgr/timer_heap.c
+  src/core/lib/iomgr/timer_uv.c
+  src/core/lib/iomgr/udp_server.c
+  src/core/lib/iomgr/unix_sockets_posix.c
+  src/core/lib/iomgr/unix_sockets_posix_noop.c
+  src/core/lib/iomgr/wakeup_fd_cv.c
+  src/core/lib/iomgr/wakeup_fd_eventfd.c
+  src/core/lib/iomgr/wakeup_fd_nospecial.c
+  src/core/lib/iomgr/wakeup_fd_pipe.c
+  src/core/lib/iomgr/wakeup_fd_posix.c
+  src/core/lib/iomgr/workqueue_uv.c
+  src/core/lib/iomgr/workqueue_windows.c
+  src/core/lib/json/json.c
+  src/core/lib/json/json_reader.c
+  src/core/lib/json/json_string.c
+  src/core/lib/json/json_writer.c
+  src/core/lib/slice/percent_encoding.c
+  src/core/lib/slice/slice.c
+  src/core/lib/slice/slice_buffer.c
+  src/core/lib/slice/slice_string_helpers.c
+  src/core/lib/surface/alarm.c
+  src/core/lib/surface/api_trace.c
+  src/core/lib/surface/byte_buffer.c
+  src/core/lib/surface/byte_buffer_reader.c
+  src/core/lib/surface/call.c
+  src/core/lib/surface/call_details.c
+  src/core/lib/surface/call_log_batch.c
+  src/core/lib/surface/channel.c
+  src/core/lib/surface/channel_init.c
+  src/core/lib/surface/channel_ping.c
+  src/core/lib/surface/channel_stack_type.c
+  src/core/lib/surface/completion_queue.c
+  src/core/lib/surface/event_string.c
+  src/core/lib/surface/lame_client.c
+  src/core/lib/surface/metadata_array.c
+  src/core/lib/surface/server.c
+  src/core/lib/surface/validate_metadata.c
+  src/core/lib/surface/version.c
+  src/core/lib/transport/byte_stream.c
+  src/core/lib/transport/connectivity_state.c
+  src/core/lib/transport/mdstr_hash_table.c
+  src/core/lib/transport/metadata.c
+  src/core/lib/transport/metadata_batch.c
+  src/core/lib/transport/pid_controller.c
+  src/core/lib/transport/service_config.c
+  src/core/lib/transport/static_metadata.c
+  src/core/lib/transport/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
+)
+
+
+target_include_directories(grpc_test_util
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_test_util
+  gpr_test_util
+  gpr
+  grpc
+)
+
+foreach(_hdr
+  include/grpc/byte_buffer.h
+  include/grpc/byte_buffer_reader.h
+  include/grpc/compression.h
+  include/grpc/grpc.h
+  include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
+  include/grpc/slice.h
+  include/grpc/slice_buffer.h
+  include/grpc/status.h
+  include/grpc/impl/codegen/byte_buffer_reader.h
+  include/grpc/impl/codegen/compression_types.h
+  include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
+  include/grpc/impl/codegen/grpc_types.h
+  include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/status.h
+  include/grpc/impl/codegen/atm.h
+  include/grpc/impl/codegen/atm_gcc_atomic.h
+  include/grpc/impl/codegen/atm_gcc_sync.h
+  include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
+  include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/port_platform.h
+  include/grpc/impl/codegen/slice.h
+  include/grpc/impl/codegen/sync.h
+  include/grpc/impl/codegen/sync_generic.h
+  include/grpc/impl/codegen/sync_posix.h
+  include/grpc/impl/codegen/sync_windows.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc_test_util_unsecure
+  test/core/end2end/cq_verifier.c
+  test/core/end2end/fake_resolver.c
+  test/core/end2end/fixtures/http_proxy.c
+  test/core/end2end/fixtures/proxy.c
+  test/core/iomgr/endpoint_tests.c
+  test/core/util/grpc_profiler.c
+  test/core/util/memory_counters.c
+  test/core/util/mock_endpoint.c
+  test/core/util/parse_hexstring.c
+  test/core/util/passthru_endpoint.c
+  test/core/util/port_posix.c
+  test/core/util/port_server_client.c
+  test/core/util/port_uv.c
+  test/core/util/port_windows.c
+  test/core/util/slice_splitter.c
+)
+
+
+target_include_directories(grpc_test_util_unsecure
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_test_util_unsecure
+  gpr
+  gpr_test_util
+  grpc_unsecure
+  grpc
+)
+
+
+endif (gRPC_BUILD_TESTS)
 
 add_library(grpc_unsecure
   src/core/lib/surface/init.c
@@ -1088,6 +1374,7 @@ target_include_directories(grpc_unsecure
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc_unsecure
@@ -1142,6 +1429,59 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
+
+add_library(reconnect_server
+  test/core/util/reconnect_server.c
+)
+
+
+target_include_directories(reconnect_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(reconnect_server
+  test_tcp_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(test_tcp_server
+  test/core/util/test_tcp_server.c
+)
+
+
+target_include_directories(test_tcp_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(test_tcp_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
 
 add_library(grpc++
   src/cpp/client/insecure_credentials.cc
@@ -1191,6 +1531,7 @@ target_include_directories(grpc++
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc++
@@ -1529,6 +1870,7 @@ target_include_directories(grpc++_cronet
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc++_cronet
@@ -1655,10 +1997,10 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
 
-add_library(grpc++_reflection
-  src/cpp/ext/proto_server_reflection.cc
-  src/cpp/ext/proto_server_reflection_plugin.cc
+add_library(grpc++_proto_reflection_desc_db
+  test/cpp/util/proto_reflection_descriptor_database.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
@@ -1669,22 +2011,25 @@ protobuf_generate_grpc_cpp(
   src/proto/grpc/reflection/v1alpha/reflection.proto
 )
 
-target_include_directories(grpc++_reflection
+target_include_directories(grpc++_proto_reflection_desc_db
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_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(grpc++_reflection
+target_link_libraries(grpc++_proto_reflection_desc_db
   grpc++
 )
 
 foreach(_hdr
-  include/grpc++/ext/proto_server_reflection_plugin.h
+  include/grpc++/impl/codegen/config_protobuf.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -1693,15 +2038,215 @@ foreach(_hdr
   )
 endforeach()
 
+endif (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc++_reflection EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_library(grpc++_reflection
+  src/cpp/ext/proto_server_reflection.cc
+  src/cpp/ext/proto_server_reflection_plugin.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/reflection/v1alpha/reflection.proto
+)
+
+target_include_directories(grpc++_reflection
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpc++_reflection
+  grpc++
+)
+
+foreach(_hdr
+  include/grpc++/ext/proto_server_reflection_plugin.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc++_reflection EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc++_test
+  src/cpp/test/server_context_test_spouse.cc
+)
+
+
+target_include_directories(grpc++_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(grpc++_test
+  grpc++
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc++_test_config
+  test/cpp/util/test_config_cc.cc
+)
+
+
+target_include_directories(grpc++_test_config
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc++_test_util
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h
+  test/cpp/end2end/test_service_impl.cc
+  test/cpp/util/byte_buffer_proto_helper.cc
+  test/cpp/util/create_test_channel.cc
+  test/cpp/util/string_ref_helper.cc
+  test/cpp/util/subprocess.cc
+  test/cpp/util/test_credentials_provider.cc
+  src/cpp/codegen/codegen_init.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo_messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/duplicate/echo_duplicate.proto
+)
+
+target_include_directories(grpc++_test_util
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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(grpc++_test_util
+  grpc++
+  grpc_test_util
+)
+
+foreach(_hdr
+  include/grpc++/impl/codegen/async_stream.h
+  include/grpc++/impl/codegen/async_unary_call.h
+  include/grpc++/impl/codegen/call.h
+  include/grpc++/impl/codegen/call_hook.h
+  include/grpc++/impl/codegen/channel_interface.h
+  include/grpc++/impl/codegen/client_context.h
+  include/grpc++/impl/codegen/client_unary_call.h
+  include/grpc++/impl/codegen/completion_queue.h
+  include/grpc++/impl/codegen/completion_queue_tag.h
+  include/grpc++/impl/codegen/config.h
+  include/grpc++/impl/codegen/core_codegen_interface.h
+  include/grpc++/impl/codegen/create_auth_context.h
+  include/grpc++/impl/codegen/grpc_library.h
+  include/grpc++/impl/codegen/method_handler_impl.h
+  include/grpc++/impl/codegen/rpc_method.h
+  include/grpc++/impl/codegen/rpc_service_method.h
+  include/grpc++/impl/codegen/security/auth_context.h
+  include/grpc++/impl/codegen/serialization_traits.h
+  include/grpc++/impl/codegen/server_context.h
+  include/grpc++/impl/codegen/server_interface.h
+  include/grpc++/impl/codegen/service_type.h
+  include/grpc++/impl/codegen/status.h
+  include/grpc++/impl/codegen/status_code_enum.h
+  include/grpc++/impl/codegen/status_helper.h
+  include/grpc++/impl/codegen/string_ref.h
+  include/grpc++/impl/codegen/stub_options.h
+  include/grpc++/impl/codegen/sync_stream.h
+  include/grpc++/impl/codegen/time.h
+  include/grpc/impl/codegen/byte_buffer_reader.h
+  include/grpc/impl/codegen/compression_types.h
+  include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
+  include/grpc/impl/codegen/grpc_types.h
+  include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/status.h
+  include/grpc/impl/codegen/atm.h
+  include/grpc/impl/codegen/atm_gcc_atomic.h
+  include/grpc/impl/codegen/atm_gcc_sync.h
+  include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/gpr_slice.h
+  include/grpc/impl/codegen/gpr_types.h
+  include/grpc/impl/codegen/port_platform.h
+  include/grpc/impl/codegen/slice.h
+  include/grpc/impl/codegen/sync.h
+  include/grpc/impl/codegen/sync_generic.h
+  include/grpc/impl/codegen/sync_posix.h
+  include/grpc/impl/codegen/sync_windows.h
+  include/grpc++/impl/codegen/proto_utils.h
+  include/grpc++/impl/codegen/config_protobuf.h
+  include/grpc++/impl/codegen/thrift_serializer.h
+  include/grpc++/impl/codegen/thrift_utils.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
 
+endif (gRPC_BUILD_TESTS)
 
 add_library(grpc++_unsecure
   src/cpp/client/insecure_credentials.cc
@@ -1746,6 +2291,7 @@ target_include_directories(grpc++_unsecure
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc++_unsecure
@@ -1862,6 +2408,53 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
+
+add_library(grpc_cli_libs
+  test/cpp/util/cli_call.cc
+  test/cpp/util/cli_credentials.cc
+  test/cpp/util/grpc_tool.cc
+  test/cpp/util/proto_file_parser.cc
+  test/cpp/util/service_describer.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/reflection/v1alpha/reflection.proto
+)
+
+target_include_directories(grpc_cli_libs
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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(grpc_cli_libs
+  grpc++_proto_reflection_desc_db
+  grpc++
+)
+
+foreach(_hdr
+  include/grpc++/impl/codegen/config_protobuf.h
+)
+  string(REPLACE "include/" "" _path ${_hdr})
+  get_filename_component(_path ${_path} PATH)
+  install(FILES ${_hdr}
+    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}"
+  )
+endforeach()
+
+endif (gRPC_BUILD_TESTS)
 
 add_library(grpc_plugin_support
   src/compiler/cpp_generator.cc
@@ -1881,6 +2474,7 @@ target_include_directories(grpc_plugin_support
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_INCLUDE_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
 target_link_libraries(grpc_plugin_support
@@ -1906,86 +2500,3273 @@ if (gRPC_INSTALL)
   )
 endif()
 
+if (gRPC_BUILD_TESTS)
+
+add_library(http2_client_main
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
+  test/cpp/interop/http2_client.cc
+)
 
-
-add_executable(gen_hpack_tables
-  tools/codegen/core/gen_hpack_tables.c
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/empty.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/test.proto
 )
 
-target_include_directories(gen_hpack_tables
+target_include_directories(http2_client_main
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
-  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${ZLIB_INCLUDE_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(gen_hpack_tables
-  gpr
+target_link_libraries(http2_client_main
+  grpc++_test_util
+  grpc_test_util
+  grpc++
   grpc
+  grpc++_test_config
 )
 
 
-if (gRPC_INSTALL)
-  install(TARGETS gen_hpack_tables EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
+add_library(interop_client_helper
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
+  test/cpp/interop/client_helper.cc
+)
 
-add_executable(gen_legal_metadata_characters
-  tools/codegen/core/gen_legal_metadata_characters.c
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/messages.proto
 )
 
-target_include_directories(gen_legal_metadata_characters
+target_include_directories(interop_client_helper
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
-  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${ZLIB_INCLUDE_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(interop_client_helper
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr
+)
 
 
-if (gRPC_INSTALL)
-  install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(interop_client_main
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
+  test/cpp/interop/client.cc
+  test/cpp/interop/interop_client.cc
+)
 
-add_executable(gen_percent_encoding_tables
-  tools/codegen/core/gen_percent_encoding_tables.c
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/empty.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/test.proto
 )
 
-target_include_directories(gen_percent_encoding_tables
+target_include_directories(interop_client_main
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
-  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${ZLIB_INCLUDE_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(interop_client_main
+  interop_client_helper
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+)
 
 
-if (gRPC_INSTALL)
-  install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-add_executable(grpc_create_jwt
-  test/core/security/create_jwt.c
+add_library(interop_server_helper
+  test/cpp/interop/server_helper.cc
+)
+
+
+target_include_directories(interop_server_helper
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(interop_server_helper
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(interop_server_lib
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
+  test/cpp/interop/interop_server.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/empty.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/test.proto
+)
+
+target_include_directories(interop_server_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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(interop_server_lib
+  interop_server_helper
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(interop_server_main
+  test/cpp/interop/interop_server_bootstrap.cc
+)
+
+
+target_include_directories(interop_server_main
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(interop_server_main
+  interop_server_lib
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(qps
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/services.grpc.pb.h
+  test/cpp/qps/client_async.cc
+  test/cpp/qps/client_sync.cc
+  test/cpp/qps/driver.cc
+  test/cpp/qps/parse_json.cc
+  test/cpp/qps/qps_worker.cc
+  test/cpp/qps/report.cc
+  test/cpp/qps/server_async.cc
+  test/cpp/qps/server_sync.cc
+  test/cpp/qps/usage_timer.cc
+  test/cpp/util/benchmark_config.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/payloads.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/stats.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/control.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/services.proto
+)
+
+target_include_directories(qps
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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(qps
+  grpc_test_util
+  grpc++_test_util
+  grpc++
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl
+  src/boringssl/err_data.c
+  third_party/boringssl/crypto/aes/aes.c
+  third_party/boringssl/crypto/aes/mode_wrappers.c
+  third_party/boringssl/crypto/asn1/a_bitstr.c
+  third_party/boringssl/crypto/asn1/a_bool.c
+  third_party/boringssl/crypto/asn1/a_bytes.c
+  third_party/boringssl/crypto/asn1/a_d2i_fp.c
+  third_party/boringssl/crypto/asn1/a_dup.c
+  third_party/boringssl/crypto/asn1/a_enum.c
+  third_party/boringssl/crypto/asn1/a_gentm.c
+  third_party/boringssl/crypto/asn1/a_i2d_fp.c
+  third_party/boringssl/crypto/asn1/a_int.c
+  third_party/boringssl/crypto/asn1/a_mbstr.c
+  third_party/boringssl/crypto/asn1/a_object.c
+  third_party/boringssl/crypto/asn1/a_octet.c
+  third_party/boringssl/crypto/asn1/a_print.c
+  third_party/boringssl/crypto/asn1/a_strnid.c
+  third_party/boringssl/crypto/asn1/a_time.c
+  third_party/boringssl/crypto/asn1/a_type.c
+  third_party/boringssl/crypto/asn1/a_utctm.c
+  third_party/boringssl/crypto/asn1/a_utf8.c
+  third_party/boringssl/crypto/asn1/asn1_lib.c
+  third_party/boringssl/crypto/asn1/asn1_par.c
+  third_party/boringssl/crypto/asn1/asn_pack.c
+  third_party/boringssl/crypto/asn1/bio_asn1.c
+  third_party/boringssl/crypto/asn1/bio_ndef.c
+  third_party/boringssl/crypto/asn1/f_enum.c
+  third_party/boringssl/crypto/asn1/f_int.c
+  third_party/boringssl/crypto/asn1/f_string.c
+  third_party/boringssl/crypto/asn1/t_bitst.c
+  third_party/boringssl/crypto/asn1/t_pkey.c
+  third_party/boringssl/crypto/asn1/tasn_dec.c
+  third_party/boringssl/crypto/asn1/tasn_enc.c
+  third_party/boringssl/crypto/asn1/tasn_fre.c
+  third_party/boringssl/crypto/asn1/tasn_new.c
+  third_party/boringssl/crypto/asn1/tasn_prn.c
+  third_party/boringssl/crypto/asn1/tasn_typ.c
+  third_party/boringssl/crypto/asn1/tasn_utl.c
+  third_party/boringssl/crypto/asn1/x_bignum.c
+  third_party/boringssl/crypto/asn1/x_long.c
+  third_party/boringssl/crypto/base64/base64.c
+  third_party/boringssl/crypto/bio/bio.c
+  third_party/boringssl/crypto/bio/bio_mem.c
+  third_party/boringssl/crypto/bio/buffer.c
+  third_party/boringssl/crypto/bio/connect.c
+  third_party/boringssl/crypto/bio/fd.c
+  third_party/boringssl/crypto/bio/file.c
+  third_party/boringssl/crypto/bio/hexdump.c
+  third_party/boringssl/crypto/bio/pair.c
+  third_party/boringssl/crypto/bio/printf.c
+  third_party/boringssl/crypto/bio/socket.c
+  third_party/boringssl/crypto/bio/socket_helper.c
+  third_party/boringssl/crypto/bn/add.c
+  third_party/boringssl/crypto/bn/asm/x86_64-gcc.c
+  third_party/boringssl/crypto/bn/bn.c
+  third_party/boringssl/crypto/bn/bn_asn1.c
+  third_party/boringssl/crypto/bn/cmp.c
+  third_party/boringssl/crypto/bn/convert.c
+  third_party/boringssl/crypto/bn/ctx.c
+  third_party/boringssl/crypto/bn/div.c
+  third_party/boringssl/crypto/bn/exponentiation.c
+  third_party/boringssl/crypto/bn/gcd.c
+  third_party/boringssl/crypto/bn/generic.c
+  third_party/boringssl/crypto/bn/kronecker.c
+  third_party/boringssl/crypto/bn/montgomery.c
+  third_party/boringssl/crypto/bn/mul.c
+  third_party/boringssl/crypto/bn/prime.c
+  third_party/boringssl/crypto/bn/random.c
+  third_party/boringssl/crypto/bn/rsaz_exp.c
+  third_party/boringssl/crypto/bn/shift.c
+  third_party/boringssl/crypto/bn/sqrt.c
+  third_party/boringssl/crypto/buf/buf.c
+  third_party/boringssl/crypto/bytestring/asn1_compat.c
+  third_party/boringssl/crypto/bytestring/ber.c
+  third_party/boringssl/crypto/bytestring/cbb.c
+  third_party/boringssl/crypto/bytestring/cbs.c
+  third_party/boringssl/crypto/chacha/chacha_generic.c
+  third_party/boringssl/crypto/chacha/chacha_vec.c
+  third_party/boringssl/crypto/cipher/aead.c
+  third_party/boringssl/crypto/cipher/cipher.c
+  third_party/boringssl/crypto/cipher/derive_key.c
+  third_party/boringssl/crypto/cipher/e_aes.c
+  third_party/boringssl/crypto/cipher/e_chacha20poly1305.c
+  third_party/boringssl/crypto/cipher/e_des.c
+  third_party/boringssl/crypto/cipher/e_null.c
+  third_party/boringssl/crypto/cipher/e_rc2.c
+  third_party/boringssl/crypto/cipher/e_rc4.c
+  third_party/boringssl/crypto/cipher/e_ssl3.c
+  third_party/boringssl/crypto/cipher/e_tls.c
+  third_party/boringssl/crypto/cipher/tls_cbc.c
+  third_party/boringssl/crypto/cmac/cmac.c
+  third_party/boringssl/crypto/conf/conf.c
+  third_party/boringssl/crypto/cpu-arm.c
+  third_party/boringssl/crypto/cpu-intel.c
+  third_party/boringssl/crypto/crypto.c
+  third_party/boringssl/crypto/curve25519/curve25519.c
+  third_party/boringssl/crypto/curve25519/x25519-x86_64.c
+  third_party/boringssl/crypto/des/des.c
+  third_party/boringssl/crypto/dh/check.c
+  third_party/boringssl/crypto/dh/dh.c
+  third_party/boringssl/crypto/dh/dh_asn1.c
+  third_party/boringssl/crypto/dh/params.c
+  third_party/boringssl/crypto/digest/digest.c
+  third_party/boringssl/crypto/digest/digests.c
+  third_party/boringssl/crypto/directory_posix.c
+  third_party/boringssl/crypto/directory_win.c
+  third_party/boringssl/crypto/dsa/dsa.c
+  third_party/boringssl/crypto/dsa/dsa_asn1.c
+  third_party/boringssl/crypto/ec/ec.c
+  third_party/boringssl/crypto/ec/ec_asn1.c
+  third_party/boringssl/crypto/ec/ec_key.c
+  third_party/boringssl/crypto/ec/ec_montgomery.c
+  third_party/boringssl/crypto/ec/oct.c
+  third_party/boringssl/crypto/ec/p224-64.c
+  third_party/boringssl/crypto/ec/p256-64.c
+  third_party/boringssl/crypto/ec/p256-x86_64.c
+  third_party/boringssl/crypto/ec/simple.c
+  third_party/boringssl/crypto/ec/util-64.c
+  third_party/boringssl/crypto/ec/wnaf.c
+  third_party/boringssl/crypto/ecdh/ecdh.c
+  third_party/boringssl/crypto/ecdsa/ecdsa.c
+  third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c
+  third_party/boringssl/crypto/engine/engine.c
+  third_party/boringssl/crypto/err/err.c
+  third_party/boringssl/crypto/evp/algorithm.c
+  third_party/boringssl/crypto/evp/digestsign.c
+  third_party/boringssl/crypto/evp/evp.c
+  third_party/boringssl/crypto/evp/evp_asn1.c
+  third_party/boringssl/crypto/evp/evp_ctx.c
+  third_party/boringssl/crypto/evp/p_dsa_asn1.c
+  third_party/boringssl/crypto/evp/p_ec.c
+  third_party/boringssl/crypto/evp/p_ec_asn1.c
+  third_party/boringssl/crypto/evp/p_rsa.c
+  third_party/boringssl/crypto/evp/p_rsa_asn1.c
+  third_party/boringssl/crypto/evp/pbkdf.c
+  third_party/boringssl/crypto/evp/sign.c
+  third_party/boringssl/crypto/ex_data.c
+  third_party/boringssl/crypto/hkdf/hkdf.c
+  third_party/boringssl/crypto/hmac/hmac.c
+  third_party/boringssl/crypto/lhash/lhash.c
+  third_party/boringssl/crypto/md4/md4.c
+  third_party/boringssl/crypto/md5/md5.c
+  third_party/boringssl/crypto/mem.c
+  third_party/boringssl/crypto/modes/cbc.c
+  third_party/boringssl/crypto/modes/cfb.c
+  third_party/boringssl/crypto/modes/ctr.c
+  third_party/boringssl/crypto/modes/gcm.c
+  third_party/boringssl/crypto/modes/ofb.c
+  third_party/boringssl/crypto/obj/obj.c
+  third_party/boringssl/crypto/obj/obj_xref.c
+  third_party/boringssl/crypto/pem/pem_all.c
+  third_party/boringssl/crypto/pem/pem_info.c
+  third_party/boringssl/crypto/pem/pem_lib.c
+  third_party/boringssl/crypto/pem/pem_oth.c
+  third_party/boringssl/crypto/pem/pem_pk8.c
+  third_party/boringssl/crypto/pem/pem_pkey.c
+  third_party/boringssl/crypto/pem/pem_x509.c
+  third_party/boringssl/crypto/pem/pem_xaux.c
+  third_party/boringssl/crypto/pkcs8/p5_pbe.c
+  third_party/boringssl/crypto/pkcs8/p5_pbev2.c
+  third_party/boringssl/crypto/pkcs8/p8_pkey.c
+  third_party/boringssl/crypto/pkcs8/pkcs8.c
+  third_party/boringssl/crypto/poly1305/poly1305.c
+  third_party/boringssl/crypto/poly1305/poly1305_arm.c
+  third_party/boringssl/crypto/poly1305/poly1305_vec.c
+  third_party/boringssl/crypto/rand/rand.c
+  third_party/boringssl/crypto/rand/urandom.c
+  third_party/boringssl/crypto/rand/windows.c
+  third_party/boringssl/crypto/rc4/rc4.c
+  third_party/boringssl/crypto/refcount_c11.c
+  third_party/boringssl/crypto/refcount_lock.c
+  third_party/boringssl/crypto/rsa/blinding.c
+  third_party/boringssl/crypto/rsa/padding.c
+  third_party/boringssl/crypto/rsa/rsa.c
+  third_party/boringssl/crypto/rsa/rsa_asn1.c
+  third_party/boringssl/crypto/rsa/rsa_impl.c
+  third_party/boringssl/crypto/sha/sha1.c
+  third_party/boringssl/crypto/sha/sha256.c
+  third_party/boringssl/crypto/sha/sha512.c
+  third_party/boringssl/crypto/stack/stack.c
+  third_party/boringssl/crypto/thread.c
+  third_party/boringssl/crypto/thread_none.c
+  third_party/boringssl/crypto/thread_pthread.c
+  third_party/boringssl/crypto/thread_win.c
+  third_party/boringssl/crypto/time_support.c
+  third_party/boringssl/crypto/x509/a_digest.c
+  third_party/boringssl/crypto/x509/a_sign.c
+  third_party/boringssl/crypto/x509/a_strex.c
+  third_party/boringssl/crypto/x509/a_verify.c
+  third_party/boringssl/crypto/x509/asn1_gen.c
+  third_party/boringssl/crypto/x509/by_dir.c
+  third_party/boringssl/crypto/x509/by_file.c
+  third_party/boringssl/crypto/x509/i2d_pr.c
+  third_party/boringssl/crypto/x509/pkcs7.c
+  third_party/boringssl/crypto/x509/t_crl.c
+  third_party/boringssl/crypto/x509/t_req.c
+  third_party/boringssl/crypto/x509/t_x509.c
+  third_party/boringssl/crypto/x509/t_x509a.c
+  third_party/boringssl/crypto/x509/x509.c
+  third_party/boringssl/crypto/x509/x509_att.c
+  third_party/boringssl/crypto/x509/x509_cmp.c
+  third_party/boringssl/crypto/x509/x509_d2.c
+  third_party/boringssl/crypto/x509/x509_def.c
+  third_party/boringssl/crypto/x509/x509_ext.c
+  third_party/boringssl/crypto/x509/x509_lu.c
+  third_party/boringssl/crypto/x509/x509_obj.c
+  third_party/boringssl/crypto/x509/x509_r2x.c
+  third_party/boringssl/crypto/x509/x509_req.c
+  third_party/boringssl/crypto/x509/x509_set.c
+  third_party/boringssl/crypto/x509/x509_trs.c
+  third_party/boringssl/crypto/x509/x509_txt.c
+  third_party/boringssl/crypto/x509/x509_v3.c
+  third_party/boringssl/crypto/x509/x509_vfy.c
+  third_party/boringssl/crypto/x509/x509_vpm.c
+  third_party/boringssl/crypto/x509/x509cset.c
+  third_party/boringssl/crypto/x509/x509name.c
+  third_party/boringssl/crypto/x509/x509rset.c
+  third_party/boringssl/crypto/x509/x509spki.c
+  third_party/boringssl/crypto/x509/x509type.c
+  third_party/boringssl/crypto/x509/x_algor.c
+  third_party/boringssl/crypto/x509/x_all.c
+  third_party/boringssl/crypto/x509/x_attrib.c
+  third_party/boringssl/crypto/x509/x_crl.c
+  third_party/boringssl/crypto/x509/x_exten.c
+  third_party/boringssl/crypto/x509/x_info.c
+  third_party/boringssl/crypto/x509/x_name.c
+  third_party/boringssl/crypto/x509/x_pkey.c
+  third_party/boringssl/crypto/x509/x_pubkey.c
+  third_party/boringssl/crypto/x509/x_req.c
+  third_party/boringssl/crypto/x509/x_sig.c
+  third_party/boringssl/crypto/x509/x_spki.c
+  third_party/boringssl/crypto/x509/x_val.c
+  third_party/boringssl/crypto/x509/x_x509.c
+  third_party/boringssl/crypto/x509/x_x509a.c
+  third_party/boringssl/crypto/x509v3/pcy_cache.c
+  third_party/boringssl/crypto/x509v3/pcy_data.c
+  third_party/boringssl/crypto/x509v3/pcy_lib.c
+  third_party/boringssl/crypto/x509v3/pcy_map.c
+  third_party/boringssl/crypto/x509v3/pcy_node.c
+  third_party/boringssl/crypto/x509v3/pcy_tree.c
+  third_party/boringssl/crypto/x509v3/v3_akey.c
+  third_party/boringssl/crypto/x509v3/v3_akeya.c
+  third_party/boringssl/crypto/x509v3/v3_alt.c
+  third_party/boringssl/crypto/x509v3/v3_bcons.c
+  third_party/boringssl/crypto/x509v3/v3_bitst.c
+  third_party/boringssl/crypto/x509v3/v3_conf.c
+  third_party/boringssl/crypto/x509v3/v3_cpols.c
+  third_party/boringssl/crypto/x509v3/v3_crld.c
+  third_party/boringssl/crypto/x509v3/v3_enum.c
+  third_party/boringssl/crypto/x509v3/v3_extku.c
+  third_party/boringssl/crypto/x509v3/v3_genn.c
+  third_party/boringssl/crypto/x509v3/v3_ia5.c
+  third_party/boringssl/crypto/x509v3/v3_info.c
+  third_party/boringssl/crypto/x509v3/v3_int.c
+  third_party/boringssl/crypto/x509v3/v3_lib.c
+  third_party/boringssl/crypto/x509v3/v3_ncons.c
+  third_party/boringssl/crypto/x509v3/v3_pci.c
+  third_party/boringssl/crypto/x509v3/v3_pcia.c
+  third_party/boringssl/crypto/x509v3/v3_pcons.c
+  third_party/boringssl/crypto/x509v3/v3_pku.c
+  third_party/boringssl/crypto/x509v3/v3_pmaps.c
+  third_party/boringssl/crypto/x509v3/v3_prn.c
+  third_party/boringssl/crypto/x509v3/v3_purp.c
+  third_party/boringssl/crypto/x509v3/v3_skey.c
+  third_party/boringssl/crypto/x509v3/v3_sxnet.c
+  third_party/boringssl/crypto/x509v3/v3_utl.c
+  third_party/boringssl/ssl/custom_extensions.c
+  third_party/boringssl/ssl/d1_both.c
+  third_party/boringssl/ssl/d1_clnt.c
+  third_party/boringssl/ssl/d1_lib.c
+  third_party/boringssl/ssl/d1_meth.c
+  third_party/boringssl/ssl/d1_pkt.c
+  third_party/boringssl/ssl/d1_srtp.c
+  third_party/boringssl/ssl/d1_srvr.c
+  third_party/boringssl/ssl/dtls_record.c
+  third_party/boringssl/ssl/pqueue/pqueue.c
+  third_party/boringssl/ssl/s3_both.c
+  third_party/boringssl/ssl/s3_clnt.c
+  third_party/boringssl/ssl/s3_enc.c
+  third_party/boringssl/ssl/s3_lib.c
+  third_party/boringssl/ssl/s3_meth.c
+  third_party/boringssl/ssl/s3_pkt.c
+  third_party/boringssl/ssl/s3_srvr.c
+  third_party/boringssl/ssl/ssl_aead_ctx.c
+  third_party/boringssl/ssl/ssl_asn1.c
+  third_party/boringssl/ssl/ssl_buffer.c
+  third_party/boringssl/ssl/ssl_cert.c
+  third_party/boringssl/ssl/ssl_cipher.c
+  third_party/boringssl/ssl/ssl_ecdh.c
+  third_party/boringssl/ssl/ssl_file.c
+  third_party/boringssl/ssl/ssl_lib.c
+  third_party/boringssl/ssl/ssl_rsa.c
+  third_party/boringssl/ssl/ssl_session.c
+  third_party/boringssl/ssl/ssl_stat.c
+  third_party/boringssl/ssl/t1_enc.c
+  third_party/boringssl/ssl/t1_lib.c
+  third_party/boringssl/ssl/tls_record.c
+)
+
+
+target_include_directories(boringssl
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl
+  ${_gRPC_SSL_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_test_util
+  third_party/boringssl/crypto/test/file_test.cc
+  third_party/boringssl/crypto/test/malloc.cc
+  third_party/boringssl/crypto/test/test_util.cc
+)
+
+
+target_include_directories(boringssl_test_util
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_test_util
+  ${_gRPC_SSL_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_aes_test_lib
+  third_party/boringssl/crypto/aes/aes_test.cc
+)
+
+
+target_include_directories(boringssl_aes_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_aes_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_asn1_test_lib
+  third_party/boringssl/crypto/asn1/asn1_test.cc
+)
+
+
+target_include_directories(boringssl_asn1_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_asn1_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_base64_test_lib
+  third_party/boringssl/crypto/base64/base64_test.cc
+)
+
+
+target_include_directories(boringssl_base64_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_base64_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_bio_test_lib
+  third_party/boringssl/crypto/bio/bio_test.cc
+)
+
+
+target_include_directories(boringssl_bio_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_bio_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_bn_test_lib
+  third_party/boringssl/crypto/bn/bn_test.cc
+)
+
+
+target_include_directories(boringssl_bn_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_bn_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_bytestring_test_lib
+  third_party/boringssl/crypto/bytestring/bytestring_test.cc
+)
+
+
+target_include_directories(boringssl_bytestring_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_bytestring_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_aead_test_lib
+  third_party/boringssl/crypto/cipher/aead_test.cc
+)
+
+
+target_include_directories(boringssl_aead_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_aead_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_cipher_test_lib
+  third_party/boringssl/crypto/cipher/cipher_test.cc
+)
+
+
+target_include_directories(boringssl_cipher_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_cipher_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_cmac_test_lib
+  third_party/boringssl/crypto/cmac/cmac_test.cc
+)
+
+
+target_include_directories(boringssl_cmac_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_cmac_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_constant_time_test_lib
+  third_party/boringssl/crypto/constant_time_test.c
+)
+
+
+target_include_directories(boringssl_constant_time_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_constant_time_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_ed25519_test_lib
+  third_party/boringssl/crypto/curve25519/ed25519_test.cc
+)
+
+
+target_include_directories(boringssl_ed25519_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_ed25519_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_x25519_test_lib
+  third_party/boringssl/crypto/curve25519/x25519_test.cc
+)
+
+
+target_include_directories(boringssl_x25519_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_x25519_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_dh_test_lib
+  third_party/boringssl/crypto/dh/dh_test.cc
+)
+
+
+target_include_directories(boringssl_dh_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_dh_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_digest_test_lib
+  third_party/boringssl/crypto/digest/digest_test.cc
+)
+
+
+target_include_directories(boringssl_digest_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_digest_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_dsa_test_lib
+  third_party/boringssl/crypto/dsa/dsa_test.c
+)
+
+
+target_include_directories(boringssl_dsa_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_dsa_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_ec_test_lib
+  third_party/boringssl/crypto/ec/ec_test.cc
+)
+
+
+target_include_directories(boringssl_ec_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_ec_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_example_mul_lib
+  third_party/boringssl/crypto/ec/example_mul.c
+)
+
+
+target_include_directories(boringssl_example_mul_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_example_mul_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_ecdsa_test_lib
+  third_party/boringssl/crypto/ecdsa/ecdsa_test.cc
+)
+
+
+target_include_directories(boringssl_ecdsa_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_ecdsa_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_err_test_lib
+  third_party/boringssl/crypto/err/err_test.cc
+)
+
+
+target_include_directories(boringssl_err_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_err_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_evp_extra_test_lib
+  third_party/boringssl/crypto/evp/evp_extra_test.cc
+)
+
+
+target_include_directories(boringssl_evp_extra_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_evp_extra_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_evp_test_lib
+  third_party/boringssl/crypto/evp/evp_test.cc
+)
+
+
+target_include_directories(boringssl_evp_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_evp_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_pbkdf_test_lib
+  third_party/boringssl/crypto/evp/pbkdf_test.cc
+)
+
+
+target_include_directories(boringssl_pbkdf_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_pbkdf_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_hkdf_test_lib
+  third_party/boringssl/crypto/hkdf/hkdf_test.c
+)
+
+
+target_include_directories(boringssl_hkdf_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_hkdf_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_hmac_test_lib
+  third_party/boringssl/crypto/hmac/hmac_test.cc
+)
+
+
+target_include_directories(boringssl_hmac_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_hmac_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_lhash_test_lib
+  third_party/boringssl/crypto/lhash/lhash_test.c
+)
+
+
+target_include_directories(boringssl_lhash_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_lhash_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_gcm_test_lib
+  third_party/boringssl/crypto/modes/gcm_test.c
+)
+
+
+target_include_directories(boringssl_gcm_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_gcm_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_pkcs12_test_lib
+  third_party/boringssl/crypto/pkcs8/pkcs12_test.cc
+)
+
+
+target_include_directories(boringssl_pkcs12_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_pkcs12_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_pkcs8_test_lib
+  third_party/boringssl/crypto/pkcs8/pkcs8_test.cc
+)
+
+
+target_include_directories(boringssl_pkcs8_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_pkcs8_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_poly1305_test_lib
+  third_party/boringssl/crypto/poly1305/poly1305_test.cc
+)
+
+
+target_include_directories(boringssl_poly1305_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_poly1305_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_refcount_test_lib
+  third_party/boringssl/crypto/refcount_test.c
+)
+
+
+target_include_directories(boringssl_refcount_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_refcount_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_rsa_test_lib
+  third_party/boringssl/crypto/rsa/rsa_test.cc
+)
+
+
+target_include_directories(boringssl_rsa_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_rsa_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_thread_test_lib
+  third_party/boringssl/crypto/thread_test.c
+)
+
+
+target_include_directories(boringssl_thread_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_thread_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_pkcs7_test_lib
+  third_party/boringssl/crypto/x509/pkcs7_test.c
+)
+
+
+target_include_directories(boringssl_pkcs7_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_pkcs7_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_x509_test_lib
+  third_party/boringssl/crypto/x509/x509_test.cc
+)
+
+
+target_include_directories(boringssl_x509_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_x509_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_tab_test_lib
+  third_party/boringssl/crypto/x509v3/tab_test.c
+)
+
+
+target_include_directories(boringssl_tab_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_tab_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_v3name_test_lib
+  third_party/boringssl/crypto/x509v3/v3name_test.c
+)
+
+
+target_include_directories(boringssl_v3name_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_v3name_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_pqueue_test_lib
+  third_party/boringssl/ssl/pqueue/pqueue_test.c
+)
+
+
+target_include_directories(boringssl_pqueue_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(boringssl_pqueue_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(boringssl_ssl_test_lib
+  third_party/boringssl/ssl/ssl_test.cc
+)
+
+
+target_include_directories(boringssl_ssl_test_lib
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(boringssl_ssl_test_lib
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_test_util
+  boringssl
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(benchmark
+  third_party/benchmark/src/benchmark.cc
+  third_party/benchmark/src/benchmark_register.cc
+  third_party/benchmark/src/colorprint.cc
+  third_party/benchmark/src/commandlineflags.cc
+  third_party/benchmark/src/complexity.cc
+  third_party/benchmark/src/console_reporter.cc
+  third_party/benchmark/src/csv_reporter.cc
+  third_party/benchmark/src/json_reporter.cc
+  third_party/benchmark/src/reporter.cc
+  third_party/benchmark/src/sleep.cc
+  third_party/benchmark/src/string_util.cc
+  third_party/benchmark/src/sysinfo.cc
+  third_party/benchmark/src/timers.cc
+)
+
+
+target_include_directories(benchmark
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_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
+)
+
+target_link_libraries(benchmark
+  ${_gRPC_SSL_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(z
+  third_party/zlib/adler32.c
+  third_party/zlib/compress.c
+  third_party/zlib/crc32.c
+  third_party/zlib/deflate.c
+  third_party/zlib/gzclose.c
+  third_party/zlib/gzlib.c
+  third_party/zlib/gzread.c
+  third_party/zlib/gzwrite.c
+  third_party/zlib/infback.c
+  third_party/zlib/inffast.c
+  third_party/zlib/inflate.c
+  third_party/zlib/inftrees.c
+  third_party/zlib/trees.c
+  third_party/zlib/uncompr.c
+  third_party/zlib/zutil.c
+)
+
+
+target_include_directories(z
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(z
+  ${_gRPC_SSL_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(bad_client_test
+  test/core/bad_client/bad_client.c
+)
+
+
+target_include_directories(bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(bad_ssl_test_server
+  test/core/bad_ssl/server_common.c
+)
+
+
+target_include_directories(bad_ssl_test_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_ssl_test_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(end2end_tests
+  test/core/end2end/end2end_tests.c
+  test/core/end2end/end2end_test_utils.c
+  test/core/end2end/tests/authority_not_supported.c
+  test/core/end2end/tests/bad_hostname.c
+  test/core/end2end/tests/binary_metadata.c
+  test/core/end2end/tests/call_creds.c
+  test/core/end2end/tests/cancel_after_accept.c
+  test/core/end2end/tests/cancel_after_client_done.c
+  test/core/end2end/tests/cancel_after_invoke.c
+  test/core/end2end/tests/cancel_before_invoke.c
+  test/core/end2end/tests/cancel_in_a_vacuum.c
+  test/core/end2end/tests/cancel_with_status.c
+  test/core/end2end/tests/compressed_payload.c
+  test/core/end2end/tests/connectivity.c
+  test/core/end2end/tests/default_host.c
+  test/core/end2end/tests/disappearing_server.c
+  test/core/end2end/tests/empty_batch.c
+  test/core/end2end/tests/filter_call_init_fails.c
+  test/core/end2end/tests/filter_causes_close.c
+  test/core/end2end/tests/filter_latency.c
+  test/core/end2end/tests/graceful_server_shutdown.c
+  test/core/end2end/tests/high_initial_seqno.c
+  test/core/end2end/tests/hpack_size.c
+  test/core/end2end/tests/idempotent_request.c
+  test/core/end2end/tests/invoke_large_request.c
+  test/core/end2end/tests/large_metadata.c
+  test/core/end2end/tests/load_reporting_hook.c
+  test/core/end2end/tests/max_concurrent_streams.c
+  test/core/end2end/tests/max_message_length.c
+  test/core/end2end/tests/negative_deadline.c
+  test/core/end2end/tests/network_status_change.c
+  test/core/end2end/tests/no_logging.c
+  test/core/end2end/tests/no_op.c
+  test/core/end2end/tests/payload.c
+  test/core/end2end/tests/ping.c
+  test/core/end2end/tests/ping_pong_streaming.c
+  test/core/end2end/tests/registered_call.c
+  test/core/end2end/tests/request_with_flags.c
+  test/core/end2end/tests/request_with_payload.c
+  test/core/end2end/tests/resource_quota_server.c
+  test/core/end2end/tests/server_finishes_request.c
+  test/core/end2end/tests/shutdown_finishes_calls.c
+  test/core/end2end/tests/shutdown_finishes_tags.c
+  test/core/end2end/tests/simple_cacheable_request.c
+  test/core/end2end/tests/simple_delayed_request.c
+  test/core/end2end/tests/simple_metadata.c
+  test/core/end2end/tests/simple_request.c
+  test/core/end2end/tests/streaming_error_response.c
+  test/core/end2end/tests/trailing_metadata.c
+  test/core/end2end/tests/write_buffering.c
+  test/core/end2end/tests/write_buffering_at_end.c
+)
+
+
+target_include_directories(end2end_tests
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(end2end_tests
+  ${_gRPC_SSL_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_library(end2end_nosec_tests
+  test/core/end2end/end2end_nosec_tests.c
+  test/core/end2end/end2end_test_utils.c
+  test/core/end2end/tests/authority_not_supported.c
+  test/core/end2end/tests/bad_hostname.c
+  test/core/end2end/tests/binary_metadata.c
+  test/core/end2end/tests/cancel_after_accept.c
+  test/core/end2end/tests/cancel_after_client_done.c
+  test/core/end2end/tests/cancel_after_invoke.c
+  test/core/end2end/tests/cancel_before_invoke.c
+  test/core/end2end/tests/cancel_in_a_vacuum.c
+  test/core/end2end/tests/cancel_with_status.c
+  test/core/end2end/tests/compressed_payload.c
+  test/core/end2end/tests/connectivity.c
+  test/core/end2end/tests/default_host.c
+  test/core/end2end/tests/disappearing_server.c
+  test/core/end2end/tests/empty_batch.c
+  test/core/end2end/tests/filter_call_init_fails.c
+  test/core/end2end/tests/filter_causes_close.c
+  test/core/end2end/tests/filter_latency.c
+  test/core/end2end/tests/graceful_server_shutdown.c
+  test/core/end2end/tests/high_initial_seqno.c
+  test/core/end2end/tests/hpack_size.c
+  test/core/end2end/tests/idempotent_request.c
+  test/core/end2end/tests/invoke_large_request.c
+  test/core/end2end/tests/large_metadata.c
+  test/core/end2end/tests/load_reporting_hook.c
+  test/core/end2end/tests/max_concurrent_streams.c
+  test/core/end2end/tests/max_message_length.c
+  test/core/end2end/tests/negative_deadline.c
+  test/core/end2end/tests/network_status_change.c
+  test/core/end2end/tests/no_logging.c
+  test/core/end2end/tests/no_op.c
+  test/core/end2end/tests/payload.c
+  test/core/end2end/tests/ping.c
+  test/core/end2end/tests/ping_pong_streaming.c
+  test/core/end2end/tests/registered_call.c
+  test/core/end2end/tests/request_with_flags.c
+  test/core/end2end/tests/request_with_payload.c
+  test/core/end2end/tests/resource_quota_server.c
+  test/core/end2end/tests/server_finishes_request.c
+  test/core/end2end/tests/shutdown_finishes_calls.c
+  test/core/end2end/tests/shutdown_finishes_tags.c
+  test/core/end2end/tests/simple_cacheable_request.c
+  test/core/end2end/tests/simple_delayed_request.c
+  test/core/end2end/tests/simple_metadata.c
+  test/core/end2end/tests/simple_request.c
+  test/core/end2end/tests/streaming_error_response.c
+  test/core/end2end/tests/trailing_metadata.c
+  test/core/end2end/tests/write_buffering.c
+  test/core/end2end/tests/write_buffering_at_end.c
+)
+
+
+target_include_directories(end2end_nosec_tests
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+
+endif (gRPC_BUILD_TESTS)
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(alarm_test
+  test/core/surface/alarm_test.c
+)
+
+target_include_directories(alarm_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(alarm_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(algorithm_test
+  test/core/compression/algorithm_test.c
+)
+
+target_include_directories(algorithm_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(algorithm_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(alloc_test
+  test/core/support/alloc_test.c
+)
+
+target_include_directories(alloc_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(alloc_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(alpn_test
+  test/core/transport/chttp2/alpn_test.c
+)
+
+target_include_directories(alpn_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(alpn_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bad_server_response_test
+  test/core/end2end/bad_server_response_test.c
+)
+
+target_include_directories(bad_server_response_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_server_response_test
+  test_tcp_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bin_decoder_test
+  test/core/transport/chttp2/bin_decoder_test.c
+)
+
+target_include_directories(bin_decoder_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bin_decoder_test
+  grpc_test_util
+  grpc
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bin_encoder_test
+  test/core/transport/chttp2/bin_encoder_test.c
+)
+
+target_include_directories(bin_encoder_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bin_encoder_test
+  grpc_test_util
+  grpc
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(census_context_test
+  test/core/census/context_test.c
+)
+
+target_include_directories(census_context_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(census_context_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(census_resource_test
+  test/core/census/resource_test.c
+)
+
+target_include_directories(census_resource_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(census_resource_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(census_trace_context_test
+  test/core/census/trace_context_test.c
+)
+
+target_include_directories(census_trace_context_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(census_trace_context_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(channel_create_test
+  test/core/surface/channel_create_test.c
+)
+
+target_include_directories(channel_create_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(channel_create_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(chttp2_hpack_encoder_test
+  test/core/transport/chttp2/hpack_encoder_test.c
+)
+
+target_include_directories(chttp2_hpack_encoder_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(chttp2_hpack_encoder_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(chttp2_status_conversion_test
+  test/core/transport/chttp2/status_conversion_test.c
+)
+
+target_include_directories(chttp2_status_conversion_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(chttp2_status_conversion_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(chttp2_stream_map_test
+  test/core/transport/chttp2/stream_map_test.c
+)
+
+target_include_directories(chttp2_stream_map_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(chttp2_stream_map_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(chttp2_varint_test
+  test/core/transport/chttp2/varint_test.c
+)
+
+target_include_directories(chttp2_varint_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(chttp2_varint_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(combiner_test
+  test/core/iomgr/combiner_test.c
+)
+
+target_include_directories(combiner_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(combiner_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(compression_test
+  test/core/compression/compression_test.c
+)
+
+target_include_directories(compression_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(compression_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(concurrent_connectivity_test
+  test/core/surface/concurrent_connectivity_test.c
+)
+
+target_include_directories(concurrent_connectivity_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(concurrent_connectivity_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(connection_refused_test
+  test/core/end2end/connection_refused_test.c
+)
+
+target_include_directories(connection_refused_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(connection_refused_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(dns_resolver_connectivity_test
+  test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+)
+
+target_include_directories(dns_resolver_connectivity_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(dns_resolver_connectivity_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(dns_resolver_test
+  test/core/client_channel/resolvers/dns_resolver_test.c
+)
+
+target_include_directories(dns_resolver_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(dns_resolver_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(dualstack_socket_test
+  test/core/end2end/dualstack_socket_test.c
+)
+
+target_include_directories(dualstack_socket_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(dualstack_socket_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(endpoint_pair_test
+  test/core/iomgr/endpoint_pair_test.c
+)
+
+target_include_directories(endpoint_pair_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(endpoint_pair_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(ev_epoll_linux_test
+  test/core/iomgr/ev_epoll_linux_test.c
+)
+
+target_include_directories(ev_epoll_linux_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(ev_epoll_linux_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fd_conservation_posix_test
+  test/core/iomgr/fd_conservation_posix_test.c
+)
+
+target_include_directories(fd_conservation_posix_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fd_conservation_posix_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fd_posix_test
+  test/core/iomgr/fd_posix_test.c
+)
+
+target_include_directories(fd_posix_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fd_posix_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fling_client
+  test/core/fling/client.c
+)
+
+target_include_directories(fling_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fling_client
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fling_server
+  test/core/fling/server.c
+)
+
+target_include_directories(fling_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fling_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fling_stream_test
+  test/core/fling/fling_stream_test.c
+)
+
+target_include_directories(fling_stream_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fling_stream_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(fling_test
+  test/core/fling/fling_test.c
+)
+
+target_include_directories(fling_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(fling_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+
+add_executable(gen_hpack_tables
+  tools/codegen/core/gen_hpack_tables.c
+)
+
+target_include_directories(gen_hpack_tables
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gen_hpack_tables
+  gpr
+  grpc
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS gen_hpack_tables EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(gen_legal_metadata_characters
+  tools/codegen/core/gen_legal_metadata_characters.c
+)
+
+target_include_directories(gen_legal_metadata_characters
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+
+
+if (gRPC_INSTALL)
+  install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(gen_percent_encoding_tables
+  tools/codegen/core/gen_percent_encoding_tables.c
+)
+
+target_include_directories(gen_percent_encoding_tables
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+
+
+if (gRPC_INSTALL)
+  install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(goaway_server_test
+  test/core/end2end/goaway_server_test.c
+)
+
+target_include_directories(goaway_server_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(goaway_server_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_avl_test
+  test/core/support/avl_test.c
+)
+
+target_include_directories(gpr_avl_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_avl_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_backoff_test
+  test/core/support/backoff_test.c
+)
+
+target_include_directories(gpr_backoff_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_backoff_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_cmdline_test
+  test/core/support/cmdline_test.c
+)
+
+target_include_directories(gpr_cmdline_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_cmdline_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_cpu_test
+  test/core/support/cpu_test.c
+)
+
+target_include_directories(gpr_cpu_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_cpu_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_env_test
+  test/core/support/env_test.c
+)
+
+target_include_directories(gpr_env_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_env_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_histogram_test
+  test/core/support/histogram_test.c
+)
+
+target_include_directories(gpr_histogram_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_histogram_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_host_port_test
+  test/core/support/host_port_test.c
+)
+
+target_include_directories(gpr_host_port_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_host_port_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_log_test
+  test/core/support/log_test.c
+)
+
+target_include_directories(gpr_log_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_log_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_mpscq_test
+  test/core/support/mpscq_test.c
+)
+
+target_include_directories(gpr_mpscq_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_mpscq_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_stack_lockfree_test
+  test/core/support/stack_lockfree_test.c
+)
+
+target_include_directories(gpr_stack_lockfree_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_stack_lockfree_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_string_test
+  test/core/support/string_test.c
+)
+
+target_include_directories(gpr_string_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_string_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_sync_test
+  test/core/support/sync_test.c
+)
+
+target_include_directories(gpr_sync_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_sync_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_thd_test
+  test/core/support/thd_test.c
+)
+
+target_include_directories(gpr_thd_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_thd_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_time_test
+  test/core/support/time_test.c
+)
+
+target_include_directories(gpr_time_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_time_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_tls_test
+  test/core/support/tls_test.c
+)
+
+target_include_directories(gpr_tls_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_tls_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(gpr_useful_test
+  test/core/support/useful_test.c
+)
+
+target_include_directories(gpr_useful_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(gpr_useful_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_auth_context_test
+  test/core/security/auth_context_test.c
+)
+
+target_include_directories(grpc_auth_context_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_auth_context_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_b64_test
+  test/core/security/b64_test.c
+)
+
+target_include_directories(grpc_b64_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_b64_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_byte_buffer_reader_test
+  test/core/surface/byte_buffer_reader_test.c
+)
+
+target_include_directories(grpc_byte_buffer_reader_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_byte_buffer_reader_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_channel_args_test
+  test/core/channel/channel_args_test.c
+)
+
+target_include_directories(grpc_channel_args_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_channel_args_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_channel_stack_test
+  test/core/channel/channel_stack_test.c
+)
+
+target_include_directories(grpc_channel_stack_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_channel_stack_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_completion_queue_test
+  test/core/surface/completion_queue_test.c
+)
+
+target_include_directories(grpc_completion_queue_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_completion_queue_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+
+add_executable(grpc_create_jwt
+  test/core/security/create_jwt.c
 )
 
 target_include_directories(grpc_create_jwt
@@ -1995,275 +5776,5835 @@ target_include_directories(grpc_create_jwt
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_create_jwt
+  ${_gRPC_SSL_LIBRARIES}
+  grpc
+  gpr
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_create_jwt EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_credentials_test
+  test/core/security/credentials_test.c
+)
+
+target_include_directories(grpc_credentials_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_credentials_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_fetch_oauth2
+  test/core/security/fetch_oauth2.c
+)
+
+target_include_directories(grpc_fetch_oauth2
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_fetch_oauth2
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_invalid_channel_args_test
+  test/core/surface/invalid_channel_args_test.c
+)
+
+target_include_directories(grpc_invalid_channel_args_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_invalid_channel_args_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_json_token_test
+  test/core/security/json_token_test.c
+)
+
+target_include_directories(grpc_json_token_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_json_token_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_jwt_verifier_test
+  test/core/security/jwt_verifier_test.c
+)
+
+target_include_directories(grpc_jwt_verifier_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_jwt_verifier_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+
+add_executable(grpc_print_google_default_creds_token
+  test/core/security/print_google_default_creds_token.c
+)
+
+target_include_directories(grpc_print_google_default_creds_token
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_print_google_default_creds_token
+  grpc
+  gpr
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_security_connector_test
+  test/core/security/security_connector_test.c
+)
+
+target_include_directories(grpc_security_connector_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_security_connector_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+
+add_executable(grpc_verify_jwt
+  test/core/security/verify_jwt.c
+)
+
+target_include_directories(grpc_verify_jwt
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_verify_jwt
+  grpc
+  gpr
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_verify_jwt EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(handshake_client
+  test/core/handshake/client_ssl.c
+)
+
+target_include_directories(handshake_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(handshake_client
+  ${_gRPC_SSL_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(handshake_server
+  test/core/handshake/server_ssl.c
+)
+
+target_include_directories(handshake_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(handshake_server
+  ${_gRPC_SSL_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(hpack_parser_test
+  test/core/transport/chttp2/hpack_parser_test.c
+)
+
+target_include_directories(hpack_parser_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(hpack_parser_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(hpack_table_test
+  test/core/transport/chttp2/hpack_table_test.c
+)
+
+target_include_directories(hpack_table_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(hpack_table_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(http_parser_test
+  test/core/http/parser_test.c
+)
+
+target_include_directories(http_parser_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(http_parser_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(httpcli_format_request_test
+  test/core/http/format_request_test.c
+)
+
+target_include_directories(httpcli_format_request_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(httpcli_format_request_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(httpcli_test
+  test/core/http/httpcli_test.c
+)
+
+target_include_directories(httpcli_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(httpcli_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(httpscli_test
+  test/core/http/httpscli_test.c
+)
+
+target_include_directories(httpscli_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(httpscli_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(init_test
+  test/core/surface/init_test.c
+)
+
+target_include_directories(init_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(init_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(internal_api_canary_iomgr_test
+  test/core/internal_api_canaries/iomgr.c
+)
+
+target_include_directories(internal_api_canary_iomgr_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(internal_api_canary_iomgr_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(internal_api_canary_support_test
+  test/core/internal_api_canaries/iomgr.c
+)
+
+target_include_directories(internal_api_canary_support_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(internal_api_canary_support_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(internal_api_canary_transport_test
+  test/core/internal_api_canaries/iomgr.c
+)
+
+target_include_directories(internal_api_canary_transport_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(internal_api_canary_transport_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(invalid_call_argument_test
+  test/core/end2end/invalid_call_argument_test.c
+)
+
+target_include_directories(invalid_call_argument_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(invalid_call_argument_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_rewrite
+  test/core/json/json_rewrite.c
+)
+
+target_include_directories(json_rewrite
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(json_rewrite
+  grpc
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_rewrite_test
+  test/core/json/json_rewrite_test.c
+)
+
+target_include_directories(json_rewrite_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(json_rewrite_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_stream_error_test
+  test/core/json/json_stream_error_test.c
+)
+
+target_include_directories(json_stream_error_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(json_stream_error_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_test
+  test/core/json/json_test.c
+)
+
+target_include_directories(json_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(json_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(lame_client_test
+  test/core/surface/lame_client_test.c
+)
+
+target_include_directories(lame_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(lame_client_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(lb_policies_test
+  test/core/client_channel/lb_policies_test.c
+)
+
+target_include_directories(lb_policies_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(lb_policies_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(load_file_test
+  test/core/iomgr/load_file_test.c
+)
+
+target_include_directories(load_file_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(load_file_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(memory_profile_client
+  test/core/memory_usage/client.c
+)
+
+target_include_directories(memory_profile_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(memory_profile_client
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(memory_profile_server
+  test/core/memory_usage/server.c
+)
+
+target_include_directories(memory_profile_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(memory_profile_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(memory_profile_test
+  test/core/memory_usage/memory_usage_test.c
+)
+
+target_include_directories(memory_profile_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(memory_profile_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(message_compress_test
+  test/core/compression/message_compress_test.c
+)
+
+target_include_directories(message_compress_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(message_compress_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(mlog_test
+  test/core/census/mlog_test.c
+)
+
+target_include_directories(mlog_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(mlog_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(multiple_server_queues_test
+  test/core/end2end/multiple_server_queues_test.c
+)
+
+target_include_directories(multiple_server_queues_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(multiple_server_queues_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(murmur_hash_test
+  test/core/support/murmur_hash_test.c
+)
+
+target_include_directories(murmur_hash_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(murmur_hash_test
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(no_server_test
+  test/core/end2end/no_server_test.c
+)
+
+target_include_directories(no_server_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(no_server_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(percent_encoding_test
+  test/core/slice/percent_encoding_test.c
+)
+
+target_include_directories(percent_encoding_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(percent_encoding_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(resolve_address_test
+  test/core/iomgr/resolve_address_test.c
+)
+
+target_include_directories(resolve_address_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(resolve_address_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(resource_quota_test
+  test/core/iomgr/resource_quota_test.c
+)
+
+target_include_directories(resource_quota_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(resource_quota_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(secure_channel_create_test
+  test/core/surface/secure_channel_create_test.c
+)
+
+target_include_directories(secure_channel_create_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(secure_channel_create_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(secure_endpoint_test
+  test/core/security/secure_endpoint_test.c
+)
+
+target_include_directories(secure_endpoint_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(secure_endpoint_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(sequential_connectivity_test
+  test/core/surface/sequential_connectivity_test.c
+)
+
+target_include_directories(sequential_connectivity_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(sequential_connectivity_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_chttp2_test
+  test/core/surface/server_chttp2_test.c
+)
+
+target_include_directories(server_chttp2_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(server_chttp2_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_test
+  test/core/surface/server_test.c
+)
+
+target_include_directories(server_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(server_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(set_initial_connect_string_test
+  test/core/client_channel/set_initial_connect_string_test.c
+)
+
+target_include_directories(set_initial_connect_string_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(set_initial_connect_string_test
+  test_tcp_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(slice_buffer_test
+  test/core/slice/slice_buffer_test.c
+)
+
+target_include_directories(slice_buffer_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(slice_buffer_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(slice_string_helpers_test
+  test/core/slice/slice_string_helpers_test.c
+)
+
+target_include_directories(slice_string_helpers_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(slice_string_helpers_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(slice_test
+  test/core/slice/slice_test.c
+)
+
+target_include_directories(slice_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(slice_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(sockaddr_resolver_test
+  test/core/client_channel/resolvers/sockaddr_resolver_test.c
+)
+
+target_include_directories(sockaddr_resolver_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(sockaddr_resolver_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(sockaddr_utils_test
+  test/core/iomgr/sockaddr_utils_test.c
+)
+
+target_include_directories(sockaddr_utils_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(sockaddr_utils_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(socket_utils_test
+  test/core/iomgr/socket_utils_test.c
+)
+
+target_include_directories(socket_utils_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(socket_utils_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(tcp_client_posix_test
+  test/core/iomgr/tcp_client_posix_test.c
+)
+
+target_include_directories(tcp_client_posix_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(tcp_client_posix_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(tcp_posix_test
+  test/core/iomgr/tcp_posix_test.c
+)
+
+target_include_directories(tcp_posix_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(tcp_posix_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(tcp_server_posix_test
+  test/core/iomgr/tcp_server_posix_test.c
+)
+
+target_include_directories(tcp_server_posix_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(tcp_server_posix_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(time_averaged_stats_test
+  test/core/iomgr/time_averaged_stats_test.c
+)
+
+target_include_directories(time_averaged_stats_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(time_averaged_stats_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(timeout_encoding_test
+  test/core/transport/timeout_encoding_test.c
+)
+
+target_include_directories(timeout_encoding_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(timeout_encoding_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(timer_heap_test
+  test/core/iomgr/timer_heap_test.c
+)
+
+target_include_directories(timer_heap_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(timer_heap_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(timer_list_test
+  test/core/iomgr/timer_list_test.c
+)
+
+target_include_directories(timer_list_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(timer_list_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(transport_connectivity_state_test
+  test/core/transport/connectivity_state_test.c
+)
+
+target_include_directories(transport_connectivity_state_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(transport_connectivity_state_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(transport_metadata_test
+  test/core/transport/metadata_test.c
+)
+
+target_include_directories(transport_metadata_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(transport_metadata_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(transport_pid_controller_test
+  test/core/transport/pid_controller_test.c
+)
+
+target_include_directories(transport_pid_controller_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(transport_pid_controller_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(transport_security_test
+  test/core/tsi/transport_security_test.c
+)
+
+target_include_directories(transport_security_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(transport_security_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(udp_server_test
+  test/core/iomgr/udp_server_test.c
+)
+
+target_include_directories(udp_server_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(udp_server_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(uri_parser_test
+  test/core/client_channel/uri_parser_test.c
+)
+
+target_include_directories(uri_parser_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(uri_parser_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(wakeup_fd_cv_test
+  test/core/iomgr/wakeup_fd_cv_test.c
+)
+
+target_include_directories(wakeup_fd_cv_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(wakeup_fd_cv_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(alarm_cpp_test
+  test/cpp/common/alarm_cpp_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(alarm_cpp_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(alarm_cpp_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(async_end2end_test
+  test/cpp/end2end/async_end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(async_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(async_end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(auth_property_iterator_test
+  test/cpp/common/auth_property_iterator_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(auth_property_iterator_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(auth_property_iterator_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bm_fullstack
+  test/cpp/microbenchmarks/bm_fullstack.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(bm_fullstack
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(bm_fullstack
+  benchmark
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(channel_arguments_test
+  test/cpp/common/channel_arguments_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(channel_arguments_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(channel_arguments_test
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(channel_filter_test
+  test/cpp/common/channel_filter_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(channel_filter_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(channel_filter_test
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(cli_call_test
+  test/cpp/util/cli_call_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(cli_call_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(cli_call_test
+  grpc_cli_libs
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(client_crash_test
+  test/cpp/end2end/client_crash_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(client_crash_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(client_crash_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(client_crash_test_server
+  test/cpp/end2end/client_crash_test_server.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(client_crash_test_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(client_crash_test_server
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(codegen_test_full
+  src/proto/grpc/testing/control.proto
+  src/proto/grpc/testing/messages.proto
+  src/proto/grpc/testing/payloads.proto
+  src/proto/grpc/testing/services.proto
+  src/proto/grpc/testing/stats.proto
+  test/cpp/codegen/codegen_test_full.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(codegen_test_full
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(codegen_test_full
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(codegen_test_minimal
+  src/proto/grpc/testing/control.proto
+  src/proto/grpc/testing/messages.proto
+  src/proto/grpc/testing/payloads.proto
+  src/proto/grpc/testing/services.proto
+  src/proto/grpc/testing/stats.proto
+  test/cpp/codegen/codegen_test_minimal.cc
+  src/cpp/codegen/codegen_init.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(codegen_test_minimal
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(codegen_test_minimal
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(credentials_test
+  test/cpp/client/credentials_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(credentials_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(credentials_test
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(cxx_byte_buffer_test
+  test/cpp/util/byte_buffer_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(cxx_byte_buffer_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(cxx_byte_buffer_test
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(cxx_slice_test
+  test/cpp/util/slice_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(cxx_slice_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(cxx_slice_test
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(cxx_string_ref_test
+  test/cpp/util/string_ref_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(cxx_string_ref_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(cxx_string_ref_test
+  grpc++
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(cxx_time_test
+  test/cpp/util/time_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(cxx_time_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(cxx_time_test
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(end2end_test
+  test/cpp/end2end/end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(filter_end2end_test
+  test/cpp/end2end/filter_end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(filter_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(filter_end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(generic_end2end_test
+  test/cpp/end2end/generic_end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(generic_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(generic_end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(golden_file_test
+  src/proto/grpc/testing/compiler_test.proto
+  test/cpp/codegen/golden_file_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(golden_file_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(golden_file_test
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_cli
+  test/cpp/util/grpc_cli.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(grpc_cli
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(grpc_cli
+  grpc_cli_libs
+  grpc++_proto_reflection_desc_db
+  grpc++
+  grpc
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+
+add_executable(grpc_cpp_plugin
+  src/compiler/cpp_plugin.cc
+)
+
+target_include_directories(grpc_cpp_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_cpp_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_csharp_plugin
+  src/compiler/csharp_plugin.cc
+)
+
+target_include_directories(grpc_csharp_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_csharp_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_node_plugin
+  src/compiler/node_plugin.cc
+)
+
+target_include_directories(grpc_node_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_node_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_node_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_objective_c_plugin
+  src/compiler/objective_c_plugin.cc
+)
+
+target_include_directories(grpc_objective_c_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_objective_c_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_php_plugin
+  src/compiler/php_plugin.cc
+)
+
+target_include_directories(grpc_php_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_php_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_php_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_python_plugin
+  src/compiler/python_plugin.cc
+)
+
+target_include_directories(grpc_python_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_python_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_python_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
+add_executable(grpc_ruby_plugin
+  src/compiler/ruby_plugin.cc
+)
+
+target_include_directories(grpc_ruby_plugin
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(grpc_ruby_plugin
+  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
+  grpc_plugin_support
+)
+
+
+if (gRPC_INSTALL)
+  install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_tool_test
+  src/proto/grpc/testing/echo.proto
+  src/proto/grpc/testing/echo_messages.proto
+  test/cpp/util/grpc_tool_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(grpc_tool_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(grpc_tool_test
+  grpc_cli_libs
+  grpc++_proto_reflection_desc_db
+  grpc++_reflection
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpclb_api_test
+  src/proto/grpc/lb/v1/load_balancer.proto
+  test/cpp/grpclb/grpclb_api_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(grpclb_api_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(grpclb_api_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(grpclb_test
+  src/proto/grpc/lb/v1/load_balancer.proto
+  test/cpp/grpclb/grpclb_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(grpclb_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(grpclb_test
+  gpr
+  gpr_test_util
+  grpc
+  grpc++
+  grpc++_test_util
+  grpc_test_util
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(http2_client
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(http2_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(http2_client
+  http2_client_main
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(hybrid_end2end_test
+  test/cpp/end2end/hybrid_end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(hybrid_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(hybrid_end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(interop_client
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(interop_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(interop_client
+  interop_client_main
+  interop_client_helper
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(interop_server
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(interop_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(interop_server
+  interop_server_main
+  interop_server_helper
+  interop_server_lib
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(interop_test
+  test/cpp/interop/interop_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(interop_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(interop_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_run_localhost
+  test/cpp/qps/json_run_localhost.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(json_run_localhost
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(json_run_localhost
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(metrics_client
+  src/proto/grpc/testing/metrics.proto
+  test/cpp/interop/metrics_client.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(metrics_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(metrics_client
+  grpc++
+  grpc
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(mock_test
+  test/cpp/end2end/mock_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(mock_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(mock_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(noop-benchmark
+  test/cpp/microbenchmarks/noop-benchmark.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(noop-benchmark
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(noop-benchmark
+  benchmark
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(proto_server_reflection_test
+  test/cpp/end2end/proto_server_reflection_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(proto_server_reflection_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(proto_server_reflection_test
+  grpc++_proto_reflection_desc_db
+  grpc++_reflection
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(qps_interarrival_test
+  test/cpp/qps/qps_interarrival_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(qps_interarrival_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(qps_interarrival_test
+  qps
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(qps_json_driver
+  test/cpp/qps/qps_json_driver.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(qps_json_driver
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(qps_json_driver
+  qps
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(qps_openloop_test
+  test/cpp/qps/qps_openloop_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(qps_openloop_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(qps_openloop_test
+  qps
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(qps_worker
+  test/cpp/qps/worker.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(qps_worker
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(qps_worker
+  qps
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(reconnect_interop_client
+  src/proto/grpc/testing/empty.proto
+  src/proto/grpc/testing/messages.proto
+  src/proto/grpc/testing/test.proto
+  test/cpp/interop/reconnect_interop_client.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(reconnect_interop_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(reconnect_interop_client
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(reconnect_interop_server
+  src/proto/grpc/testing/empty.proto
+  src/proto/grpc/testing/messages.proto
+  src/proto/grpc/testing/test.proto
+  test/cpp/interop/reconnect_interop_server.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(reconnect_interop_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(reconnect_interop_server
+  reconnect_server
+  test_tcp_server
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(round_robin_end2end_test
+  test/cpp/end2end/round_robin_end2end_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(round_robin_end2end_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(round_robin_end2end_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(secure_auth_context_test
+  test/cpp/common/secure_auth_context_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(secure_auth_context_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(secure_auth_context_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(secure_sync_unary_ping_pong_test
+  test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(secure_sync_unary_ping_pong_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(secure_sync_unary_ping_pong_test
+  qps
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_builder_plugin_test
+  test/cpp/end2end/server_builder_plugin_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(server_builder_plugin_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(server_builder_plugin_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_context_test_spouse_test
+  test/cpp/test/server_context_test_spouse_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(server_context_test_spouse_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(server_context_test_spouse_test
+  grpc_test_util
+  grpc++_test
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_crash_test
+  test/cpp/end2end/server_crash_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(server_crash_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(server_crash_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_crash_test_client
+  test/cpp/end2end/server_crash_test_client.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(server_crash_test_client
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(server_crash_test_client
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(shutdown_test
+  test/cpp/end2end/shutdown_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(shutdown_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(shutdown_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(status_test
+  test/cpp/util/status_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(status_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(status_test
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(streaming_throughput_test
+  test/cpp/end2end/streaming_throughput_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(streaming_throughput_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(streaming_throughput_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(stress_test
+  src/proto/grpc/testing/empty.proto
+  src/proto/grpc/testing/messages.proto
+  src/proto/grpc/testing/metrics.proto
+  src/proto/grpc/testing/test.proto
+  test/cpp/interop/client_helper.cc
+  test/cpp/interop/interop_client.cc
+  test/cpp/interop/stress_interop_client.cc
+  test/cpp/interop/stress_test.cc
+  test/cpp/util/metrics_server.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(stress_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(stress_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(thread_manager_test
+  test/cpp/thread_manager/thread_manager_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(thread_manager_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(thread_manager_test
+  grpc++
+  grpc
+  gpr
+  grpc++_test_config
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(thread_stress_test
+  test/cpp/end2end/thread_stress_test.cc
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(thread_stress_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(thread_stress_test
+  grpc++_test_util
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_aes_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_aes_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_aes_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_aes_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_asn1_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_asn1_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_asn1_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_asn1_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_base64_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_base64_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_base64_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_base64_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_bio_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_bio_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_bio_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_bio_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_bn_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_bn_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_bn_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_bn_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_bytestring_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_bytestring_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_bytestring_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_bytestring_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_aead_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_aead_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_aead_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_aead_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_cipher_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_cipher_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_cipher_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_cipher_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_cmac_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_cmac_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_cmac_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_cmac_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_constant_time_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_constant_time_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_constant_time_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_constant_time_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_ed25519_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_ed25519_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_ed25519_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_ed25519_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_x25519_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_x25519_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_x25519_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_x25519_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_dh_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_dh_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_dh_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_dh_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_digest_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_digest_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_digest_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_digest_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_dsa_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_dsa_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_dsa_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_dsa_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_ec_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_ec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_ec_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_ec_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_example_mul
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_example_mul
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_example_mul
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_example_mul_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_ecdsa_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_ecdsa_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_ecdsa_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_ecdsa_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_err_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_err_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_err_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_err_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_evp_extra_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_evp_extra_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_evp_extra_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_evp_extra_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_evp_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_evp_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_evp_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_evp_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_pbkdf_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_pbkdf_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_pbkdf_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_pbkdf_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_hkdf_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_hkdf_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_hkdf_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_hkdf_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_hmac_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_hmac_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_hmac_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_hmac_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_lhash_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_lhash_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_lhash_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_lhash_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_gcm_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_gcm_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_gcm_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_gcm_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_pkcs12_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_pkcs12_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_pkcs12_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_pkcs12_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_pkcs8_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_pkcs8_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_pkcs8_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_pkcs8_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_poly1305_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_poly1305_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_poly1305_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_poly1305_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_refcount_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_refcount_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_refcount_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_refcount_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_rsa_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_rsa_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_rsa_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_rsa_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_thread_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_thread_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_thread_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_thread_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_pkcs7_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_pkcs7_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_pkcs7_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_pkcs7_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_x509_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_x509_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_x509_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_x509_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_tab_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_tab_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_tab_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_tab_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_v3name_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_v3name_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_v3name_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_v3name_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_pqueue_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_pqueue_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_pqueue_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_pqueue_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(boringssl_ssl_test
+  third_party/googletest/src/gtest-all.cc
+)
+
+target_include_directories(boringssl_ssl_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  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
+)
+
+target_link_libraries(boringssl_ssl_test
+  ${_gRPC_SSL_LIBRARIES}
+  boringssl_ssl_test_lib
+  boringssl_test_util
+  boringssl
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(badreq_bad_client_test
+  test/core/bad_client/tests/badreq.c
+)
+
+target_include_directories(badreq_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(badreq_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(connection_prefix_bad_client_test
+  test/core/bad_client/tests/connection_prefix.c
+)
+
+target_include_directories(connection_prefix_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(connection_prefix_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(head_of_line_blocking_bad_client_test
+  test/core/bad_client/tests/head_of_line_blocking.c
+)
+
+target_include_directories(head_of_line_blocking_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(head_of_line_blocking_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(headers_bad_client_test
+  test/core/bad_client/tests/headers.c
+)
+
+target_include_directories(headers_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(headers_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(initial_settings_frame_bad_client_test
+  test/core/bad_client/tests/initial_settings_frame.c
+)
+
+target_include_directories(initial_settings_frame_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(initial_settings_frame_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(large_metadata_bad_client_test
+  test/core/bad_client/tests/large_metadata.c
+)
+
+target_include_directories(large_metadata_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(large_metadata_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(server_registered_method_bad_client_test
+  test/core/bad_client/tests/server_registered_method.c
+)
+
+target_include_directories(server_registered_method_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(server_registered_method_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(simple_request_bad_client_test
+  test/core/bad_client/tests/simple_request.c
+)
+
+target_include_directories(simple_request_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(simple_request_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(unknown_frame_bad_client_test
+  test/core/bad_client/tests/unknown_frame.c
+)
+
+target_include_directories(unknown_frame_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(unknown_frame_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(window_overflow_bad_client_test
+  test/core/bad_client/tests/window_overflow.c
+)
+
+target_include_directories(window_overflow_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(window_overflow_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bad_ssl_cert_server
+  test/core/bad_ssl/servers/cert.c
+)
+
+target_include_directories(bad_ssl_cert_server
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_ssl_cert_server
+  bad_ssl_test_server
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(bad_ssl_cert_test
+  test/core/bad_ssl/bad_ssl_test.c
+)
+
+target_include_directories(bad_ssl_cert_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(bad_ssl_cert_test
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_census_test
+  test/core/end2end/fixtures/h2_census.c
+)
+
+target_include_directories(h2_census_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_census_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_compress_test
+  test/core/end2end/fixtures/h2_compress.c
+)
+
+target_include_directories(h2_compress_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_compress_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_fakesec_test
+  test/core/end2end/fixtures/h2_fakesec.c
+)
+
+target_include_directories(h2_fakesec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_fakesec_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_fd_test
+  test/core/end2end/fixtures/h2_fd.c
+)
+
+target_include_directories(h2_fd_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_fd_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full_test
+  test/core/end2end/fixtures/h2_full.c
+)
+
+target_include_directories(h2_full_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full+pipe_test
+  test/core/end2end/fixtures/h2_full+pipe.c
+)
+
+target_include_directories(h2_full+pipe_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full+pipe_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full+trace_test
+  test/core/end2end/fixtures/h2_full+trace.c
+)
+
+target_include_directories(h2_full+trace_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full+trace_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_http_proxy_test
+  test/core/end2end/fixtures/h2_http_proxy.c
+)
+
+target_include_directories(h2_http_proxy_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_http_proxy_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_load_reporting_test
+  test/core/end2end/fixtures/h2_load_reporting.c
+)
+
+target_include_directories(h2_load_reporting_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_load_reporting_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_oauth2_test
+  test/core/end2end/fixtures/h2_oauth2.c
+)
+
+target_include_directories(h2_oauth2_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_oauth2_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_proxy_test
+  test/core/end2end/fixtures/h2_proxy.c
+)
+
+target_include_directories(h2_proxy_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_proxy_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_sockpair_test
+  test/core/end2end/fixtures/h2_sockpair.c
+)
+
+target_include_directories(h2_sockpair_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_sockpair_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_sockpair+trace_test
+  test/core/end2end/fixtures/h2_sockpair+trace.c
+)
+
+target_include_directories(h2_sockpair+trace_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_sockpair+trace_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_sockpair_1byte_test
+  test/core/end2end/fixtures/h2_sockpair_1byte.c
+)
+
+target_include_directories(h2_sockpair_1byte_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_sockpair_1byte_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_ssl_test
+  test/core/end2end/fixtures/h2_ssl.c
+)
+
+target_include_directories(h2_ssl_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_ssl_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_ssl_cert_test
+  test/core/end2end/fixtures/h2_ssl_cert.c
+)
+
+target_include_directories(h2_ssl_cert_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_ssl_cert_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_ssl_proxy_test
+  test/core/end2end/fixtures/h2_ssl_proxy.c
+)
+
+target_include_directories(h2_ssl_proxy_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_ssl_proxy_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_uds_test
+  test/core/end2end/fixtures/h2_uds.c
+)
+
+target_include_directories(h2_uds_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_uds_test
+  end2end_tests
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_census_nosec_test
+  test/core/end2end/fixtures/h2_census.c
+)
+
+target_include_directories(h2_census_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_census_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_compress_nosec_test
+  test/core/end2end/fixtures/h2_compress.c
+)
+
+target_include_directories(h2_compress_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_compress_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_fd_nosec_test
+  test/core/end2end/fixtures/h2_fd.c
+)
+
+target_include_directories(h2_fd_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_fd_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full_nosec_test
+  test/core/end2end/fixtures/h2_full.c
+)
+
+target_include_directories(h2_full_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full+pipe_nosec_test
+  test/core/end2end/fixtures/h2_full+pipe.c
+)
+
+target_include_directories(h2_full+pipe_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full+pipe_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_full+trace_nosec_test
+  test/core/end2end/fixtures/h2_full+trace.c
+)
+
+target_include_directories(h2_full+trace_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_full+trace_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_http_proxy_nosec_test
+  test/core/end2end/fixtures/h2_http_proxy.c
+)
+
+target_include_directories(h2_http_proxy_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_http_proxy_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_load_reporting_nosec_test
+  test/core/end2end/fixtures/h2_load_reporting.c
+)
+
+target_include_directories(h2_load_reporting_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(h2_load_reporting_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_proxy_nosec_test
+  test/core/end2end/fixtures/h2_proxy.c
+)
+
+target_include_directories(h2_proxy_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_create_jwt
-  ${_gRPC_SSL_LIBRARIES}
-  grpc
+target_link_libraries(h2_proxy_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
   gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_create_jwt EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
-
-add_executable(grpc_print_google_default_creds_token
-  test/core/security/print_google_default_creds_token.c
+add_executable(h2_sockpair_nosec_test
+  test/core/end2end/fixtures/h2_sockpair.c
 )
 
-target_include_directories(grpc_print_google_default_creds_token
+target_include_directories(h2_sockpair_nosec_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_print_google_default_creds_token
-  grpc
+target_link_libraries(h2_sockpair_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
   gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
-
-
-add_executable(grpc_verify_jwt
-  test/core/security/verify_jwt.c
+add_executable(h2_sockpair+trace_nosec_test
+  test/core/end2end/fixtures/h2_sockpair+trace.c
 )
 
-target_include_directories(grpc_verify_jwt
+target_include_directories(h2_sockpair+trace_nosec_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_verify_jwt
-  grpc
+target_link_libraries(h2_sockpair+trace_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
   gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_verify_jwt EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(h2_sockpair_1byte_nosec_test
+  test/core/end2end/fixtures/h2_sockpair_1byte.c
+)
 
+target_include_directories(h2_sockpair_1byte_nosec_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
-add_executable(grpc_cpp_plugin
-  src/compiler/cpp_plugin.cc
+target_link_libraries(h2_sockpair_1byte_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
 )
 
-target_include_directories(grpc_cpp_plugin
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(h2_uds_nosec_test
+  test/core/end2end/fixtures/h2_uds.c
+)
+
+target_include_directories(h2_uds_nosec_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_cpp_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(h2_uds_nosec_test
+  end2end_nosec_tests
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(api_fuzzer_one_entry
+  test/core/end2end/fuzzers/api_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(api_fuzzer_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
+target_link_libraries(api_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
 
-add_executable(grpc_csharp_plugin
-  src/compiler/csharp_plugin.cc
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(client_fuzzer_one_entry
+  test/core/end2end/fuzzers/client_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
 )
 
-target_include_directories(grpc_csharp_plugin
+target_include_directories(client_fuzzer_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_csharp_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(client_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(hpack_parser_fuzzer_test_one_entry
+  test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
 
+target_include_directories(hpack_parser_fuzzer_test_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
-add_executable(grpc_node_plugin
-  src/compiler/node_plugin.cc
+target_link_libraries(hpack_parser_fuzzer_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
-target_include_directories(grpc_node_plugin
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(http_request_fuzzer_test_one_entry
+  test/core/http/request_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(http_request_fuzzer_test_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_node_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(http_request_fuzzer_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_node_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(http_response_fuzzer_test_one_entry
+  test/core/http/response_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
 
+target_include_directories(http_response_fuzzer_test_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
-add_executable(grpc_objective_c_plugin
-  src/compiler/objective_c_plugin.cc
+target_link_libraries(http_response_fuzzer_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
-target_include_directories(grpc_objective_c_plugin
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(json_fuzzer_test_one_entry
+  test/core/json/fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(json_fuzzer_test_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_objective_c_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(json_fuzzer_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(nanopb_fuzzer_response_test_one_entry
+  test/core/nanopb/fuzzer_response.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
 
+target_include_directories(nanopb_fuzzer_response_test_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
-add_executable(grpc_php_plugin
-  src/compiler/php_plugin.cc
+target_link_libraries(nanopb_fuzzer_response_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
-target_include_directories(grpc_php_plugin
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(nanopb_fuzzer_serverlist_test_one_entry
+  test/core/nanopb/fuzzer_serverlist.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(nanopb_fuzzer_serverlist_test_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_php_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_php_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(percent_decode_fuzzer_one_entry
+  test/core/slice/percent_decode_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(percent_decode_fuzzer_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
+target_link_libraries(percent_decode_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
 
-add_executable(grpc_python_plugin
-  src/compiler/python_plugin.cc
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(percent_encode_fuzzer_one_entry
+  test/core/slice/percent_encode_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
 )
 
-target_include_directories(grpc_python_plugin
+target_include_directories(percent_encode_fuzzer_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_python_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(percent_encode_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_python_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(server_fuzzer_one_entry
+  test/core/end2end/fuzzers/server_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
 
+target_include_directories(server_fuzzer_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
 
-add_executable(grpc_ruby_plugin
-  src/compiler/ruby_plugin.cc
+target_link_libraries(server_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
-target_include_directories(grpc_ruby_plugin
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(ssl_server_fuzzer_one_entry
+  test/core/security/ssl_server_fuzzer.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(ssl_server_fuzzer_one_entry
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
   PRIVATE ${BORINGSSL_ROOT_DIR}/include
   PRIVATE ${PROTOBUF_ROOT_DIR}/src
   PRIVATE ${ZLIB_ROOT_DIR}
   PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
 )
 
-target_link_libraries(grpc_ruby_plugin
-  ${_gRPC_PROTOBUF_PROTOC_LIBRARIES}
-  grpc_plugin_support
+target_link_libraries(ssl_server_fuzzer_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
 )
 
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 
-if (gRPC_INSTALL)
-  install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  )
-endif()
+add_executable(uri_fuzzer_test_one_entry
+  test/core/client_channel/uri_fuzzer_test.c
+  test/core/util/one_corpus_entry_fuzzer.c
+)
+
+target_include_directories(uri_fuzzer_test_one_entry
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+)
+
+target_link_libraries(uri_fuzzer_test_one_entry
+  grpc_test_util
+  grpc
+  gpr_test_util
+  gpr
+)
 
+endif (gRPC_BUILD_TESTS)
 
 
 
-- 
GitLab


From c7554240502d9dcf5a308def02b0c026adffdf50 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 19 Jan 2017 10:31:47 +0100
Subject: [PATCH 344/344] fix building protoc artifacts on windows

---
 tools/run_tests/artifacts/build_artifact_protoc.bat | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/run_tests/artifacts/build_artifact_protoc.bat b/tools/run_tests/artifacts/build_artifact_protoc.bat
index fd93318833..b2bf86da40 100644
--- a/tools/run_tests/artifacts/build_artifact_protoc.bat
+++ b/tools/run_tests/artifacts/build_artifact_protoc.bat
@@ -34,7 +34,7 @@ cd third_party/protobuf/cmake
 
 mkdir build & cd build
 mkdir solution & cd solution
-cmake -G "%generator%" -Dprotobuf_BUILD_TESTS=OFF ../../.. || goto :error
+cmake -G "%generator%" -Dprotobuf_BUILD_TESTS=OFF ../.. || goto :error
 endlocal
 
 call vsprojects/build_plugins.bat || goto :error
-- 
GitLab