interop-testing: Add custom_metadata interop test

This commit is contained in:
Eric Gribkoff 2016-12-27 10:01:33 -08:00 committed by GitHub
parent b34d07d058
commit 257062fa88
7 changed files with 151 additions and 4 deletions

View File

@ -143,6 +143,8 @@ public abstract class AbstractInteropTest {
.add(TestUtils.recordServerCallInterceptor(serverCallCapture))
.add(TestUtils.recordRequestHeadersInterceptor(requestHeadersCapture))
.add(TestUtils.echoRequestHeadersInterceptor(Util.METADATA_KEY))
.add(TestUtils.echoRequestMetadataInHeaders(Util.ECHO_INITIAL_METADATA_KEY))
.add(TestUtils.echoRequestMetadataInTrailers(Util.ECHO_TRAILING_METADATA_KEY))
.add(interceptors)
.build();
@ -843,6 +845,85 @@ public abstract class AbstractInteropTest {
verifyNoMoreInteractions(responseObserver);
}
@Test(timeout = 10000)
public void customMetadata() throws Exception {
final int responseSize = 314159;
final int requestSize = 271828;
final SimpleRequest request = SimpleRequest.newBuilder()
.setResponseSize(responseSize)
.setResponseType(PayloadType.COMPRESSABLE)
.setPayload(Payload.newBuilder()
.setBody(ByteString.copyFrom(new byte[requestSize])))
.build();
final StreamingOutputCallRequest streamingRequest = StreamingOutputCallRequest.newBuilder()
.addResponseParameters(ResponseParameters.newBuilder().setSize(responseSize))
.setResponseType(PayloadType.COMPRESSABLE)
.setPayload(Payload.newBuilder().setBody(ByteString.copyFrom(new byte[requestSize])))
.build();
final SimpleResponse goldenResponse = SimpleResponse.newBuilder()
.setPayload(Payload.newBuilder()
.setType(PayloadType.COMPRESSABLE)
.setBody(ByteString.copyFrom(new byte[responseSize])))
.build();
final StreamingOutputCallResponse goldenStreamingResponse =
StreamingOutputCallResponse.newBuilder()
.setPayload(Payload.newBuilder()
.setType(PayloadType.COMPRESSABLE)
.setBody(ByteString.copyFrom(new byte[responseSize])))
.build();
final byte[] trailingBytes =
{(byte) 0xa, (byte) 0xb, (byte) 0xa, (byte) 0xb, (byte) 0xa, (byte) 0xb};
// Test UnaryCall
Metadata metadata = new Metadata();
metadata.put(Util.ECHO_INITIAL_METADATA_KEY, "test_initial_metadata_value");
metadata.put(Util.ECHO_TRAILING_METADATA_KEY, trailingBytes);
TestServiceGrpc.TestServiceBlockingStub blockingStub = TestServiceGrpc.newBlockingStub(channel);
blockingStub = MetadataUtils.attachHeaders(blockingStub, metadata);
AtomicReference<Metadata> headersCapture = new AtomicReference<Metadata>();
AtomicReference<Metadata> trailersCapture = new AtomicReference<Metadata>();
blockingStub = MetadataUtils.captureMetadata(blockingStub, headersCapture, trailersCapture);
SimpleResponse response = blockingStub.unaryCall(request);
assertEquals(goldenResponse, response);
assertEquals("test_initial_metadata_value",
headersCapture.get().get(Util.ECHO_INITIAL_METADATA_KEY));
assertTrue(
Arrays.equals(trailingBytes, trailersCapture.get().get(Util.ECHO_TRAILING_METADATA_KEY)));
if (metricsExpected()) {
assertMetrics("grpc.testing.TestService/UnaryCall", Status.Code.OK,
Collections.singleton(request), Collections.singleton(goldenResponse));
}
// Test FullDuplexCall
metadata = new Metadata();
metadata.put(Util.ECHO_INITIAL_METADATA_KEY, "test_initial_metadata_value");
metadata.put(Util.ECHO_TRAILING_METADATA_KEY, trailingBytes);
TestServiceGrpc.TestServiceStub stub = TestServiceGrpc.newStub(channel);
stub = MetadataUtils.attachHeaders(stub, metadata);
headersCapture = new AtomicReference<Metadata>();
trailersCapture = new AtomicReference<Metadata>();
stub = MetadataUtils.captureMetadata(stub, headersCapture, trailersCapture);
StreamRecorder<Messages.StreamingOutputCallResponse> recorder = StreamRecorder.create();
StreamObserver<Messages.StreamingOutputCallRequest> requestStream =
stub.fullDuplexCall(recorder);
requestStream.onNext(streamingRequest);
requestStream.onCompleted();
recorder.awaitCompletion();
assertSuccess(recorder);
assertEquals(goldenStreamingResponse, recorder.firstValue().get());
assertEquals("test_initial_metadata_value",
headersCapture.get().get(Util.ECHO_INITIAL_METADATA_KEY));
assertTrue(
Arrays.equals(trailingBytes, trailersCapture.get().get(Util.ECHO_TRAILING_METADATA_KEY)));
if (metricsExpected()) {
assertMetrics("grpc.testing.TestService/FullDuplexCall", Status.Code.OK,
Collections.singleton(streamingRequest), Collections.singleton(goldenStreamingResponse));
}
}
/** Sends an rpc to an unimplemented method within TestService. */
@Test(timeout = 10000)
public void unimplementedMethod() {

View File

@ -48,6 +48,7 @@ public enum TestCases {
JWT_TOKEN_CREDS("JWT-based auth"),
OAUTH2_AUTH_TOKEN("raw oauth2 access token auth"),
PER_RPC_CREDS("per rpc raw oauth2 access token auth"),
CUSTOM_METADATA("unary and full duplex calls with metadata"),
UNIMPLEMENTED_METHOD("call an unimplemented RPC method"),
UNIMPLEMENTED_SERVICE("call an unimplemented RPC service"),
CANCEL_AFTER_BEGIN("cancel stream after starting it"),

View File

@ -263,6 +263,11 @@ public class TestServiceClient {
break;
}
case CUSTOM_METADATA: {
tester.customMetadata();
break;
}
case UNIMPLEMENTED_METHOD: {
tester.unimplementedMethod();
break;

View File

@ -146,7 +146,9 @@ public class TestServiceServer {
.maxMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
.addService(ServerInterceptors.intercept(
new TestServiceImpl(executor),
TestUtils.echoRequestHeadersInterceptor(Util.METADATA_KEY)))
TestUtils.echoRequestHeadersInterceptor(Util.METADATA_KEY),
TestUtils.echoRequestMetadataInHeaders(Util.ECHO_INITIAL_METADATA_KEY),
TestUtils.echoRequestMetadataInTrailers(Util.ECHO_TRAILING_METADATA_KEY)))
.build().start();
}

View File

@ -47,6 +47,10 @@ public class Util {
public static final Metadata.Key<Messages.SimpleContext> METADATA_KEY =
ProtoUtils.keyForProto(Messages.SimpleContext.getDefaultInstance());
public static final Metadata.Key<String> ECHO_INITIAL_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-initial", Metadata.ASCII_STRING_MARSHALLER);
public static final Metadata.Key<byte[]> ECHO_TRAILING_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-trailing-bin", Metadata.BINARY_BYTE_MARSHALLER);
/** Assert that two messages are equal, producing a useful message if not. */
public static void assertEquals(MessageLite expected, MessageLite actual) {

View File

@ -57,9 +57,9 @@ public class TestCasesTest {
// names of testcases as defined in the interop spec
String[] testCases = {"empty_unary", "large_unary", "client_streaming", "server_streaming",
"ping_pong", "empty_stream", "compute_engine_creds", "service_account_creds",
"jwt_token_creds", "oauth2_auth_token", "per_rpc_creds", "unimplemented_method",
"unimplemented_service", "cancel_after_begin", "cancel_after_first_response",
"timeout_on_sleeping_server"};
"jwt_token_creds", "oauth2_auth_token", "per_rpc_creds", "custom_metadata",
"unimplemented_method", "unimplemented_service", "cancel_after_begin",
"cancel_after_first_response", "timeout_on_sleeping_server"};
assertEquals(testCases.length, TestCases.values().length);

View File

@ -104,6 +104,60 @@ public class TestUtils {
};
}
/**
* Echoes request headers with the specified key(s) from a client into response headers only.
*/
public static ServerInterceptor echoRequestMetadataInHeaders(final Metadata.Key<?>... keys) {
final Set<Metadata.Key<?>> keySet = new HashSet<Metadata.Key<?>>(Arrays.asList(keys));
return new ServerInterceptor() {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
final Metadata requestHeaders,
ServerCallHandler<ReqT, RespT> next) {
return next.startCall(new SimpleForwardingServerCall<ReqT, RespT>(call) {
@Override
public void sendHeaders(Metadata responseHeaders) {
responseHeaders.merge(requestHeaders, keySet);
super.sendHeaders(responseHeaders);
}
@Override
public void close(Status status, Metadata trailers) {
super.close(status, trailers);
}
}, requestHeaders);
}
};
}
/**
* Echoes request headers with the specified key(s) from a client into response trailers only.
*/
public static ServerInterceptor echoRequestMetadataInTrailers(final Metadata.Key<?>... keys) {
final Set<Metadata.Key<?>> keySet = new HashSet<Metadata.Key<?>>(Arrays.asList(keys));
return new ServerInterceptor() {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
final Metadata requestHeaders,
ServerCallHandler<ReqT, RespT> next) {
return next.startCall(new SimpleForwardingServerCall<ReqT, RespT>(call) {
@Override
public void sendHeaders(Metadata responseHeaders) {
super.sendHeaders(responseHeaders);
}
@Override
public void close(Status status, Metadata trailers) {
trailers.merge(requestHeaders, keySet);
super.close(status, trailers);
}
}, requestHeaders);
}
};
}
/**
* Capture the request headers from a client. Useful for testing metadata propagation without
* requiring that it be symmetric on client and server, as with