Merge branch 'compression-accept-encoding' into compression-interop
diff --git a/Makefile b/Makefile
index afe399c..5f7a61d 100644
--- a/Makefile
+++ b/Makefile
@@ -4862,6 +4862,7 @@
 
 
 LIBINTEROP_CLIENT_HELPER_SRC = \
+    $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc \
     test/cpp/interop/client_helper.cc \
 
 
@@ -4906,6 +4907,7 @@
 -include $(LIBINTEROP_CLIENT_HELPER_OBJS:.o=.dep)
 endif
 endif
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/client_helper.o: $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc
 
 
 LIBINTEROP_CLIENT_MAIN_SRC = \
diff --git a/build.json b/build.json
index 6715ef1..ae3cd66 100644
--- a/build.json
+++ b/build.json
@@ -711,6 +711,7 @@
         "test/cpp/interop/client_helper.h"
       ],
       "src": [
+        "test/proto/messages.proto",
         "test/cpp/interop/client_helper.cc"
       ],
       "deps": [
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 34945f3..5137bf6 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -121,6 +121,10 @@
   gpr_uint32 propagate_;
 };
 
+namespace testing {
+class InteropClientContextInspector;
+}  // namespace testing
+
 class ClientContext {
  public:
   ClientContext();
@@ -190,6 +194,7 @@
   ClientContext(const ClientContext&);
   ClientContext& operator=(const ClientContext&);
 
+  friend class ::grpc::testing::InteropClientContextInspector;
   friend class CallOpClientRecvStatus;
   friend class CallOpRecvInitialMetadata;
   friend class Channel;
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index 4f7fc54..2296835 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -80,7 +80,7 @@
 class Server;
 
 namespace testing {
-class InteropContextInspector;
+class InteropServerContextInspector;
 }  // namespace testing
 
 // Interface of server side rpc context.
@@ -135,7 +135,7 @@
   }
 
  private:
-  friend class ::grpc::testing::InteropContextInspector;
+  friend class ::grpc::testing::InteropServerContextInspector;
   friend class ::grpc::Server;
   template <class W, class R>
   friend class ::grpc::ServerAsyncReader;
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 501731a..a7624fd 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -531,6 +531,12 @@
   call->compression_algorithm = algo;
 }
 
+grpc_compression_algorithm grpc_call_get_compression_algorithm(
+    const grpc_call *call) {
+  return call->compression_algorithm;
+}
+
+
 static void set_encodings_accepted_by_peer(grpc_call *call,
                                 const gpr_slice accept_encoding_slice) {
   size_t i;
@@ -563,6 +569,10 @@
   return call->encodings_accepted_by_peer;
 }
 
+gpr_uint32 grpc_call_get_message_flags(const grpc_call *call) {
+  return call->incoming_message_flags;
+}
+
 static void set_status_details(grpc_call *call, status_source source,
                                grpc_mdstr *status) {
   if (call->status[source].details != NULL) {
@@ -1435,7 +1445,7 @@
   void *user_data = grpc_mdelem_get_user_data(md, destroy_compression);
   if (user_data) {
     algorithm =
-        ((grpc_compression_level)(gpr_intptr)user_data) - COMPRESS_OFFSET;
+        ((grpc_compression_algorithm)(gpr_intptr)user_data) - COMPRESS_OFFSET;
   } else {
     const char *md_c_str = grpc_mdstr_as_c_string(md->value);
     if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str),
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 912979f..00638e4 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -38,6 +38,10 @@
 #include "src/core/channel/context.h"
 #include <grpc/grpc.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Primitive operation types - grpc_op's get rewritten into these */
 typedef enum {
   GRPC_IOREQ_RECV_INITIAL_METADATA,
@@ -162,10 +166,19 @@
 
 gpr_uint8 grpc_call_is_client(grpc_call *call);
 
+grpc_compression_algorithm grpc_call_get_compression_algorithm(
+    const grpc_call *call);
+
+gpr_uint32 grpc_call_get_message_flags(const grpc_call *call);
+
 /** Returns a bitset for the encodings (compression algorithms) supported by \a
  * call's peer.
  *
  * To be indexed by grpc_compression_algorithm enum values. */
 gpr_uint32 grpc_call_get_encodings_accepted_by_peer(grpc_call *call);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index 73d82f7..65fdc63 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -48,10 +48,13 @@
 #include <grpc++/create_channel.h>
 #include <grpc++/credentials.h>
 #include <grpc++/stream.h>
-#include "src/cpp/client/secure_credentials.h"
+
 #include "test/core/security/oauth2_utils.h"
 #include "test/cpp/util/create_test_channel.h"
 
+#include "src/core/surface/call.h"
+#include "src/cpp/client/secure_credentials.h"
+
 DECLARE_bool(enable_ssl);
 DECLARE_bool(use_prod_roots);
 DECLARE_int32(server_port);
@@ -62,6 +65,8 @@
 DECLARE_string(service_account_key_file);
 DECLARE_string(oauth_scope);
 
+using grpc::testing::CompressionType;
+
 namespace grpc {
 namespace testing {
 
@@ -138,5 +143,32 @@
   }
 }
 
+CompressionType GetInteropCompressionTypeFromCompressionAlgorithm(
+    grpc_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      return CompressionType::NONE;
+    case GRPC_COMPRESS_GZIP:
+      return CompressionType::GZIP;
+    case GRPC_COMPRESS_DEFLATE:
+      return CompressionType::DEFLATE;
+    default:
+      GPR_ASSERT(false);
+  }
+}
+
+InteropClientContextInspector::InteropClientContextInspector(
+    const ::grpc::ClientContext& context)
+    : context_(context) {}
+
+grpc_compression_algorithm
+InteropClientContextInspector::GetCallCompressionAlgorithm() const {
+  return grpc_call_get_compression_algorithm(context_.call_);
+}
+
+gpr_uint32 InteropClientContextInspector::GetMessageFlags() const {
+  return grpc_call_get_message_flags(context_.call_);
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h
index c4361bb..1c7036d 100644
--- a/test/cpp/interop/client_helper.h
+++ b/test/cpp/interop/client_helper.h
@@ -39,6 +39,8 @@
 #include <grpc++/config.h>
 #include <grpc++/channel_interface.h>
 
+#include "test/proto/messages.grpc.pb.h"
+
 namespace grpc {
 namespace testing {
 
@@ -49,6 +51,23 @@
 std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
     const grpc::string& test_case);
 
+grpc::testing::CompressionType
+GetInteropCompressionTypeFromCompressionAlgorithm(
+    grpc_compression_algorithm algorithm);
+
+class InteropClientContextInspector {
+ public:
+  InteropClientContextInspector(const ::grpc::ClientContext& context);
+
+  // Inspector methods, able to peek inside ClientContext, follow.
+  grpc_compression_algorithm GetCallCompressionAlgorithm() const;
+  gpr_uint32 GetMessageFlags() const;
+
+ private:
+  const ::grpc::ClientContext& context_;
+};
+
+
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index dfb90fa..8e2d778 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -33,25 +33,31 @@
 
 #include "test/cpp/interop/interop_client.h"
 
+#include <fstream>
 #include <memory>
 
 #include <unistd.h>
 
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
 #include <grpc++/credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
+
 #include "test/cpp/interop/client_helper.h"
 #include "test/proto/test.grpc.pb.h"
 #include "test/proto/empty.grpc.pb.h"
 #include "test/proto/messages.grpc.pb.h"
+#include "src/core/transport/stream_op.h"
 
 namespace grpc {
 namespace testing {
 
+static const char* kRandomFile = "test/cpp/interop/rnd.dat";
+
 namespace {
 // The same value is defined by the Java client.
 const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
@@ -95,17 +101,47 @@
   std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
 
   ClientContext context;
-  request->set_response_type(PayloadType::COMPRESSABLE);
+  InteropClientContextInspector inspector(context);
   request->set_response_size(kLargeResponseSize);
   grpc::string payload(kLargeRequestSize, '\0');
   request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
 
   Status s = stub->UnaryCall(&context, *request, response);
 
+  // Compression related checks.
+  GPR_ASSERT(request->response_compression() ==
+             GetInteropCompressionTypeFromCompressionAlgorithm(
+                 inspector.GetCallCompressionAlgorithm()));
+  if (request->response_compression() == NONE) {
+    GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
+  } else if (request->response_type() == PayloadType::COMPRESSABLE) {
+    // requested compression and compressable response => results should always
+    // be compressed.
+    GPR_ASSERT(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS);
+  }
+
   AssertOkOrPrintErrorStatus(s);
-  GPR_ASSERT(response->payload().type() == PayloadType::COMPRESSABLE);
-  GPR_ASSERT(response->payload().body() ==
-             grpc::string(kLargeResponseSize, '\0'));
+
+  // Payload related checks.
+  if (request->response_type() != PayloadType::RANDOM) {
+    GPR_ASSERT(response->payload().type() == request->response_type());
+  }
+  switch (response->payload().type()) {
+    case PayloadType::COMPRESSABLE:
+      GPR_ASSERT(response->payload().body() ==
+                 grpc::string(kLargeResponseSize, '\0'));
+      break;
+    case PayloadType::UNCOMPRESSABLE: {
+        std::ifstream rnd_file(kRandomFile);
+        GPR_ASSERT(rnd_file.good());
+        for (int i = 0; i < kLargeResponseSize; i++) {
+          GPR_ASSERT(response->payload().body()[i] == (char)rnd_file.get());
+        }
+      }
+      break;
+    default:
+      GPR_ASSERT(false);
+  }
 }
 
 void InteropClient::DoComputeEngineCreds(
@@ -117,6 +153,7 @@
   SimpleResponse response;
   request.set_fill_username(true);
   request.set_fill_oauth_scope(true);
+  request.set_response_type(PayloadType::COMPRESSABLE);
   PerformLargeUnary(&request, &response);
   gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
   gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
@@ -136,6 +173,7 @@
   SimpleResponse response;
   request.set_fill_username(true);
   request.set_fill_oauth_scope(true);
+  request.set_response_type(PayloadType::COMPRESSABLE);
   PerformLargeUnary(&request, &response);
   GPR_ASSERT(!response.username().empty());
   GPR_ASSERT(!response.oauth_scope().empty());
@@ -199,6 +237,7 @@
   SimpleRequest request;
   SimpleResponse response;
   request.set_fill_username(true);
+  request.set_response_type(PayloadType::COMPRESSABLE);
   PerformLargeUnary(&request, &response);
   GPR_ASSERT(!response.username().empty());
   GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
@@ -206,11 +245,25 @@
 }
 
 void InteropClient::DoLargeUnary() {
-  gpr_log(GPR_INFO, "Sending a large unary rpc...");
-  SimpleRequest request;
-  SimpleResponse response;
-  PerformLargeUnary(&request, &response);
-  gpr_log(GPR_INFO, "Large unary done.");
+  const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
+  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
+  for (const auto payload_type : payload_types) {
+    for (const auto compression_type : compression_types) {
+      char* log_suffix;
+      gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
+          CompressionType_Name(compression_type).c_str(),
+          PayloadType_Name(payload_type).c_str());
+
+      gpr_log(GPR_INFO, "Sending a large unary rpc %s.", log_suffix);
+      SimpleRequest request;
+      SimpleResponse response;
+      request.set_response_type(payload_type);
+      request.set_response_compression(compression_type);
+      PerformLargeUnary(&request, &response);
+      gpr_log(GPR_INFO, "Large unary done %s.", log_suffix);
+      gpr_free(log_suffix);
+    }
+  }
 }
 
 void InteropClient::DoRequestStreaming() {
@@ -240,30 +293,66 @@
 }
 
 void InteropClient::DoResponseStreaming() {
-  gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
   std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
 
-  ClientContext context;
-  StreamingOutputCallRequest request;
-  for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
-    ResponseParameters* response_parameter = request.add_response_parameters();
-    response_parameter->set_size(response_stream_sizes[i]);
-  }
-  StreamingOutputCallResponse response;
-  std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
-      stub->StreamingOutputCall(&context, request));
+  const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
+  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
+  for (const auto payload_type : payload_types) {
+    for (const auto compression_type : compression_types) {
+      ClientContext context;
+      InteropClientContextInspector inspector(context);
+      StreamingOutputCallRequest request;
 
-  unsigned int i = 0;
-  while (stream->Read(&response)) {
-    GPR_ASSERT(response.payload().body() ==
-               grpc::string(response_stream_sizes[i], '\0'));
-    ++i;
-  }
-  GPR_ASSERT(response_stream_sizes.size() == i);
-  Status s = stream->Finish();
+      char* log_suffix;
+      gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
+          CompressionType_Name(compression_type).c_str(),
+          PayloadType_Name(payload_type).c_str());
 
-  AssertOkOrPrintErrorStatus(s);
-  gpr_log(GPR_INFO, "Response streaming done.");
+      gpr_log(GPR_INFO, "Receiving response steaming rpc %s.", log_suffix);
+
+      request.set_response_type(payload_type);
+      request.set_response_compression(compression_type);
+
+      for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
+        ResponseParameters* response_parameter =
+            request.add_response_parameters();
+        response_parameter->set_size(response_stream_sizes[i]);
+      }
+      StreamingOutputCallResponse response;
+
+      std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
+          stub->StreamingOutputCall(&context, request));
+
+      unsigned int i = 0;
+      while (stream->Read(&response)) {
+        GPR_ASSERT(response.payload().body() ==
+                   grpc::string(response_stream_sizes[i], '\0'));
+
+        // Compression related checks.
+        GPR_ASSERT(request.response_compression() ==
+                   GetInteropCompressionTypeFromCompressionAlgorithm(
+                       inspector.GetCallCompressionAlgorithm()));
+        if (request.response_compression() == NONE) {
+          GPR_ASSERT(
+              !(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
+        } else if (request.response_type() == PayloadType::COMPRESSABLE) {
+          // requested compression and compressable response => results should
+          // always be compressed.
+          GPR_ASSERT(inspector.GetMessageFlags() &
+                     GRPC_WRITE_INTERNAL_COMPRESS);
+        }
+
+        ++i;
+      }
+
+      GPR_ASSERT(response_stream_sizes.size() == i);
+      Status s = stream->Finish();
+
+      AssertOkOrPrintErrorStatus(s);
+      gpr_log(GPR_INFO, "Response streaming done %s.", log_suffix);
+      gpr_free(log_suffix);
+    }
+  }
 }
 
 void InteropClient::DoResponseStreamingWithSlowConsumer() {
diff --git a/test/cpp/interop/rnd.dat b/test/cpp/interop/rnd.dat
new file mode 100644
index 0000000..8c7f38f
--- /dev/null
+++ b/test/cpp/interop/rnd.dat
Binary files differ
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 05a10de..0097d16 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -31,6 +31,7 @@
  *
  */
 
+#include <fstream>
 #include <memory>
 #include <sstream>
 #include <thread>
@@ -41,6 +42,7 @@
 #include <gflags/gflags.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/useful.h>
 #include <grpc++/config.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
@@ -48,6 +50,7 @@
 #include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
+
 #include "test/proto/test.grpc.pb.h"
 #include "test/proto/empty.grpc.pb.h"
 #include "test/proto/messages.grpc.pb.h"
@@ -65,6 +68,7 @@
 using grpc::ServerReaderWriter;
 using grpc::ServerWriter;
 using grpc::SslServerCredentialsOptions;
+using grpc::testing::InteropServerContextInspector;
 using grpc::testing::Payload;
 using grpc::testing::PayloadType;
 using grpc::testing::SimpleRequest;
@@ -77,19 +81,56 @@
 using grpc::Status;
 
 static bool got_sigint = false;
+static const char* kRandomFile = "test/cpp/interop/rnd.dat";
 
 bool SetPayload(PayloadType type, int size, Payload* payload) {
-  PayloadType response_type = type;
-  // TODO(yangg): Support UNCOMPRESSABLE payload.
-  if (type != PayloadType::COMPRESSABLE) {
-    return false;
+  PayloadType response_type;
+  if (type == PayloadType::RANDOM) {
+    response_type =
+        rand() & 0x1 ? PayloadType::COMPRESSABLE : PayloadType::UNCOMPRESSABLE;
+  } else {
+    response_type = type;
   }
   payload->set_type(response_type);
-  std::unique_ptr<char[]> body(new char[size]());
-  payload->set_body(body.get(), size);
+  switch (response_type) {
+    case PayloadType::COMPRESSABLE: {
+      std::unique_ptr<char[]> body(new char[size]());
+      payload->set_body(body.get(), size);
+    } break;
+    case PayloadType::UNCOMPRESSABLE: {
+      std::unique_ptr<char[]> body(new char[size]());
+      std::ifstream rnd_file(kRandomFile);
+      GPR_ASSERT(rnd_file.good());
+      rnd_file.read(body.get(), size);
+      GPR_ASSERT(!rnd_file.eof());  // Requested more rnd bytes than available
+      payload->set_body(body.get(), size);
+    } break;
+    default:
+      GPR_ASSERT(false);
+  }
   return true;
 }
 
+template <typename RequestType>
+void SetResponseCompression(ServerContext* context,
+                            const RequestType& request) {
+  if (request.has_response_compression()) {
+    switch (request.response_compression()) {
+      case grpc::testing::NONE:
+        context->set_compression_algorithm(GRPC_COMPRESS_NONE);
+        break;
+      case grpc::testing::GZIP:
+        context->set_compression_algorithm(GRPC_COMPRESS_GZIP);
+        break;
+      case grpc::testing::DEFLATE:
+        context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+        break;
+    }
+  } else {
+    context->set_compression_algorithm(GRPC_COMPRESS_NONE);
+  }
+}
+
 class TestServiceImpl : public TestService::Service {
  public:
   Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request,
@@ -99,12 +140,16 @@
 
   Status UnaryCall(ServerContext* context, const SimpleRequest* request,
                    SimpleResponse* response) {
+    InteropServerContextInspector inspector(*context);
+    SetResponseCompression(context, *request);
     if (request->has_response_size() && request->response_size() > 0) {
       if (!SetPayload(request->response_type(), request->response_size(),
                       response->mutable_payload())) {
         return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
       }
     }
+    const gpr_uint32 client_accept_encodings_bitset =
+        inspector.GetEncodingsAcceptedByClient();
 
     if (request->has_response_status()) {
       return Status(static_cast<grpc::StatusCode>
@@ -118,6 +163,7 @@
   Status StreamingOutputCall(
       ServerContext* context, const StreamingOutputCallRequest* request,
       ServerWriter<StreamingOutputCallResponse>* writer) {
+    SetResponseCompression(context, *request);
     StreamingOutputCallResponse response;
     bool write_success = true;
     response.mutable_payload()->set_type(request->response_type());
@@ -156,6 +202,7 @@
     StreamingOutputCallResponse response;
     bool write_success = true;
     while (write_success && stream->Read(&request)) {
+      SetResponseCompression(context, request);
       if (request.response_parameters_size() != 0) {
         response.mutable_payload()->set_type(request.payload().type());
         response.mutable_payload()->set_body(
diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc
index 30a78ff..3721d79 100644
--- a/test/cpp/interop/server_helper.cc
+++ b/test/cpp/interop/server_helper.cc
@@ -36,10 +36,12 @@
 #include <memory>
 
 #include <gflags/gflags.h>
-#include "test/core/end2end/data/ssl_test_data.h"
 #include <grpc++/config.h>
 #include <grpc++/server_credentials.h>
 
+#include "src/core/surface/call.h"
+#include "test/core/end2end/data/ssl_test_data.h"
+
 DECLARE_bool(enable_ssl);
 
 namespace grpc {
@@ -58,16 +60,25 @@
   }
 }
 
-InteropContextInspector::InteropContextInspector(
+InteropServerContextInspector::InteropServerContextInspector(
     const ::grpc::ServerContext& context)
     : context_(context) {}
 
-std::shared_ptr<const AuthContext> InteropContextInspector::GetAuthContext()
-    const {
+grpc_compression_algorithm
+InteropServerContextInspector::GetCallCompressionAlgorithm() const {
+  return grpc_call_get_compression_algorithm(context_.call_);
+}
+
+gpr_uint32 InteropServerContextInspector::GetEncodingsAcceptedByClient() const {
+  return grpc_call_get_encodings_accepted_by_peer(context_.call_);
+}
+
+std::shared_ptr<const AuthContext>
+InteropServerContextInspector::GetAuthContext() const {
   return context_.auth_context();
 }
 
-bool InteropContextInspector::IsCancelled() const {
+bool InteropServerContextInspector::IsCancelled() const {
   return context_.IsCancelled();
 }
 
diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h
index ce977b4..7b6b12c 100644
--- a/test/cpp/interop/server_helper.h
+++ b/test/cpp/interop/server_helper.h
@@ -36,6 +36,7 @@
 
 #include <memory>
 
+#include <grpc/compression.h>
 #include <grpc++/server_context.h>
 #include <grpc++/server_credentials.h>
 
@@ -44,13 +45,15 @@
 
 std::shared_ptr<ServerCredentials> CreateInteropServerCredentials();
 
-class InteropContextInspector {
+class InteropServerContextInspector {
  public:
-  InteropContextInspector(const ::grpc::ServerContext& context);
+  InteropServerContextInspector(const ::grpc::ServerContext& context);
 
   // Inspector methods, able to peek inside ServerContext, follow.
   std::shared_ptr<const AuthContext> GetAuthContext() const;
   bool IsCancelled() const;
+  grpc_compression_algorithm GetCallCompressionAlgorithm() const;
+  gpr_uint32 GetEncodingsAcceptedByClient() const;
 
  private:
   const ::grpc::ServerContext& context_;
diff --git a/test/proto/messages.proto b/test/proto/messages.proto
index 89e5544..a81266f 100644
--- a/test/proto/messages.proto
+++ b/test/proto/messages.proto
@@ -64,7 +64,7 @@
 
 // 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 { 
+message EchoStatus {
   optional int32 code = 1;
   optional string message = 2;
 }
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index b28489c..a855f31 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -13411,7 +13411,9 @@
       "grpc_test_util"
     ], 
     "headers": [
-      "test/cpp/interop/client_helper.h"
+      "test/cpp/interop/client_helper.h", 
+      "test/proto/messages.grpc.pb.h", 
+      "test/proto/messages.pb.h"
     ], 
     "language": "c++", 
     "name": "interop_client_helper",