/* * Copyright 2015 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 com.google.common.truth.Truth.assertThat; import static io.grpc.internal.GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY; import static io.grpc.internal.GrpcUtil.MESSAGE_ENCODING_KEY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.protobuf.ByteString; import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.ClientCall; import io.grpc.ClientCall.Listener; import io.grpc.ClientInterceptor; import io.grpc.Codec; import io.grpc.CompressorRegistry; import io.grpc.DecompressorRegistry; import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; import io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.ServerCall; import io.grpc.ServerCallHandler; import io.grpc.ServerInterceptor; import io.grpc.ServerInterceptors; import io.grpc.stub.StreamObserver; import io.grpc.testing.integration.Messages.Payload; import io.grpc.testing.integration.Messages.SimpleRequest; import io.grpc.testing.integration.Messages.SimpleResponse; import io.grpc.testing.integration.TestServiceGrpc.TestServiceBlockingStub; import io.grpc.testing.integration.TransportCompressionTest.Fzip; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; /** * Tests for compression configurations. * *
Because of the asymmetry of clients and servers, clients will not know what decompression * methods the server supports. In cases where the client is willing to encode, and the server * is willing to decode, a second RPC is sent to show that the client has learned and will use * the encoding. * *
In cases where compression is negotiated, but either the client or the server doesn't * actually want to encode, a dummy codec is used to record usage. If compression is not enabled, * the codec will see no data pass through. This is checked on each test to ensure the code is * doing the right thing. */ @RunWith(Parameterized.class) public class CompressionTest { private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); // Ensures that both the request and response messages are more than 0 bytes. The framer/deframer // may not use the compressor if the message is empty. private static final SimpleRequest REQUEST = SimpleRequest.newBuilder() .setResponseSize(1) .build(); private Fzip clientCodec = new Fzip("fzip", Codec.Identity.NONE); private Fzip serverCodec = new Fzip("fzip", Codec.Identity.NONE); private DecompressorRegistry clientDecompressors = DecompressorRegistry.emptyInstance(); private DecompressorRegistry serverDecompressors = DecompressorRegistry.emptyInstance(); private CompressorRegistry clientCompressors = CompressorRegistry.newEmptyInstance(); private CompressorRegistry serverCompressors = CompressorRegistry.newEmptyInstance(); /** The headers received by the server from the client. */ private volatile Metadata serverResponseHeaders; /** The headers received by the client from the server. */ private volatile Metadata clientResponseHeaders; // Params private final boolean enableClientMessageCompression; private final boolean enableServerMessageCompression; private final boolean clientAcceptEncoding; private final boolean clientEncoding; private final boolean serverAcceptEncoding; private final boolean serverEncoding; private Server server; private ManagedChannel channel; private TestServiceBlockingStub stub; /** * Auto called by test. */ public CompressionTest( boolean enableClientMessageCompression, boolean clientAcceptEncoding, boolean clientEncoding, boolean enableServerMessageCompression, boolean serverAcceptEncoding, boolean serverEncoding) { this.enableClientMessageCompression = enableClientMessageCompression; this.clientAcceptEncoding = clientAcceptEncoding; this.clientEncoding = clientEncoding; this.enableServerMessageCompression = enableServerMessageCompression; this.serverAcceptEncoding = serverAcceptEncoding; this.serverEncoding = serverEncoding; } @Before public void setUp() throws Exception { clientDecompressors = clientDecompressors.with(Codec.Identity.NONE, false); serverDecompressors = serverDecompressors.with(Codec.Identity.NONE, false); } @After public void tearDown() { channel.shutdownNow(); server.shutdownNow(); executor.shutdownNow(); } /** * Parameters for test. */ @Parameters public static Collection