mirror of https://github.com/grpc/grpc-java.git
interop-testing: Add custom_metadata interop test
This commit is contained in:
parent
b34d07d058
commit
257062fa88
|
@ -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() {
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -263,6 +263,11 @@ public class TestServiceClient {
|
|||
break;
|
||||
}
|
||||
|
||||
case CUSTOM_METADATA: {
|
||||
tester.customMetadata();
|
||||
break;
|
||||
}
|
||||
|
||||
case UNIMPLEMENTED_METHOD: {
|
||||
tester.unimplementedMethod();
|
||||
break;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue