Merge pull request #6908 from jtattermusch/csharp_send_completion_dedup

C#: dedup code for send finished handler
diff --git a/.travis.yml b/.travis.yml
index 004d44f..16c6390 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,23 @@
 language: objective-c
-osx_image: xcode7.2
+osx_image: xcode7.3
 env:
   global:
     - CONFIG=opt
     - TEST=objc
     - JOBS=1
 before_install:
+  - pod --version
+  - gem uninstall cocoapods -a
+  - gem install cocoapods -v '1.0.0'
+  - pod --version
   - brew install gflags
-  # Pod install does this too, but we don't want the output.
-  - pod repo update --silent
+  - pushd third_party/protobuf
+  - git checkout v3.0.0-beta-3
+  - popd
 install:
   - make grpc_objective_c_plugin
   - pushd src/objective-c/tests
-  # Needs to be verbose, or otherwise OpenSSL's prepare_command makes Travis
-  # time out:
-  - pod install --verbose
+  - pod install
   - popd
 before_script:
   - make interop_server
@@ -27,6 +30,6 @@
   - InteropTestsLocalCleartext
   # TODO(jcanizales): Investigate why they time out:
   # - InteropTestsRemote
-xcode_sdk: iphonesimulator9.2
+xcode_sdk: iphonesimulator9.3
 notifications:
   email: false
diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h
index aa86fc4..e5010c2 100644
--- a/include/grpc/impl/codegen/log.h
+++ b/include/grpc/impl/codegen/log.h
@@ -34,6 +34,7 @@
 #ifndef GRPC_IMPL_CODEGEN_LOG_H
 #define GRPC_IMPL_CODEGEN_LOG_H
 
+#include <inttypes.h>
 #include <stdarg.h>
 #include <stdlib.h> /* for abort() */
 
@@ -74,7 +75,7 @@
 /* Log a message. It's advised to use GPR_xxx above to generate the context
  * for each message */
 GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity,
-                    const char *format, ...);
+                    const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
 
 GPRAPI void gpr_log_message(const char *file, int line,
                             gpr_log_severity severity, const char *message);
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 7fff36c..9640ab6 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -434,6 +434,15 @@
 #endif
 #endif
 
+#ifndef GPRC_PRINT_FORMAT_CHECK
+#ifdef __GNUC__
+#define GPRC_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS) \
+  __attribute__((format(printf, FORMAT_STR, ARGS)))
+#else
+#define GPRC_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS)
+#endif
+#endif /* GPRC_PRINT_FORMAT_CHECK */
+
 #if GPR_FORBID_UNREACHABLE_CODE
 #define GPR_UNREACHABLE_CODE(STATEMENT)
 #else
diff --git a/include/grpc/support/string_util.h b/include/grpc/support/string_util.h
index f981bc0..952cbfc 100644
--- a/include/grpc/support/string_util.h
+++ b/include/grpc/support/string_util.h
@@ -54,7 +54,8 @@
 
    On error, returns -1 and sets *strp to NULL. If the format string is bad,
    the result is undefined. */
-GPRAPI int gpr_asprintf(char **strp, const char *format, ...);
+GPRAPI int gpr_asprintf(char **strp, const char *format, ...)
+    GPRC_PRINT_FORMAT_CHECK(2, 3);
 
 #ifdef __cplusplus
 }
diff --git a/package.xml b/package.xml
index 0a54f9c..b25e42c 100644
--- a/package.xml
+++ b/package.xml
@@ -1074,20 +1074,5 @@
 - Updated functions with TSRM macros for ZTS support #6607
    </notes>
   </release>
-  <release>
-   <version>
-    <release>0.15.0</release>
-    <api>0.15.0</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2016-05-19</date>
-   <license>BSD</license>
-   <notes>
-- TBD
-   </notes>
-  </release>
  </changelog>
 </package>
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 da2cdfe..40dd7c5 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -333,7 +333,7 @@
   p->started_picking = 1;
 
   if (grpc_lb_round_robin_trace) {
-    gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
+    gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%" PRIuPTR, p,
             p->num_subchannels);
   }
 
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 620ba4e..5efc95e 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -183,7 +183,8 @@
     gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
     gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
     gpr_timespec timeout = gpr_time_sub(next_try, now);
-    gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d.%09d seconds",
+    gpr_log(GPR_DEBUG,
+            "dns resolution failed: retrying in %" PRId64 ".%09d seconds",
             timeout.tv_sec, timeout.tv_nsec);
     GPR_ASSERT(!r->have_retry_timer);
     r->have_retry_timer = true;
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 0428bb1..c95dd20 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -111,13 +111,14 @@
     }
   }
   if (count == 0) {
-    gpr_log(GPR_ERROR, "No address added out of total %d resolved",
+    gpr_log(GPR_ERROR, "No address added out of total %" PRIuPTR " resolved",
             resolved->naddrs);
     goto error;
   }
   if (count != resolved->naddrs) {
-    gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
-            count, resolved->naddrs);
+    gpr_log(GPR_ERROR,
+            "Only %d addresses added out of total %" PRIuPTR " resolved", count,
+            resolved->naddrs);
   }
   grpc_resolved_addresses_destroy(resolved);
 
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 ebbefbc..e3437e5 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
@@ -229,13 +229,14 @@
     }
   }
   if (count == 0) {
-    gpr_log(GPR_ERROR, "No address added out of total %d resolved",
+    gpr_log(GPR_ERROR, "No address added out of total %" PRIuPTR " resolved",
             resolved->naddrs);
     goto error;
   }
   if (count != resolved->naddrs) {
-    gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
-            count, resolved->naddrs);
+    gpr_log(GPR_ERROR,
+            "Only %d addresses added out of total %" PRIuPTR " resolved", count,
+            resolved->naddrs);
     /* if it's an error, don't we want to goto error; here ? */
   }
   grpc_resolved_addresses_destroy(resolved);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 2375a45..6e8640f 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -964,7 +964,7 @@
     if (metadata_size > metadata_peer_limit) {
       gpr_log(GPR_DEBUG,
               "to-be-sent initial metadata size exceeds peer limit "
-              "(%lu vs. %lu)",
+              "(%" PRIuPTR " vs. %" PRIuPTR ")",
               metadata_size, metadata_peer_limit);
       cancel_from_api(exec_ctx, transport_global, stream_global,
                       GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
@@ -1019,7 +1019,7 @@
     if (metadata_size > metadata_peer_limit) {
       gpr_log(GPR_DEBUG,
               "to-be-sent trailing metadata size exceeds peer limit "
-              "(%lu vs. %lu)",
+              "(%" PRIuPTR " vs. %" PRIuPTR ")",
               metadata_size, metadata_peer_limit);
       cancel_from_api(exec_ctx, transport_global, stream_global,
                       GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
@@ -2019,10 +2019,13 @@
                                         int64_t val, uint32_t id,
                                         char **scope) {
   char *underscore_pos;
+  char *buf;
   char *result;
   if (context == NULL) {
     *scope = NULL;
-    gpr_asprintf(&result, "%s(%lld)", var, val);
+    gpr_asprintf(&buf, "%s(%" PRId64 ")", var, val);
+    result = gpr_leftpad(buf, ' ', 40);
+    gpr_free(buf);
     return result;
   }
   underscore_pos = strchr(context, '_');
@@ -2033,7 +2036,9 @@
     gpr_asprintf(scope, "%s[%d]", tmp, id);
     gpr_free(tmp);
   }
-  gpr_asprintf(&result, "%s.%s(%lld)", underscore_pos + 1, var, val);
+  gpr_asprintf(&buf, "%s.%s(%" PRId64 ")", underscore_pos + 1, var, val);
+  result = gpr_leftpad(buf, ' ', 40);
+  gpr_free(buf);
   return result;
 }
 
@@ -2054,6 +2059,8 @@
                                uint32_t stream_id, int64_t val1, int64_t val2) {
   char *scope1;
   char *scope2;
+  char *tmp_phase;
+  char *tmp_scope1;
   char *label1 =
       format_flowctl_context_var(context1, var1, val1, stream_id, &scope1);
   char *label2 =
@@ -2061,14 +2068,18 @@
   char *clisvr = is_client ? "client" : "server";
   char *prefix;
 
-  gpr_asprintf(&prefix, "FLOW % 8s: %s % 11s ", phase, clisvr, scope1);
+  tmp_phase = gpr_leftpad(phase, ' ', 8);
+  tmp_scope1 = gpr_leftpad(scope1, ' ', 11);
+  gpr_asprintf(&prefix, "FLOW %s: %s %s ", phase, clisvr, scope1);
+  gpr_free(tmp_phase);
+  gpr_free(tmp_scope1);
 
   switch (op) {
     case GRPC_CHTTP2_FLOWCTL_MOVE:
       GPR_ASSERT(samestr(scope1, scope2));
       if (val2 != 0) {
         gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-                "%sMOVE   % 40s <- % 40s giving %d", prefix, label1, label2,
+                "%sMOVE   %s <- %s giving %" PRId64, prefix, label1, label2,
                 val1 + val2);
       }
       break;
@@ -2076,7 +2087,7 @@
       GPR_ASSERT(val2 >= 0);
       if (val2 != 0) {
         gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-                "%sCREDIT % 40s by % 40s giving %d", prefix, label1, label2,
+                "%sCREDIT %s by %s giving %" PRId64, prefix, label1, label2,
                 val1 + val2);
       }
       break;
@@ -2084,7 +2095,7 @@
       GPR_ASSERT(val2 >= 0);
       if (val2 != 0) {
         gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-                "%sDEBIT  % 40s by % 40s giving %d", prefix, label1, label2,
+                "%sDEBIT  %s by %s giving %" PRId64, prefix, label1, label2,
                 val1 - val2);
       }
       break;
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 4bd374b..3c74258 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -534,14 +534,14 @@
     grpc_chttp2_stream_parsing *stream_parsing) {
   uint32_t incoming_frame_size = transport_parsing->incoming_frame_size;
   if (incoming_frame_size > transport_parsing->incoming_window) {
-    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d",
+    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %" PRId64,
             transport_parsing->incoming_frame_size,
             transport_parsing->incoming_window);
     return GRPC_CHTTP2_CONNECTION_ERROR;
   }
 
   if (incoming_frame_size > stream_parsing->incoming_window) {
-    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d",
+    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %" PRId64,
             transport_parsing->incoming_frame_size,
             stream_parsing->incoming_window);
     return GRPC_CHTTP2_CONNECTION_ERROR;
@@ -649,7 +649,8 @@
     if (new_size > metadata_size_limit) {
       if (!stream_parsing->exceeded_metadata_size) {
         gpr_log(GPR_DEBUG,
-                "received initial metadata size exceeds limit (%lu vs. %lu)",
+                "received initial metadata size exceeds limit (%" PRIuPTR
+                " vs. %" PRIuPTR ")",
                 new_size, metadata_size_limit);
         stream_parsing->seen_error = true;
         stream_parsing->exceeded_metadata_size = true;
@@ -695,7 +696,8 @@
   if (new_size > metadata_size_limit) {
     if (!stream_parsing->exceeded_metadata_size) {
       gpr_log(GPR_DEBUG,
-              "received trailing metadata size exceeds limit (%lu vs. %lu)",
+              "received trailing metadata size exceeds limit (%" PRIuPTR
+              " vs. %" PRIuPTR ")",
               new_size, metadata_size_limit);
       stream_parsing->seen_error = true;
       stream_parsing->exceeded_metadata_size = true;
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 4fe9a7f..32f4f8d 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -177,8 +177,8 @@
       const float savings_ratio = 1.0f - (float)after_size / (float)before_size;
       GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
                                                  &algo_name));
-      gpr_log(GPR_DEBUG,
-              "Compressed[%s] %d bytes vs. %d bytes (%.2f%% savings)",
+      gpr_log(GPR_DEBUG, "Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR
+                         " bytes (%.2f%% savings)",
               algo_name, before_size, after_size, 100 * savings_ratio);
     }
     gpr_slice_buffer_swap(&calld->slices, &tmp);
@@ -188,10 +188,10 @@
       char *algo_name;
       GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
                                                  &algo_name));
-      gpr_log(
-          GPR_DEBUG,
-          "Algorithm '%s' enabled but decided not to compress. Input size: %d",
-          algo_name, calld->slices.length);
+      gpr_log(GPR_DEBUG,
+              "Algorithm '%s' enabled but decided not to compress. Input size: "
+              "%" PRIuPTR,
+              algo_name, calld->slices.length);
     }
   }
 
diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c
index 60cef8b..89292a1 100644
--- a/src/core/lib/iomgr/iomgr.c
+++ b/src/core/lib/iomgr/iomgr.c
@@ -96,7 +96,8 @@
             gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time),
             gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
       if (g_root_object.next != &g_root_object) {
-        gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed",
+        gpr_log(GPR_DEBUG,
+                "Waiting for %" PRIuPTR " iomgr objects to be destroyed",
                 count_objects());
       }
       last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
@@ -114,9 +115,9 @@
       if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) {
         if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) {
           if (g_root_object.next != &g_root_object) {
-            gpr_log(GPR_DEBUG,
-                    "Failed to free %d iomgr objects before shutdown deadline: "
-                    "memory leaks are likely",
+            gpr_log(GPR_DEBUG, "Failed to free %" PRIuPTR
+                               " iomgr objects before shutdown deadline: "
+                               "memory leaks are likely",
                     count_objects());
             dump_objects("LEAKED");
             if (grpc_iomgr_abort_on_leaks()) {
diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c
index ca04c02..508fae4 100644
--- a/src/core/lib/support/log_linux.c
+++ b/src/core/lib/support/log_linux.c
@@ -95,9 +95,9 @@
     strcpy(time_buffer, "error:strftime");
   }
 
-  gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]",
+  gpr_asprintf(&prefix, "%s%s.%09" PRId32 " %7ld %s:%d]",
                gpr_log_severity_string(args->severity), time_buffer,
-               (int)(now.tv_nsec), gettid(), display_file, args->line);
+               now.tv_nsec, gettid(), display_file, args->line);
 
   fprintf(stderr, "%-60s %s\n", prefix, args->message);
   gpr_free(prefix);
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index a2ab6c5..30c1e67 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -194,6 +194,16 @@
   return i;
 }
 
+char *gpr_leftpad(const char *str, char flag, size_t length) {
+  const size_t str_length = strlen(str);
+  const size_t out_length = str_length > length ? str_length : length;
+  char *out = gpr_malloc(out_length + 1);
+  memset(out, flag, out_length - str_length);
+  memcpy(out + out_length - str_length, str, str_length);
+  out[out_length] = 0;
+  return out;
+}
+
 char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) {
   return gpr_strjoin_sep(strs, nstrs, "", final_length);
 }
diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h
index ea58610..2b6bb3e 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/support/string.h
@@ -83,6 +83,10 @@
 /* Reverse a run of bytes */
 void gpr_reverse_bytes(char *str, int len);
 
+/* Pad a string with flag characters. The given length specifies the minimum
+   field width. The input string is never truncated. */
+char *gpr_leftpad(const char *str, char flag, size_t length);
+
 /* Join a set of strings, returning the resulting string.
    Total combined length (excluding null terminator) is returned in total_length
    if it is non-null. */
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index a9b1e25..c613f32 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -1182,7 +1182,7 @@
     if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
       gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.",
                    algo);
-      gpr_log(GPR_ERROR, error_msg);
+      gpr_log(GPR_ERROR, "%s", error_msg);
       close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
     } else if (grpc_compression_options_is_algorithm_enabled(
                    &compression_options, algo) == 0) {
@@ -1191,7 +1191,7 @@
       grpc_compression_algorithm_name(algo, &algo_name);
       gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
                    algo_name);
-      gpr_log(GPR_ERROR, error_msg);
+      gpr_log(GPR_ERROR, "%s", error_msg);
       close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
     } else {
       call->incoming_compression_algorithm = algo;
diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c
index a6d1d51..31c074f 100644
--- a/src/core/lib/surface/call_log_batch.c
+++ b/src/core/lib/surface/call_log_batch.c
@@ -112,7 +112,7 @@
   size_t i;
   for (i = 0; i < nops; i++) {
     tmp = grpc_op_string(&ops[i]);
-    gpr_log(file, line, severity, "ops[%d]: %s", i, tmp);
+    gpr_log(file, line, severity, "ops[%" PRIuPTR "]: %s", i, tmp);
     gpr_free(tmp);
   }
 }
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index 79de54b..0677f29 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -235,7 +235,7 @@
     gc_mdtab(shard);
     /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
     if (shard->count != 0) {
-      gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked",
+      gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked",
               shard->count);
       if (grpc_iomgr_abort_on_leaks()) {
         abort();
@@ -248,7 +248,7 @@
     gpr_mu_destroy(&shard->mu);
     /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
     if (shard->count != 0) {
-      gpr_log(GPR_DEBUG, "WARNING: %d metadata strings were leaked",
+      gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
               shard->count);
       for (size_t j = 0; j < shard->capacity; j++) {
         for (internal_string *s = shard->strs[j]; s; s = s->bucket_next) {
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
index 81897f8..98e27a1 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
@@ -224,7 +224,7 @@
 
             fakeCall.UnaryResponseClientHandler(true,
                 new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()),
-                null,
+                CreateResponsePayload(),
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.OutOfRange);
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 508641d..a7a88a3 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -1,32 +1,36 @@
 source 'https://github.com/CocoaPods/Specs.git'
 platform :ios, '8.0'
 
-pod 'Protobuf', :path => "../../../third_party/protobuf"
-pod 'BoringSSL', :podspec => ".."
-pod 'CronetFramework', :podspec => ".."
-pod 'gRPC', :path => "../../.."
-pod 'RemoteTest', :path => "RemoteTestClient"
+install! 'cocoapods', :deterministic_uuids => false
 
-link_with 'AllTests',
-          'RxLibraryUnitTests',
-          'InteropTests',
-          'InteropTestsLocalSSL',
-          'InteropTestsLocalCleartext'
+def shared_pods
+	pod 'Protobuf', :path => "../../../third_party/protobuf"
+	pod 'BoringSSL', :podspec => ".."
+	pod 'CronetFramework', :podspec => ".."
+	pod 'gRPC', :path => "../../.."
+	pod 'RemoteTest', :path => "RemoteTestClient"
+end
 
 target 'Tests' do
+	shared_pods
 end
 
 target 'AllTests' do
+	shared_pods
 end
 
 target 'RxLibraryUnitTests' do
+	shared_pods
 end
 
 target 'InteropTestsRemote' do
+	shared_pods
 end
 
 target 'InteropTestsLocalSSL' do
+	shared_pods
 end
 
 target 'InteropTestsLocalCleartext' do
+	shared_pods
 end
diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
index 6ecef05..e1fd991 100644
--- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
+++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
@@ -2,6 +2,10 @@
   s.name     = "RemoteTest"
   s.version  = "0.0.1"
   s.license  = "New BSD"
+  s.authors  = { 'gRPC contributors' => 'grpc-io@googlegroups.com' }
+  s.homepage = "http://www.grpc.io/"
+  s.summary = "RemoteTest example"
+  s.source = { :git => 'https://github.com/grpc/grpc.git' }
 
   s.ios.deployment_target = '7.1'
   s.osx.deployment_target = '10.9'
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index b042961..89e0ea6 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -7,33 +7,34 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		036D953EE34B1FD523647ACD /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
-		08A8BB02D19A53D902B214B8 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
-		50267643BA114A2A724D4FDF /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+		0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; };
+		16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; };
+		20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; };
+		333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; };
+		3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; };
 		6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
 		63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
 		635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; };
 		635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
 		63715F561B780C020029CB0B /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; };
-		6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
-		6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
-		6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; settings = {ASSET_TAGS = (); }; };
-		6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; settings = {ASSET_TAGS = (); }; };
-		6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; settings = {ASSET_TAGS = (); }; };
-		63DC84181BE15179000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
-		63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; settings = {ASSET_TAGS = (); }; };
-		63DC84281BE15267000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
-		63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; settings = {ASSET_TAGS = (); }; };
-		63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; settings = {ASSET_TAGS = (); }; };
-		63DC84391BE15294000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
-		63DC84481BE152B5000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; settings = {ASSET_TAGS = (); }; };
-		63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; settings = {ASSET_TAGS = (); }; };
-		63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; settings = {ASSET_TAGS = (); }; };
-		63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; settings = {ASSET_TAGS = (); }; };
+		6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+		6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+		6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; };
+		6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; };
+		6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
+		63DC84181BE15179000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; };
+		63DC84281BE15267000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; };
+		63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+		63DC84391BE15294000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		63DC84481BE152B5000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; };
+		63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; };
+		63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
 		63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; };
 		63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
-		7D8A186224D39101F90230F6 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
-		DCFAE001609CCBFE69DFA6A1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+		F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -87,8 +88,15 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
+		07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
 		0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
+		20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = "<group>"; };
+		51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = "<group>"; };
+		553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = "<group>"; };
+		5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = "<group>"; };
 		6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = "<group>"; };
 		63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = "<group>"; };
@@ -105,6 +113,17 @@
 		63E240CC1B6C4D3A005F3B0E /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = "<group>"; };
 		63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = "<group>"; };
 		63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = "<group>"; };
+		7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = "<group>"; };
+		A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = "<group>"; };
+		CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.debug.xcconfig"; sourceTree = "<group>"; };
+		E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = "<group>"; };
+		E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = "<group>"; };
+		E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
+		FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -114,7 +133,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */,
-				7D8A186224D39101F90230F6 /* libPods.a in Frameworks */,
+				F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -122,6 +141,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -130,7 +150,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				63DC84181BE15179000708E8 /* libTests.a in Frameworks */,
-				036D953EE34B1FD523647ACD /* libPods.a in Frameworks */,
+				20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -139,7 +159,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				63DC84281BE15267000708E8 /* libTests.a in Frameworks */,
-				DCFAE001609CCBFE69DFA6A1 /* libPods.a in Frameworks */,
+				0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -148,7 +168,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				63DC84391BE15294000708E8 /* libTests.a in Frameworks */,
-				08A8BB02D19A53D902B214B8 /* libPods.a in Frameworks */,
+				16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -157,7 +177,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				63DC84481BE152B5000708E8 /* libTests.a in Frameworks */,
-				50267643BA114A2A724D4FDF /* libPods.a in Frameworks */,
+				333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -168,6 +188,12 @@
 			isa = PBXGroup;
 			children = (
 				35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */,
+				CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */,
+				FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */,
+				DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */,
+				DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */,
+				A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */,
+				20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -177,6 +203,18 @@
 			children = (
 				FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */,
 				0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */,
+				B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */,
+				5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */,
+				E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */,
+				51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */,
+				553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */,
+				7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */,
+				DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */,
+				E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */,
+				07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */,
+				3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */,
+				060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */,
+				E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */,
 			);
 			name = Pods;
 			sourceTree = "<group>";
@@ -236,12 +274,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */;
 			buildPhases = (
-				914ADDD7106BA9BB8A7E569F /* Check Pods Manifest.lock */,
+				914ADDD7106BA9BB8A7E569F /* 📦 Check Pods Manifest.lock */,
 				63423F401B150A5F006CF63C /* Sources */,
 				63423F411B150A5F006CF63C /* Frameworks */,
 				63423F421B150A5F006CF63C /* Resources */,
-				A441F71824DCB9D0CA297748 /* Copy Pods Resources */,
-				5F14F59509E10C2852014F9E /* Embed Pods Frameworks */,
+				A441F71824DCB9D0CA297748 /* 📦 Copy Pods Resources */,
+				5F14F59509E10C2852014F9E /* 📦 Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -257,9 +295,11 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */;
 			buildPhases = (
+				796680C7599CB4ED736DD62A /* 📦 Check Pods Manifest.lock */,
 				635697C31B14FC11007A7283 /* Sources */,
 				635697C41B14FC11007A7283 /* Frameworks */,
 				635697C51B14FC11007A7283 /* CopyFiles */,
+				AEEBFC914CBAEE347382E8C4 /* 📦 Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -274,12 +314,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */;
 			buildPhases = (
-				B2986CEEE8CDD4901C97598B /* Check Pods Manifest.lock */,
+				B2986CEEE8CDD4901C97598B /* 📦 Check Pods Manifest.lock */,
 				63DC840F1BE15179000708E8 /* Sources */,
 				63DC84101BE15179000708E8 /* Frameworks */,
 				63DC84111BE15179000708E8 /* Resources */,
-				4F5690DC0E6AD6663FE78B8B /* Embed Pods Frameworks */,
-				C977426A8727267BBAC7D48E /* Copy Pods Resources */,
+				4F5690DC0E6AD6663FE78B8B /* 📦 Embed Pods Frameworks */,
+				C977426A8727267BBAC7D48E /* 📦 Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -295,12 +335,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */;
 			buildPhases = (
-				4C406327D3907A5E5FBA8AC9 /* Check Pods Manifest.lock */,
+				4C406327D3907A5E5FBA8AC9 /* 📦 Check Pods Manifest.lock */,
 				63DC841F1BE15267000708E8 /* Sources */,
 				63DC84201BE15267000708E8 /* Frameworks */,
 				63DC84211BE15267000708E8 /* Resources */,
-				900B6EDD4D16BE7D765C3885 /* Embed Pods Frameworks */,
-				C2E09DC4BD239F71160F0CC1 /* Copy Pods Resources */,
+				900B6EDD4D16BE7D765C3885 /* 📦 Embed Pods Frameworks */,
+				C2E09DC4BD239F71160F0CC1 /* 📦 Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -316,12 +356,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */;
 			buildPhases = (
-				5C20DCCB71C3991E6FE78C22 /* Check Pods Manifest.lock */,
+				5C20DCCB71C3991E6FE78C22 /* 📦 Check Pods Manifest.lock */,
 				63DC84301BE15294000708E8 /* Sources */,
 				63DC84311BE15294000708E8 /* Frameworks */,
 				63DC84321BE15294000708E8 /* Resources */,
-				C591129ACE9F6CC5EE03FCDE /* Embed Pods Frameworks */,
-				693DD0B453431D64EA24FD66 /* Copy Pods Resources */,
+				C591129ACE9F6CC5EE03FCDE /* 📦 Embed Pods Frameworks */,
+				693DD0B453431D64EA24FD66 /* 📦 Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -337,12 +377,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */;
 			buildPhases = (
-				7418AC7B3844B29E48D24FC7 /* Check Pods Manifest.lock */,
+				7418AC7B3844B29E48D24FC7 /* 📦 Check Pods Manifest.lock */,
 				63DC843F1BE152B5000708E8 /* Sources */,
 				63DC84401BE152B5000708E8 /* Frameworks */,
 				63DC84411BE152B5000708E8 /* Resources */,
-				A8E3AC66DF770B774114A30E /* Embed Pods Frameworks */,
-				8AD3130D3C58A0FB32FF2A36 /* Copy Pods Resources */,
+				A8E3AC66DF770B774114A30E /* 📦 Embed Pods Frameworks */,
+				8AD3130D3C58A0FB32FF2A36 /* 📦 Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -446,14 +486,14 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		4C406327D3907A5E5FBA8AC9 /* Check Pods Manifest.lock */ = {
+		4C406327D3907A5E5FBA8AC9 /* 📦 Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Check Pods Manifest.lock";
+			name = "📦 Check Pods Manifest.lock";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -461,29 +501,29 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		4F5690DC0E6AD6663FE78B8B /* Embed Pods Frameworks */ = {
+		4F5690DC0E6AD6663FE78B8B /* 📦 Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Embed Pods Frameworks";
+			name = "📦 Embed Pods Frameworks";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		5C20DCCB71C3991E6FE78C22 /* Check Pods Manifest.lock */ = {
+		5C20DCCB71C3991E6FE78C22 /* 📦 Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Check Pods Manifest.lock";
+			name = "📦 Check Pods Manifest.lock";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -491,44 +531,44 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		5F14F59509E10C2852014F9E /* Embed Pods Frameworks */ = {
+		5F14F59509E10C2852014F9E /* 📦 Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Embed Pods Frameworks";
+			name = "📦 Embed Pods Frameworks";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		693DD0B453431D64EA24FD66 /* Copy Pods Resources */ = {
+		693DD0B453431D64EA24FD66 /* 📦 Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Copy Pods Resources";
+			name = "📦 Copy Pods Resources";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		7418AC7B3844B29E48D24FC7 /* Check Pods Manifest.lock */ = {
+		7418AC7B3844B29E48D24FC7 /* 📦 Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Check Pods Manifest.lock";
+			name = "📦 Check Pods Manifest.lock";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -536,44 +576,14 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		8AD3130D3C58A0FB32FF2A36 /* Copy Pods Resources */ = {
+		796680C7599CB4ED736DD62A /* 📦 Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Copy Pods Resources";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
-			showEnvVarsInLog = 0;
-		};
-		900B6EDD4D16BE7D765C3885 /* Embed Pods Frameworks */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Embed Pods Frameworks";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
-			showEnvVarsInLog = 0;
-		};
-		914ADDD7106BA9BB8A7E569F /* Check Pods Manifest.lock */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Check Pods Manifest.lock";
+			name = "📦 Check Pods Manifest.lock";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -581,44 +591,44 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		A441F71824DCB9D0CA297748 /* Copy Pods Resources */ = {
+		8AD3130D3C58A0FB32FF2A36 /* 📦 Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Copy Pods Resources";
+			name = "📦 Copy Pods Resources";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		A8E3AC66DF770B774114A30E /* Embed Pods Frameworks */ = {
+		900B6EDD4D16BE7D765C3885 /* 📦 Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Embed Pods Frameworks";
+			name = "📦 Embed Pods Frameworks";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		B2986CEEE8CDD4901C97598B /* Check Pods Manifest.lock */ = {
+		914ADDD7106BA9BB8A7E569F /* 📦 Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Check Pods Manifest.lock";
+			name = "📦 Check Pods Manifest.lock";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -626,49 +636,109 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		C2E09DC4BD239F71160F0CC1 /* Copy Pods Resources */ = {
+		A441F71824DCB9D0CA297748 /* 📦 Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Copy Pods Resources";
+			name = "📦 Copy Pods Resources";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		C591129ACE9F6CC5EE03FCDE /* Embed Pods Frameworks */ = {
+		A8E3AC66DF770B774114A30E /* 📦 Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Embed Pods Frameworks";
+			name = "📦 Embed Pods Frameworks";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		C977426A8727267BBAC7D48E /* Copy Pods Resources */ = {
+		AEEBFC914CBAEE347382E8C4 /* 📦 Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
 			);
-			name = "Copy Pods Resources";
+			name = "📦 Copy Pods Resources";
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		B2986CEEE8CDD4901C97598B /* 📦 Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "📦 Check Pods Manifest.lock";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
+			showEnvVarsInLog = 0;
+		};
+		C2E09DC4BD239F71160F0CC1 /* 📦 Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "📦 Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		C591129ACE9F6CC5EE03FCDE /* 📦 Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "📦 Embed Pods Frameworks";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		C977426A8727267BBAC7D48E /* 📦 Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "📦 Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
 /* End PBXShellScriptBuildPhase section */
@@ -764,7 +834,7 @@
 /* Begin XCBuildConfiguration section */
 		63423F4E1B150A5F006CF63C /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			baseConfigurationReference = B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */;
 			buildSettings = {
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SDKROOT)/Developer/Library/Frameworks",
@@ -782,7 +852,7 @@
 		};
 		63423F4F1B150A5F006CF63C /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			baseConfigurationReference = 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */;
 			buildSettings = {
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SDKROOT)/Developer/Library/Frameworks",
@@ -874,6 +944,7 @@
 		};
 		635697DC1B14FC11007A7283 /* Debug */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */;
 			buildSettings = {
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -882,6 +953,7 @@
 		};
 		635697DD1B14FC11007A7283 /* Release */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */;
 			buildSettings = {
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -890,7 +962,7 @@
 		};
 		63DC841C1BE15179000708E8 /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			baseConfigurationReference = 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */;
 			buildSettings = {
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_TESTABILITY = YES;
@@ -904,7 +976,7 @@
 		};
 		63DC841D1BE15179000708E8 /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			baseConfigurationReference = 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */;
 			buildSettings = {
 				INFOPLIST_FILE = Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -916,7 +988,7 @@
 		};
 		63DC842C1BE15267000708E8 /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			baseConfigurationReference = DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */;
 			buildSettings = {
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_TESTABILITY = YES;
@@ -930,7 +1002,7 @@
 		};
 		63DC842D1BE15267000708E8 /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			baseConfigurationReference = E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */;
 			buildSettings = {
 				INFOPLIST_FILE = Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -942,7 +1014,7 @@
 		};
 		63DC843D1BE15294000708E8 /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			baseConfigurationReference = 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */;
 			buildSettings = {
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_TESTABILITY = YES;
@@ -956,7 +1028,7 @@
 		};
 		63DC843E1BE15294000708E8 /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			baseConfigurationReference = 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */;
 			buildSettings = {
 				INFOPLIST_FILE = Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -968,7 +1040,7 @@
 		};
 		63DC844C1BE152B5000708E8 /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			baseConfigurationReference = E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */;
 			buildSettings = {
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_TESTABILITY = YES;
@@ -982,7 +1054,7 @@
 		};
 		63DC844D1BE152B5000708E8 /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			baseConfigurationReference = 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */;
 			buildSettings = {
 				INFOPLIST_FILE = Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh
index e7ad31e..8547bfd 100755
--- a/src/objective-c/tests/build_tests.sh
+++ b/src/objective-c/tests/build_tests.sh
@@ -33,6 +33,9 @@
 
 set -e
 
+# CocoaPods requires the terminal to be using UTF-8 encoding.
+export LANG=en_US.UTF-8
+
 cd $(dirname $0)
 
 hash pod 2>/dev/null || { echo >&2 "Cocoapods needs to be installed."; exit 1; }
diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php
index 712af91..c86d298 100644
--- a/src/php/lib/Grpc/AbstractCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -39,6 +39,7 @@
     protected $call;
     protected $deserialize;
     protected $metadata;
+    protected $trailing_metadata;
 
     /**
      * Create a new Call wrapper object.
@@ -66,6 +67,7 @@
         $this->call = new Call($channel, $method, $deadline);
         $this->deserialize = $deserialize;
         $this->metadata = null;
+        $this->trailing_metadata = null;
         if (isset($options['call_credentials_callback']) &&
             is_callable($call_credentials_callback =
                         $options['call_credentials_callback'])) {
@@ -84,6 +86,14 @@
     }
 
     /**
+     * @return The trailing metadata sent by the server.
+     */
+    public function getTrailingMetadata()
+    {
+        return $this->trailing_metadata;
+    }
+
+    /**
      * @return string The URI of the endpoint.
      */
     public function getPeer()
diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php
index bf813c1..95e51c5 100644
--- a/src/php/lib/Grpc/BidiStreamingCall.php
+++ b/src/php/lib/Grpc/BidiStreamingCall.php
@@ -112,6 +112,7 @@
             OP_RECV_STATUS_ON_CLIENT => true,
         ]);
 
+        $this->trailing_metadata = $status_event->status->metadata;
         return $status_event->status;
     }
 }
diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php
index 500cfe0..315a406 100644
--- a/src/php/lib/Grpc/ClientStreamingCall.php
+++ b/src/php/lib/Grpc/ClientStreamingCall.php
@@ -86,6 +86,8 @@
         ]);
         $this->metadata = $event->metadata;
 
-        return [$this->deserializeResponse($event->message), $event->status];
+        $status = $event->status;
+        $this->trailing_metadata = $status->metadata;
+        return [$this->deserializeResponse($event->message), $status];
     }
 }
diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php
index da48523..53599fe 100644
--- a/src/php/lib/Grpc/ServerStreamingCall.php
+++ b/src/php/lib/Grpc/ServerStreamingCall.php
@@ -91,6 +91,7 @@
             OP_RECV_STATUS_ON_CLIENT => true,
         ]);
 
+        $this->trailing_metadata = $status_event->status->metadata;
         return $status_event->status;
     }
 }
diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php
index b57903d..b114b77 100644
--- a/src/php/lib/Grpc/UnaryCall.php
+++ b/src/php/lib/Grpc/UnaryCall.php
@@ -75,6 +75,8 @@
             OP_RECV_STATUS_ON_CLIENT => true,
         ]);
 
-        return [$this->deserializeResponse($event->message), $event->status];
+        $status = $event->status;
+        $this->trailing_metadata = $status->metadata;
+        return [$this->deserializeResponse($event->message), $status];
     }
 }
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index 16bb5cd..62865f8 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -482,7 +482,7 @@
 typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader *reader);
 extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 #define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
-typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...);
+typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
 extern gpr_log_type gpr_log_import;
 #define gpr_log gpr_log_import
 typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
@@ -821,7 +821,7 @@
 typedef char *(*gpr_strdup_type)(const char *src);
 extern gpr_strdup_type gpr_strdup_import;
 #define gpr_strdup gpr_strdup_import
-typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...);
+typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(2, 3);
 extern gpr_asprintf_type gpr_asprintf_import;
 #define gpr_asprintf gpr_asprintf_import
 typedef const char *(*gpr_subprocess_binary_extension_type)();
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 20e356f..bf20f15 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -344,10 +344,9 @@
             if state.client is _CLOSED:
               details = '"{}" requires exactly one request message.'.format(
                   rpc_event.request_call_details.method)
-              # TODO(5992#issuecomment-220761992): really, what status code?
               _abort(
                   state, rpc_event.operation_call,
-                  cygrpc.StatusCode.unavailable, details)
+                  cygrpc.StatusCode.unimplemented, details)
               return None
             elif state.client is _CANCELLED:
               return None
diff --git a/src/python/grpcio/tests/unit/_rpc_test.py b/src/python/grpcio/tests/unit/_rpc_test.py
index 8773e96..8407593 100644
--- a/src/python/grpcio/tests/unit/_rpc_test.py
+++ b/src/python/grpcio/tests/unit/_rpc_test.py
@@ -29,8 +29,6 @@
 
 """Test of gRPC Python's application-layer API."""
 
-from __future__ import division
-
 import itertools
 import threading
 import unittest
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 9c86a36..e9845cd 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -482,7 +482,7 @@
 typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader *reader);
 extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 #define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
-typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...);
+typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
 extern gpr_log_type gpr_log_import;
 #define gpr_log gpr_log_import
 typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
@@ -821,7 +821,7 @@
 typedef char *(*gpr_strdup_type)(const char *src);
 extern gpr_strdup_type gpr_strdup_import;
 #define gpr_strdup gpr_strdup_import
-typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...);
+typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(2, 3);
 extern gpr_asprintf_type gpr_asprintf_import;
 #define gpr_asprintf gpr_asprintf_import
 typedef const char *(*gpr_subprocess_binary_extension_type)();
diff --git a/templates/package.xml.template b/templates/package.xml.template
index 85f9a7d..a620a2d 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -200,20 +200,5 @@
   - Updated functions with TSRM macros for ZTS support #6607
      </notes>
     </release>
-    <release>
-     <version>
-      <release>${settings.php_version.php()}</release>
-      <api>${settings.php_version.php()}</api>
-     </version>
-     <stability>
-      <release>beta</release>
-      <api>beta</api>
-     </stability>
-     <date>2016-05-19</date>
-     <license>BSD</license>
-     <notes>
-  - TBD
-     </notes>
-    </release>
    </changelog>
   </package>
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 1534360..3160312 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -135,7 +135,7 @@
 }
 
 static void kill_server(const servers_fixture *f, size_t i) {
-  gpr_log(GPR_INFO, "KILLING SERVER %d", i);
+  gpr_log(GPR_INFO, "KILLING SERVER %" PRIuPTR, i);
   GPR_ASSERT(f->servers[i] != NULL);
   grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
   GPR_ASSERT(
@@ -157,7 +157,7 @@
 static void revive_server(const servers_fixture *f, request_data *rdata,
                           size_t i) {
   int got_port;
-  gpr_log(GPR_INFO, "RAISE AGAIN SERVER %d", i);
+  gpr_log(GPR_INFO, "RAISE AGAIN SERVER %" PRIuPTR, i);
   GPR_ASSERT(f->servers[i] == NULL);
 
   gpr_log(GPR_DEBUG, "revive: %s", f->servers_hostports[i]);
@@ -311,7 +311,7 @@
             .type != GRPC_QUEUE_TIMEOUT) {
       GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
       read_tag = ((int)(intptr_t)ev.tag);
-      gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d",
+      gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%" PRIuPTR,
               ev.success, ev.type, read_tag, iter_num);
       if (ev.success && read_tag >= 1000) {
         GPR_ASSERT(s_idx == -1); /* only one server must reply */
@@ -643,7 +643,8 @@
                                       const size_t num_iters) {
   size_t i;
   for (i = 0; i < num_iters; i++) {
-    gpr_log(GPR_ERROR, "FAILURE: Iter (expected, actual): %d (%d, %d)", i,
+    gpr_log(GPR_ERROR,
+            "FAILURE: Iter (expected, actual): %" PRIuPTR " (%d, %d)", i,
             expected_connection_sequence[i % expected_seq_length],
             actual_connection_sequence[i]);
   }
@@ -726,8 +727,8 @@
     const int actual = actual_connection_sequence[i];
     const int expected = -1;
     if (actual != expected) {
-      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
-              actual, i);
+      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %" PRIuPTR,
+              expected, actual, i);
       abort();
     }
   }
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index 438b949..63371a6 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -69,7 +69,7 @@
   GPR_ASSERT(success);
   gpr_slice_buffer_move_into(&state.temp_incoming_buffer,
                              &state.incoming_buffer);
-  gpr_log(GPR_DEBUG, "got %d bytes, magic is %d bytes",
+  gpr_log(GPR_DEBUG, "got %" PRIuPTR " bytes, magic is %" PRIuPTR " bytes",
           state.incoming_buffer.length, strlen(magic_connect_string));
   if (state.incoming_buffer.length > strlen(magic_connect_string)) {
     gpr_atm_rel_store(&state.done_atm, 1);
@@ -173,8 +173,8 @@
     bool done = gpr_atm_acq_load(&state.done_atm) != 0;
     gpr_timespec time_left =
         gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
-    gpr_log(GPR_DEBUG, "done=%d, time_left=%d.%09d", done, time_left.tv_sec,
-            time_left.tv_nsec);
+    gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09" PRId32, done,
+            time_left.tv_sec, time_left.tv_nsec);
     if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) {
       break;
     }
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 1a93903..47ecf72 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -66,13 +66,14 @@
   char *algorithm_name;
 
   GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0);
-  gpr_log(GPR_INFO,
-          "assert_passthrough: value_length=%d value_hash=0x%08x "
-          "algorithm='%s' uncompressed_split='%s' compressed_split='%s'",
-          GPR_SLICE_LENGTH(value), gpr_murmur_hash3(GPR_SLICE_START_PTR(value),
-                                                    GPR_SLICE_LENGTH(value), 0),
-          algorithm_name, grpc_slice_split_mode_name(uncompressed_split_mode),
-          grpc_slice_split_mode_name(compressed_split_mode));
+  gpr_log(
+      GPR_INFO, "assert_passthrough: value_length=%" PRIuPTR
+                " value_hash=0x%08x "
+                "algorithm='%s' uncompressed_split='%s' compressed_split='%s'",
+      GPR_SLICE_LENGTH(value),
+      gpr_murmur_hash3(GPR_SLICE_START_PTR(value), GPR_SLICE_LENGTH(value), 0),
+      algorithm_name, grpc_slice_split_mode_name(uncompressed_split_mode),
+      grpc_slice_split_mode_name(compressed_split_mode));
 
   gpr_slice_buffer_init(&input);
   gpr_slice_buffer_init(&compressed_raw);
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index 83629a9..673c705 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -112,7 +112,7 @@
   char *details = NULL;
   size_t details_capacity = 0;
 
-  gpr_log(GPR_DEBUG, "test with %d ops", num_ops);
+  gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
 
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                "/foo", "foo.test.google.fr:1234", deadline,
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index fd56c8b..dff7992 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -112,7 +112,7 @@
   char *details = NULL;
   size_t details_capacity = 0;
 
-  gpr_log(GPR_DEBUG, "test with %d ops", num_ops);
+  gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
 
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                "/foo", "foo.test.google.fr:1234", deadline,
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 52082c3..6d15ecf 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -188,13 +188,15 @@
   grpc_endpoint_test_fixture f =
       begin_test(config, "read_and_write_test", slice_size);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  gpr_log(GPR_DEBUG, "num_bytes=%d write_size=%d slice_size=%d shutdown=%d",
+  gpr_log(GPR_DEBUG, "num_bytes=%" PRIuPTR " write_size=%" PRIuPTR
+                     " slice_size=%" PRIuPTR " shutdown=%d",
           num_bytes, write_size, slice_size, shutdown);
 
   if (shutdown) {
     gpr_log(GPR_INFO, "Start read and write shutdown test");
   } else {
-    gpr_log(GPR_INFO, "Start read and write test with %d bytes, slice size %d",
+    gpr_log(GPR_INFO, "Start read and write test with %" PRIuPTR
+                      " bytes, slice size %" PRIuPTR,
             num_bytes, slice_size);
   }
 
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 0630f1d..24ba474 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -398,7 +398,7 @@
   client_wait_and_shutdown(&cl);
   server_wait_and_shutdown(&sv);
   GPR_ASSERT(sv.read_bytes_total == cl.write_bytes_total);
-  gpr_log(GPR_INFO, "Total read bytes %d", sv.read_bytes_total);
+  gpr_log(GPR_INFO, "Total read bytes %" PRIdPTR, sv.read_bytes_total);
 }
 
 typedef struct fd_change_data {
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 7a98fa0..19ba258 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -151,7 +151,7 @@
   read_bytes = count_slices(state->incoming.slices, state->incoming.count,
                             &current_data);
   state->read_bytes += read_bytes;
-  gpr_log(GPR_INFO, "Read %d bytes of %d", read_bytes,
+  gpr_log(GPR_INFO, "Read %" PRIuPTR " bytes of %" PRIuPTR, read_bytes,
           state->target_read_bytes);
   if (state->read_bytes >= state->target_read_bytes) {
     gpr_mu_unlock(g_mu);
@@ -170,8 +170,8 @@
   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  gpr_log(GPR_INFO, "Read test of size %d, slice size %d", num_bytes,
-          slice_size);
+  gpr_log(GPR_INFO, "Read test of size %" PRIuPTR ", slice size %" PRIuPTR,
+          num_bytes, slice_size);
 
   create_sockets(sv);
 
@@ -179,7 +179,7 @@
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
-  gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+  gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
 
   state.ep = ep;
   state.read_bytes = 0;
@@ -216,7 +216,7 @@
   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  gpr_log(GPR_INFO, "Start large read test, slice size %d", slice_size);
+  gpr_log(GPR_INFO, "Start large read test, slice size %" PRIuPTR, slice_size);
 
   create_sockets(sv);
 
@@ -225,7 +225,7 @@
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket(sv[0]);
-  gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+  gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
 
   state.ep = ep;
   state.read_bytes = 0;
@@ -344,8 +344,9 @@
   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  gpr_log(GPR_INFO, "Start write test with %d bytes, slice size %d", num_bytes,
-          slice_size);
+  gpr_log(GPR_INFO,
+          "Start write test with %" PRIuPTR " bytes, slice size %" PRIuPTR,
+          num_bytes, slice_size);
 
   create_sockets(sv);
 
@@ -404,8 +405,9 @@
   int fd_released_done = 0;
   grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done);
 
-  gpr_log(GPR_INFO, "Release fd read_test of size %d, slice size %d", num_bytes,
-          slice_size);
+  gpr_log(GPR_INFO,
+          "Release fd read_test of size %" PRIuPTR ", slice size %" PRIuPTR,
+          num_bytes, slice_size);
 
   create_sockets(sv);
 
@@ -414,7 +416,7 @@
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
-  gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+  gpr_log(GPR_INFO, "Wrote %" PRIuPTR " bytes", written_bytes);
 
   state.ep = ep;
   state.read_bytes = 0;
diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c
index 2df3837..0da483a 100644
--- a/test/core/support/slice_test.c
+++ b/test/core/support/slice_test.c
@@ -164,7 +164,7 @@
   size_t i;
 
   LOG_TEST_NAME("test_slice_split_head_works");
-  gpr_log(GPR_INFO, "length=%d", length);
+  gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
 
   /* Create a slice in which each byte is equal to the distance from it to the
      beginning of the slice. */
@@ -192,7 +192,7 @@
   size_t i;
 
   LOG_TEST_NAME("test_slice_split_tail_works");
-  gpr_log(GPR_INFO, "length=%d", length);
+  gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
 
   /* Create a slice in which each byte is equal to the distance from it to the
      beginning of the slice. */
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index d5f8107..553a824 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -156,7 +156,7 @@
   LOG_TEST_NAME("test_asprintf");
 
   /* Print an empty string. */
-  GPR_ASSERT(gpr_asprintf(&buf, "") == 0);
+  GPR_ASSERT(gpr_asprintf(&buf, "%s", "") == 0);
   GPR_ASSERT(buf[0] == '\0');
   gpr_free(buf);
 
@@ -334,6 +334,38 @@
   GPR_ASSERT(0 == strcmp("-9223372036854775808", buf));
 }
 
+static void test_leftpad() {
+  char *padded;
+
+  padded = gpr_leftpad("foo", ' ', 5);
+  GPR_ASSERT(0 == strcmp("  foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", ' ', 4);
+  GPR_ASSERT(0 == strcmp(" foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", ' ', 3);
+  GPR_ASSERT(0 == strcmp("foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", ' ', 2);
+  GPR_ASSERT(0 == strcmp("foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", ' ', 1);
+  GPR_ASSERT(0 == strcmp("foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", ' ', 0);
+  GPR_ASSERT(0 == strcmp("foo", padded));
+  gpr_free(padded);
+
+  padded = gpr_leftpad("foo", '0', 5);
+  GPR_ASSERT(0 == strcmp("00foo", padded));
+  gpr_free(padded);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   test_strdup();
@@ -346,5 +378,6 @@
   test_strsplit();
   test_ltoa();
   test_int64toa();
+  test_leftpad();
   return 0;
 }
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index 49a1fc4..2fcd7f5 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -348,8 +348,8 @@
   size_t total_consumed = 0;
   static int optid = 101;
 
-  gpr_log(GPR_INFO, "%s: %d producers, %d consumers", "test_threading",
-          producers, consumers);
+  gpr_log(GPR_INFO, "%s: %" PRIuPTR " producers, %" PRIuPTR " consumers",
+          "test_threading", producers, consumers);
 
   /* start all threads: they will wait for phase1 */
   for (i = 0; i < producers + consumers; i++) {
diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c
index 095861e..08d1073 100644
--- a/test/core/transport/chttp2/bin_encoder_test.c
+++ b/test/core/transport/chttp2/bin_encoder_test.c
@@ -88,7 +88,8 @@
     char *t = gpr_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII);
     char *e = gpr_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
     char *g = gpr_dump_slice(got, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-    gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot:  %s\nwant: %s", t, g, e);
+    gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot:  %s\nwant: %s", line, t, g,
+            e);
     gpr_free(t);
     gpr_free(e);
     gpr_free(g);
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index a4e9694..0078929 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -166,7 +166,7 @@
   grpc_init();
 
   for (i = 0; i < nstrs; i++) {
-    gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
+    gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x", i);
     strs[i] = grpc_mdstr_from_string(buffer);
     shuf[i] = i;
     gpr_free(buffer);
@@ -188,7 +188,8 @@
   for (i = 0; i < nstrs; i++) {
     GRPC_MDSTR_UNREF(strs[shuf[i]]);
     for (j = i + 1; j < nstrs; j++) {
-      gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[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);
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index b839801..8229bda 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -229,9 +229,10 @@
         credentials_type(creds_type),
         message_content(content) {}
   void Log() const {
-    gpr_log(GPR_INFO,
-            "Scenario: disable_blocking %d, credentials %s, message size %d",
-            disable_blocking, credentials_type.c_str(), message_content.size());
+    gpr_log(
+        GPR_INFO,
+        "Scenario: disable_blocking %d, credentials %s, message size %" PRIuPTR,
+        disable_blocking, credentials_type.c_str(), message_content.size());
   }
   bool disable_blocking;
   const grpc::string credentials_type;
diff --git a/test/cpp/end2end/zookeeper_test.cc b/test/cpp/end2end/zookeeper_test.cc
index 12853a1..fdc500e 100644
--- a/test/cpp/end2end/zookeeper_test.cc
+++ b/test/cpp/end2end/zookeeper_test.cc
@@ -101,7 +101,7 @@
       zookeeper_address_ = addr_str;
       gpr_free(addr);
     }
-    gpr_log(GPR_DEBUG, zookeeper_address_.c_str());
+    gpr_log(GPR_DEBUG, "%s", zookeeper_address_.c_str());
 
     // Connects to zookeeper server
     zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 7727824..addaf17 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -171,8 +171,9 @@
         "large_unary|large_compressed_unary|client_streaming|server_streaming|"
         "server_compressed_streaming|half_duplex|ping_pong|cancel_after_begin|"
         "cancel_after_first_response|timeout_on_sleeping_server|empty_stream|"
-        "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds",
-        "status_code_and_message|custom_metadata", FLAGS_test_case.c_str());
+        "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds|"
+        "status_code_and_message|custom_metadata",
+        FLAGS_test_case.c_str());
     ret = 1;
   }
 
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index a0479e8..0bf1fd6 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -433,7 +433,7 @@
     // most likely due to connection failure.
     gpr_log(GPR_ERROR,
             "DoResponseStreaming(): Read fewer streams (%d) than "
-            "response_stream_sizes.size() (%d)",
+            "response_stream_sizes.size() (%" PRIuPTR ")",
             i, response_stream_sizes.size());
     return TransientFailureOrAbort();
   }
@@ -517,9 +517,11 @@
         // stream->Read() failed before reading all the expected messages. This
         // is most likely due to a connection failure.
         gpr_log(GPR_ERROR,
-                "DoResponseCompressedStreaming(): Responses read (k=%d) is "
+                "DoResponseCompressedStreaming(): Responses read (k=%" PRIuPTR
+                ") is "
                 "less than the expected messages (i.e "
-                "response_stream_sizes.size() (%d)). (i=%d, j=%d)",
+                "response_stream_sizes.size() (%" PRIuPTR ")). (i=%" PRIuPTR
+                ", j=%" PRIuPTR ")",
                 k, response_stream_sizes.size(), i, j);
         return TransientFailureOrAbort();
       }
@@ -608,7 +610,7 @@
     // most likely due to a connection failure
     gpr_log(GPR_ERROR,
             "DoHalfDuplex(): Responses read (i=%d) are less than the expected "
-            "number of messages response_stream_sizes.size() (%d)",
+            "number of messages response_stream_sizes.size() (%" PRIuPTR ")",
             i, response_stream_sizes.size());
     return TransientFailureOrAbort();
   }
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index c8c2215..7a0cb99 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -76,7 +76,7 @@
   while (reader->Read(&gauge_response)) {
     if (gauge_response.value_case() == GaugeResponse::kLongValue) {
       if (!total_only) {
-        gpr_log(GPR_INFO, "%s: %ld", gauge_response.name().c_str(),
+        gpr_log(GPR_INFO, "%s: %lld", gauge_response.name().c_str(),
                 gauge_response.long_value());
       }
       overall_qps += gauge_response.long_value();
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 57d8c22..83dbdc3 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -244,8 +244,8 @@
   // where class contained in std::vector must have a copy constructor
   auto* servers = new ServerData[num_servers];
   for (size_t i = 0; i < num_servers; i++) {
-    gpr_log(GPR_INFO, "Starting server on %s (worker #%d)", workers[i].c_str(),
-            i);
+    gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
+            workers[i].c_str(), i);
     servers[i].stub = WorkerService::NewStub(
         CreateChannel(workers[i], InsecureChannelCredentials()));
 
@@ -307,8 +307,8 @@
   auto* clients = new ClientData[num_clients];
   for (size_t i = 0; i < num_clients; i++) {
     const auto& worker = workers[i + num_servers];
-    gpr_log(GPR_INFO, "Starting client on %s (worker #%d)", worker.c_str(),
-            i + num_servers);
+    gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
+            worker.c_str(), i + num_servers);
     clients[i].stub = WorkerService::NewStub(
         CreateChannel(worker, InsecureChannelCredentials()));
     ClientConfig per_client_config = client_config;
diff --git a/test/cpp/qps/parse_json.cc b/test/cpp/qps/parse_json.cc
index be80428..e4fc35f 100644
--- a/test/cpp/qps/parse_json.cc
+++ b/test/cpp/qps/parse_json.cc
@@ -55,7 +55,7 @@
     grpc::string errmsg(status.error_message());
     gpr_log(GPR_ERROR, "Failed to convert json to binary: errcode=%d msg=%s",
             status.error_code(), errmsg.c_str());
-    gpr_log(GPR_ERROR, "JSON: ", json.c_str());
+    gpr_log(GPR_ERROR, "JSON: %s", json.c_str());
     abort();
   }
   GPR_ASSERT(msg->ParseFromString(binary));