-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
interop-testing: Add cartesian product HTTP/2 interop test
- Loading branch information
Showing
3 changed files
with
219 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
173 changes: 173 additions & 0 deletions
173
interop-testing/src/test/java/io/grpc/testing/integration/Http2Test.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright 2022 The gRPC Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.grpc.testing.integration; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotEquals; | ||
|
||
import io.grpc.ChannelCredentials; | ||
import io.grpc.ManagedChannelBuilder; | ||
import io.grpc.Metadata; | ||
import io.grpc.ServerBuilder; | ||
import io.grpc.ServerCredentials; | ||
import io.grpc.TlsChannelCredentials; | ||
import io.grpc.TlsServerCredentials; | ||
import io.grpc.internal.testing.TestUtils; | ||
import io.grpc.netty.InternalNettyChannelBuilder; | ||
import io.grpc.netty.InternalNettyServerBuilder; | ||
import io.grpc.netty.NettyChannelBuilder; | ||
import io.grpc.netty.NettyServerBuilder; | ||
import io.grpc.okhttp.InternalOkHttpChannelBuilder; | ||
import io.grpc.okhttp.InternalOkHttpServerBuilder; | ||
import io.grpc.okhttp.OkHttpChannelBuilder; | ||
import io.grpc.okhttp.OkHttpServerBuilder; | ||
import io.grpc.stub.MetadataUtils; | ||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
import java.net.InetSocketAddress; | ||
import java.util.Arrays; | ||
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
import org.junit.runners.Parameterized.Parameters; | ||
|
||
/** | ||
* Integration tests for GRPC over the various HTTP2 transports. | ||
*/ | ||
@RunWith(Parameterized.class) | ||
public class Http2Test extends AbstractInteropTest { | ||
@BeforeClass | ||
public static void loadConscrypt() throws Exception { | ||
// Load conscrypt if it is available. Either Conscrypt or Jetty ALPN needs to be available for | ||
// OkHttp to negotiate. | ||
TestUtils.installConscryptIfAvailable(); | ||
} | ||
|
||
enum Transport { | ||
NETTY, OKHTTP; | ||
} | ||
|
||
/** Parameterized test cases. */ | ||
@Parameters(name = "client={0},server={1}") | ||
public static Iterable<Object[]> data() { | ||
return Arrays.asList(new Object[][] { | ||
{Transport.NETTY, Transport.NETTY}, | ||
{Transport.OKHTTP, Transport.OKHTTP}, | ||
{Transport.OKHTTP, Transport.NETTY}, | ||
{Transport.NETTY, Transport.OKHTTP}, | ||
}); | ||
} | ||
|
||
private final Transport clientType; | ||
private final Transport serverType; | ||
|
||
public Http2Test(Transport clientType, Transport serverType) { | ||
this.clientType = clientType; | ||
this.serverType = serverType; | ||
} | ||
|
||
@Override | ||
protected ServerBuilder<?> getServerBuilder() { | ||
// Starts the server with HTTPS. | ||
ServerCredentials serverCreds; | ||
try { | ||
serverCreds = TlsServerCredentials.create( | ||
TestUtils.loadCert("server1.pem"), TestUtils.loadCert("server1.key")); | ||
} catch (IOException ex) { | ||
throw new RuntimeException(ex); | ||
} | ||
ServerBuilder<?> builder; | ||
if (serverType == Transport.NETTY) { | ||
NettyServerBuilder nettyBuilder = NettyServerBuilder.forPort(0, serverCreds) | ||
.flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW); | ||
// Disable the default census stats tracer, use testing tracer instead. | ||
InternalNettyServerBuilder.setStatsEnabled(nettyBuilder, false); | ||
builder = nettyBuilder; | ||
} else { | ||
OkHttpServerBuilder okHttpBuilder = OkHttpServerBuilder.forPort(0, serverCreds) | ||
.flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW); | ||
// Disable the default census stats tracer, use testing tracer instead. | ||
InternalOkHttpServerBuilder.setStatsEnabled(okHttpBuilder, false); | ||
builder = okHttpBuilder; | ||
} | ||
return builder | ||
.maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE) | ||
.addStreamTracerFactory(createCustomCensusTracerFactory()); | ||
} | ||
|
||
@Override | ||
protected ManagedChannelBuilder<?> createChannelBuilder() { | ||
ChannelCredentials channelCreds; | ||
try { | ||
channelCreds = TlsChannelCredentials.newBuilder() | ||
.trustManager(TestUtils.loadCert("ca.pem")) | ||
.build(); | ||
} catch (Exception ex) { | ||
throw new RuntimeException(ex); | ||
} | ||
int port = ((InetSocketAddress) getListenAddress()).getPort(); | ||
ManagedChannelBuilder<?> builder; | ||
if (clientType == Transport.NETTY) { | ||
NettyChannelBuilder nettyBuilder = NettyChannelBuilder | ||
.forAddress("localhost", port, channelCreds) | ||
.flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW); | ||
// Disable the default census stats interceptor, use testing interceptor instead. | ||
InternalNettyChannelBuilder.setStatsEnabled(nettyBuilder, false); | ||
builder = nettyBuilder; | ||
} else { | ||
OkHttpChannelBuilder okHttpBuilder = OkHttpChannelBuilder | ||
.forAddress("localhost", port, channelCreds) | ||
.flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW); | ||
// Disable the default census stats interceptor, use testing interceptor instead. | ||
InternalOkHttpChannelBuilder.setStatsEnabled(okHttpBuilder, false); | ||
builder = okHttpBuilder; | ||
} | ||
return builder | ||
.overrideAuthority(TestUtils.TEST_SERVER_HOST) | ||
.maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE) | ||
.intercept(createCensusStatsClientInterceptor()); | ||
} | ||
|
||
@Test | ||
public void remoteAddr() { | ||
InetSocketAddress isa = (InetSocketAddress) obtainRemoteClientAddr(); | ||
assertEquals(InetAddress.getLoopbackAddress(), isa.getAddress()); | ||
// It should not be the same as the server | ||
assertNotEquals(((InetSocketAddress) getListenAddress()).getPort(), isa.getPort()); | ||
} | ||
|
||
@Test | ||
public void localAddr() throws Exception { | ||
InetSocketAddress isa = (InetSocketAddress) obtainLocalServerAddr(); | ||
assertEquals(InetAddress.getLoopbackAddress(), isa.getAddress()); | ||
assertEquals(((InetSocketAddress) getListenAddress()).getPort(), isa.getPort()); | ||
} | ||
|
||
@Test | ||
public void contentLengthPermitted() throws Exception { | ||
// Some third-party gRPC implementations (e.g., ServiceTalk) include Content-Length. The HTTP/2 | ||
// code starting in Netty 4.1.60.Final has special-cased handling of Content-Length, and may | ||
// call uncommon methods on our custom headers implementation. | ||
// https://github.com/grpc/grpc-java/issues/7953 | ||
Metadata contentLength = new Metadata(); | ||
contentLength.put(Metadata.Key.of("content-length", Metadata.ASCII_STRING_MARSHALLER), "5"); | ||
blockingStub | ||
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(contentLength)) | ||
.emptyCall(EMPTY); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
okhttp/src/main/java/io/grpc/okhttp/InternalOkHttpServerBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright 2022 The gRPC Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.grpc.okhttp; | ||
|
||
import io.grpc.Internal; | ||
import io.grpc.ServerStreamTracer; | ||
import io.grpc.internal.InternalServer; | ||
import io.grpc.internal.TransportTracer; | ||
import java.util.List; | ||
|
||
/** | ||
* Internal {@link OkHttpServerBuilder} accessor. This is intended for usage internal to | ||
* the gRPC team. If you *really* think you need to use this, contact the gRPC team first. | ||
*/ | ||
@Internal | ||
public final class InternalOkHttpServerBuilder { | ||
public static InternalServer buildTransportServers(OkHttpServerBuilder builder, | ||
List<? extends ServerStreamTracer.Factory> streamTracerFactories) { | ||
return builder.buildTransportServers(streamTracerFactories); | ||
} | ||
|
||
public static void setTransportTracerFactory(OkHttpServerBuilder builder, | ||
TransportTracer.Factory transportTracerFactory) { | ||
builder.setTransportTracerFactory(transportTracerFactory); | ||
} | ||
|
||
public static void setStatsEnabled(OkHttpServerBuilder builder, boolean value) { | ||
builder.setStatsEnabled(value); | ||
} | ||
|
||
private InternalOkHttpServerBuilder() {} | ||
} |