diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java index fdc8cc3202..ec03909f55 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java @@ -1532,6 +1532,27 @@ public abstract class AbstractInteropTest { assertStatsTrace("grpc.testing.TestService/FullDuplexCall", Status.Code.UNKNOWN); } + @Test + public void specialStatusMessage() throws Exception { + int errorCode = 2; + String errorMessage = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n"; + SimpleRequest simpleRequest = SimpleRequest.newBuilder() + .setResponseStatus(EchoStatus.newBuilder() + .setCode(errorCode) + .setMessage(errorMessage) + .build()) + .build(); + + try { + blockingStub.unaryCall(simpleRequest); + fail(); + } catch (StatusRuntimeException e) { + assertEquals(Status.UNKNOWN.getCode(), e.getStatus().getCode()); + assertEquals(errorMessage, e.getStatus().getDescription()); + } + assertStatsTrace("grpc.testing.TestService/UnaryCall", Status.Code.UNKNOWN); + } + /** Sends an rpc to an unimplemented method within TestService. */ @Test public void unimplementedMethod() { diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/TestCases.java b/interop-testing/src/main/java/io/grpc/testing/integration/TestCases.java index 82f5a80440..39eef8a5ab 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/TestCases.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/TestCases.java @@ -44,6 +44,7 @@ public enum TestCases { PER_RPC_CREDS("per rpc raw oauth2 access token auth"), CUSTOM_METADATA("unary and full duplex calls with metadata"), STATUS_CODE_AND_MESSAGE("request error code and message"), + SPECIAL_STATUS_MESSAGE("special characters in status message"), UNIMPLEMENTED_METHOD("call an unimplemented RPC method"), UNIMPLEMENTED_SERVICE("call an unimplemented RPC service"), CANCEL_AFTER_BEGIN("cancel stream after starting it"), diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java b/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java index ab9e58506f..df56c37f05 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java @@ -301,6 +301,10 @@ public class TestServiceClient { break; } + case SPECIAL_STATUS_MESSAGE: + tester.specialStatusMessage(); + break; + case UNIMPLEMENTED_METHOD: { tester.unimplementedMethod(); break; diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/TestCasesTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/TestCasesTest.java index faa2cf58af..844ab9bd76 100644 --- a/interop-testing/src/test/java/io/grpc/testing/integration/TestCasesTest.java +++ b/interop-testing/src/test/java/io/grpc/testing/integration/TestCasesTest.java @@ -58,6 +58,7 @@ public class TestCasesTest { "per_rpc_creds", "custom_metadata", "status_code_and_message", + "special_status_message", "unimplemented_method", "unimplemented_service", "cancel_after_begin",