Merge branch 'master' of https://github.com/grpc/grpc into new_interop_tests
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 1e049663..6a3979d 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -750,21 +750,36 @@
 
 ### unimplemented_method
 
-Status: Ready for implementation. Blocking beta.
+This test verifies that calling an unimplemented RPC method returns the 
+UNIMPLEMENTED status code.
 
-This test verifies calling unimplemented RPC method returns the UNIMPLEMENTED status code.
+Server features:
+N/A
+
+Procedure:
+* Client calls `grpc.testing.TestService/UnimplementedMethod` with an empty
+  request (defined as `grpc.testing.Empty`):
+
+    ```
+    {
+    }
+    ```
+   
+Client asserts:
+* received status code is 12 (UNIMPLEMENTED)
+* received status message is empty or null/unset
+
+### unimplemented_service
+
+This test verifies calling an unimplemented server returns the UNIMPLEMENTED
+status code.
 
 Server features:
 N/A
 
 Procedure:
 * Client calls `grpc.testing.UnimplementedService/UnimplementedCall` with an
-  empty request (defined as `grpc.testing.Empty`):
-
-    ```
-    {
-    }
-    ```
+  empty request (defined as `grpc.testing.Empty`)
 
 Client asserts:
 * received status code is 12 (UNIMPLEMENTED)
diff --git a/src/proto/grpc/testing/test.proto b/src/proto/grpc/testing/test.proto
index 84369db..801baf8 100644
--- a/src/proto/grpc/testing/test.proto
+++ b/src/proto/grpc/testing/test.proto
@@ -69,6 +69,10 @@
   // first request.
   rpc HalfDuplexCall(stream StreamingOutputCallRequest)
       returns (stream StreamingOutputCallResponse);
+
+  // The test server will not implement this method. It will be used
+  // to test the behavior when clients call unimplemented methods.
+  rpc UnimplementedMethod(grpc.testing.Empty) returns (grpc.testing.Empty);
 }
 
 // A simple service NOT implemented at servers so clients can test for
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 032b378..51de7ac 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -79,7 +79,8 @@
               "slow_consumer : single request with response streaming with "
               "slow client consumer;\n"
               "status_code_and_message: verify status code & message;\n"
-              "timeout_on_sleeping_server: deadline exceeds on stream;\n");
+              "timeout_on_sleeping_server: deadline exceeds on stream;\n"
+              "unimplemented_method: client calls an unimplemented_method;\n");
 DEFINE_string(default_service_account, "",
               "Email of GCE default service account");
 DEFINE_string(service_account_key_file, "",
@@ -149,6 +150,8 @@
     client.DoStatusWithMessage();
   } else if (FLAGS_test_case == "custom_metadata") {
     client.DoCustomMetadata();
+  } else if (FLAGS_test_case == "unimplemented_method") {
+    client.DoUnimplementedMethod();
   } else if (FLAGS_test_case == "all") {
     client.DoEmpty();
     client.DoLargeUnary();
@@ -166,6 +169,7 @@
     client.DoEmptyStream();
     client.DoStatusWithMessage();
     client.DoCustomMetadata();
+    client.DoUnimplementedMethod();
     // service_account_creds and jwt_token_creds can only run with ssl.
     if (FLAGS_use_tls) {
       grpc::string json_key = GetServiceAccountJsonKey();
@@ -198,7 +202,8 @@
                                "server_compressed_unary",
                                "server_streaming",
                                "status_code_and_message",
-                               "timeout_on_sleeping_server"};
+                               "timeout_on_sleeping_server",
+                               "unimplemented_method"};
     char* joined_testcases =
         gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", NULL);
 
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 6117878..65519a0 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -937,5 +937,25 @@
   return true;
 }
 
+bool InteropClient::DoUnimplementedMethod() {
+  gpr_log(GPR_DEBUG, "Sending a request for an unimplemented rpc...");
+
+  Empty request = Empty::default_instance();
+  Empty response = Empty::default_instance();
+  ClientContext context;
+
+  Status s = serviceStub_.Get()->UnimplementedMethod(
+    &context, request, &response);
+
+  if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) {
+    return false;
+  }
+
+  GPR_ASSERT(s.error_message().empty());
+
+  gpr_log(GPR_DEBUG, "unimplemented rpc done.");
+  return true;
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index eb886fc..a535bf9 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -79,6 +79,7 @@
   bool DoEmptyStream();
   bool DoStatusWithMessage();
   bool DoCustomMetadata();
+  bool DoUnimplementedMethod();
   // Auth tests.
   // username is a string containing the user email
   bool DoJwtTokenCreds(const grpc::string& username);
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 389d070..310cfe6 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -89,7 +89,7 @@
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED
+    return []
 
   def unimplemented_test_cases_server(self):
     return _SKIP_ADVANCED