Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright 2016 The gRPC Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package io.grpc.internal;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 import static junit.framework.TestCase.assertFalse;
     21 import static org.junit.Assert.assertEquals;
     22 import static org.junit.Assert.assertNotEquals;
     23 import static org.junit.Assert.assertNotNull;
     24 import static org.junit.Assert.assertNull;
     25 import static org.junit.Assert.assertTrue;
     26 import static org.junit.Assert.fail;
     27 import static org.mockito.Mockito.mock;
     28 
     29 import com.google.common.util.concurrent.MoreExecutors;
     30 import io.grpc.CallOptions;
     31 import io.grpc.Channel;
     32 import io.grpc.ClientCall;
     33 import io.grpc.ClientInterceptor;
     34 import io.grpc.CompressorRegistry;
     35 import io.grpc.DecompressorRegistry;
     36 import io.grpc.LoadBalancer;
     37 import io.grpc.MethodDescriptor;
     38 import io.grpc.NameResolver;
     39 import io.grpc.internal.testing.StatsTestUtils.FakeStatsRecorder;
     40 import io.grpc.internal.testing.StatsTestUtils.FakeTagContextBinarySerializer;
     41 import io.grpc.internal.testing.StatsTestUtils.FakeTagger;
     42 import java.net.InetSocketAddress;
     43 import java.net.SocketAddress;
     44 import java.net.URI;
     45 import java.util.List;
     46 import java.util.concurrent.Executor;
     47 import java.util.concurrent.TimeUnit;
     48 import org.junit.Rule;
     49 import org.junit.Test;
     50 import org.junit.rules.ExpectedException;
     51 import org.junit.runner.RunWith;
     52 import org.junit.runners.JUnit4;
     53 
     54 /** Unit tests for {@link AbstractManagedChannelImplBuilder}. */
     55 @RunWith(JUnit4.class)
     56 public class AbstractManagedChannelImplBuilderTest {
     57 
     58   @Rule
     59   public final ExpectedException thrown = ExpectedException.none();
     60 
     61   private static final ClientInterceptor DUMMY_USER_INTERCEPTOR =
     62       new ClientInterceptor() {
     63         @Override
     64         public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
     65             MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
     66           return next.newCall(method, callOptions);
     67         }
     68       };
     69 
     70   private Builder builder = new Builder("fake");
     71   private Builder directAddressBuilder = new Builder(new SocketAddress(){}, "fake");
     72 
     73   @Test
     74   public void executor_default() {
     75     assertNotNull(builder.executorPool);
     76   }
     77 
     78   @Test
     79   public void executor_normal() {
     80     Executor executor = mock(Executor.class);
     81     assertEquals(builder, builder.executor(executor));
     82     assertEquals(executor, builder.executorPool.getObject());
     83   }
     84 
     85   @Test
     86   public void executor_null() {
     87     ObjectPool<? extends Executor> defaultValue = builder.executorPool;
     88     builder.executor(mock(Executor.class));
     89     assertEquals(builder, builder.executor(null));
     90     assertEquals(defaultValue, builder.executorPool);
     91   }
     92 
     93   @Test
     94   public void directExecutor() {
     95     assertEquals(builder, builder.directExecutor());
     96     assertEquals(MoreExecutors.directExecutor(), builder.executorPool.getObject());
     97   }
     98 
     99   @Test
    100   public void nameResolverFactory_default() {
    101     assertNotNull(builder.getNameResolverFactory());
    102   }
    103 
    104   @Test
    105   public void nameResolverFactory_normal() {
    106     NameResolver.Factory nameResolverFactory = mock(NameResolver.Factory.class);
    107     assertEquals(builder, builder.nameResolverFactory(nameResolverFactory));
    108     assertEquals(nameResolverFactory, builder.getNameResolverFactory());
    109   }
    110 
    111   @Test
    112   public void nameResolverFactory_null() {
    113     NameResolver.Factory defaultValue = builder.getNameResolverFactory();
    114     builder.nameResolverFactory(mock(NameResolver.Factory.class));
    115     assertEquals(builder, builder.nameResolverFactory(null));
    116     assertEquals(defaultValue, builder.getNameResolverFactory());
    117   }
    118 
    119   @Test(expected = IllegalStateException.class)
    120   public void nameResolverFactory_notAllowedWithDirectAddress() {
    121     directAddressBuilder.nameResolverFactory(mock(NameResolver.Factory.class));
    122   }
    123 
    124   @Test
    125   public void loadBalancerFactory_default() {
    126     assertNull(builder.loadBalancerFactory);
    127   }
    128 
    129   @Test
    130   public void loadBalancerFactory_normal() {
    131     LoadBalancer.Factory loadBalancerFactory = mock(LoadBalancer.Factory.class);
    132     assertEquals(builder, builder.loadBalancerFactory(loadBalancerFactory));
    133     assertEquals(loadBalancerFactory, builder.loadBalancerFactory);
    134   }
    135 
    136   @Test
    137   public void loadBalancerFactory_null() {
    138     LoadBalancer.Factory defaultValue = builder.loadBalancerFactory;
    139     builder.loadBalancerFactory(mock(LoadBalancer.Factory.class));
    140     assertEquals(builder, builder.loadBalancerFactory(null));
    141     assertEquals(defaultValue, builder.loadBalancerFactory);
    142   }
    143 
    144   @Test(expected = IllegalStateException.class)
    145   public void loadBalancerFactory_notAllowedWithDirectAddress() {
    146     directAddressBuilder.loadBalancerFactory(mock(LoadBalancer.Factory.class));
    147   }
    148 
    149   @Test
    150   public void fullStreamDecompression_default() {
    151     assertFalse(builder.fullStreamDecompression);
    152   }
    153 
    154   @Test
    155   public void fullStreamDecompression_enabled() {
    156     assertEquals(builder, builder.enableFullStreamDecompression());
    157     assertTrue(builder.fullStreamDecompression);
    158   }
    159 
    160   @Test
    161   public void decompressorRegistry_default() {
    162     assertNotNull(builder.decompressorRegistry);
    163   }
    164 
    165   @Test
    166   public void decompressorRegistry_normal() {
    167     DecompressorRegistry decompressorRegistry = DecompressorRegistry.emptyInstance();
    168     assertNotEquals(decompressorRegistry, builder.decompressorRegistry);
    169     assertEquals(builder, builder.decompressorRegistry(decompressorRegistry));
    170     assertEquals(decompressorRegistry, builder.decompressorRegistry);
    171   }
    172 
    173   @Test
    174   public void decompressorRegistry_null() {
    175     DecompressorRegistry defaultValue = builder.decompressorRegistry;
    176     assertEquals(builder, builder.decompressorRegistry(DecompressorRegistry.emptyInstance()));
    177     assertNotEquals(defaultValue, builder.decompressorRegistry);
    178     builder.decompressorRegistry(null);
    179     assertEquals(defaultValue, builder.decompressorRegistry);
    180   }
    181 
    182   @Test
    183   public void compressorRegistry_default() {
    184     assertNotNull(builder.compressorRegistry);
    185   }
    186 
    187   @Test
    188   public void compressorRegistry_normal() {
    189     CompressorRegistry compressorRegistry = CompressorRegistry.newEmptyInstance();
    190     assertNotEquals(compressorRegistry, builder.compressorRegistry);
    191     assertEquals(builder, builder.compressorRegistry(compressorRegistry));
    192     assertEquals(compressorRegistry, builder.compressorRegistry);
    193   }
    194 
    195   @Test
    196   public void compressorRegistry_null() {
    197     CompressorRegistry defaultValue = builder.compressorRegistry;
    198     builder.compressorRegistry(CompressorRegistry.newEmptyInstance());
    199     assertNotEquals(defaultValue, builder.compressorRegistry);
    200     assertEquals(builder, builder.compressorRegistry(null));
    201     assertEquals(defaultValue, builder.compressorRegistry);
    202   }
    203 
    204   @Test
    205   public void userAgent_default() {
    206     assertNull(builder.userAgent);
    207   }
    208 
    209   @Test
    210   public void userAgent_normal() {
    211     String userAgent = "user-agent/1";
    212     assertEquals(builder, builder.userAgent(userAgent));
    213     assertEquals(userAgent, builder.userAgent);
    214   }
    215 
    216   @Test
    217   public void userAgent_null() {
    218     assertEquals(builder, builder.userAgent(null));
    219     assertNull(builder.userAgent);
    220 
    221     builder.userAgent("user-agent/1");
    222     builder.userAgent(null);
    223     assertNull(builder.userAgent);
    224   }
    225 
    226   @Test
    227   public void overrideAuthority_default() {
    228     assertNull(builder.authorityOverride);
    229   }
    230 
    231   @Test
    232   public void overrideAuthority_normal() {
    233     String overrideAuthority = "best-authority";
    234     assertEquals(builder, builder.overrideAuthority(overrideAuthority));
    235     assertEquals(overrideAuthority, builder.authorityOverride);
    236   }
    237 
    238   @Test(expected = NullPointerException.class)
    239   public void overrideAuthority_null() {
    240     builder.overrideAuthority(null);
    241   }
    242 
    243   @Test(expected = IllegalArgumentException.class)
    244   public void overrideAuthority_invalid() {
    245     builder.overrideAuthority("not_allowed");
    246   }
    247 
    248   @Test
    249   public void overrideAuthority_getNameResolverFactory() {
    250     Builder builder = new Builder("target");
    251     assertNull(builder.authorityOverride);
    252     assertFalse(builder.getNameResolverFactory() instanceof OverrideAuthorityNameResolverFactory);
    253     builder.overrideAuthority("google.com");
    254     assertTrue(builder.getNameResolverFactory() instanceof OverrideAuthorityNameResolverFactory);
    255   }
    256 
    257   @Test
    258   public void makeTargetStringForDirectAddress_scopedIpv6() throws Exception {
    259     InetSocketAddress address = new InetSocketAddress("0:0:0:0:0:0:0:0%0", 10005);
    260     assertEquals("/0:0:0:0:0:0:0:0%0:10005", address.toString());
    261     String target = AbstractManagedChannelImplBuilder.makeTargetStringForDirectAddress(address);
    262     URI uri = new URI(target);
    263     assertEquals("directaddress:////0:0:0:0:0:0:0:0%250:10005", target);
    264     assertEquals(target, uri.toString());
    265   }
    266 
    267   @Test
    268   public void getEffectiveInterceptors_default() {
    269     builder.intercept(DUMMY_USER_INTERCEPTOR);
    270     List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
    271     assertEquals(3, effectiveInterceptors.size());
    272     assertThat(effectiveInterceptors.get(0))
    273         .isInstanceOf(CensusTracingModule.TracingClientInterceptor.class);
    274     assertThat(effectiveInterceptors.get(1))
    275         .isInstanceOf(CensusStatsModule.StatsClientInterceptor.class);
    276     assertThat(effectiveInterceptors.get(2)).isSameAs(DUMMY_USER_INTERCEPTOR);
    277   }
    278 
    279   @Test
    280   public void getEffectiveInterceptors_disableStats() {
    281     builder.intercept(DUMMY_USER_INTERCEPTOR);
    282     builder.setStatsEnabled(false);
    283     List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
    284     assertEquals(2, effectiveInterceptors.size());
    285     assertThat(effectiveInterceptors.get(0))
    286         .isInstanceOf(CensusTracingModule.TracingClientInterceptor.class);
    287     assertThat(effectiveInterceptors.get(1)).isSameAs(DUMMY_USER_INTERCEPTOR);
    288   }
    289 
    290   @Test
    291   public void getEffectiveInterceptors_disableTracing() {
    292     builder.intercept(DUMMY_USER_INTERCEPTOR);
    293     builder.setTracingEnabled(false);
    294     List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
    295     assertEquals(2, effectiveInterceptors.size());
    296     assertThat(effectiveInterceptors.get(0))
    297         .isInstanceOf(CensusStatsModule.StatsClientInterceptor.class);
    298     assertThat(effectiveInterceptors.get(1)).isSameAs(DUMMY_USER_INTERCEPTOR);
    299   }
    300 
    301   @Test
    302   public void getEffectiveInterceptors_disableBoth() {
    303     builder.intercept(DUMMY_USER_INTERCEPTOR);
    304     builder.setStatsEnabled(false);
    305     builder.setTracingEnabled(false);
    306     List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
    307     assertThat(effectiveInterceptors).containsExactly(DUMMY_USER_INTERCEPTOR);
    308   }
    309 
    310   @Test
    311   public void idleTimeout() {
    312     Builder builder = new Builder("target");
    313 
    314     assertEquals(AbstractManagedChannelImplBuilder.IDLE_MODE_DEFAULT_TIMEOUT_MILLIS,
    315         builder.getIdleTimeoutMillis());
    316 
    317     builder.idleTimeout(Long.MAX_VALUE, TimeUnit.DAYS);
    318     assertEquals(ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis());
    319 
    320     builder.idleTimeout(AbstractManagedChannelImplBuilder.IDLE_MODE_MAX_TIMEOUT_DAYS,
    321         TimeUnit.DAYS);
    322     assertEquals(ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis());
    323 
    324     try {
    325       builder.idleTimeout(0, TimeUnit.SECONDS);
    326       fail("Should throw");
    327     } catch (IllegalArgumentException e) {
    328       // expected
    329     }
    330 
    331     builder.idleTimeout(1, TimeUnit.NANOSECONDS);
    332     assertEquals(AbstractManagedChannelImplBuilder.IDLE_MODE_MIN_TIMEOUT_MILLIS,
    333         builder.getIdleTimeoutMillis());
    334 
    335     builder.idleTimeout(30, TimeUnit.SECONDS);
    336     assertEquals(TimeUnit.SECONDS.toMillis(30), builder.getIdleTimeoutMillis());
    337   }
    338 
    339   @Test
    340   public void maxRetryAttempts() {
    341     Builder builder = new Builder("target");
    342     assertEquals(5, builder.maxRetryAttempts);
    343 
    344     builder.maxRetryAttempts(3);
    345     assertEquals(3, builder.maxRetryAttempts);
    346   }
    347 
    348   @Test
    349   public void maxHedgedAttempts() {
    350     Builder builder = new Builder("target");
    351     assertEquals(5, builder.maxHedgedAttempts);
    352 
    353     builder.maxHedgedAttempts(3);
    354     assertEquals(3, builder.maxHedgedAttempts);
    355   }
    356 
    357   @Test
    358   public void retryBufferSize() {
    359     Builder builder = new Builder("target");
    360     assertEquals(1L << 24, builder.retryBufferSize);
    361 
    362     builder.retryBufferSize(3456L);
    363     assertEquals(3456L, builder.retryBufferSize);
    364   }
    365 
    366   @Test
    367   public void perRpcBufferLimit() {
    368     Builder builder = new Builder("target");
    369     assertEquals(1L << 20, builder.perRpcBufferLimit);
    370 
    371     builder.perRpcBufferLimit(3456L);
    372     assertEquals(3456L, builder.perRpcBufferLimit);
    373   }
    374 
    375   @Test
    376   public void retryBufferSizeInvalidArg() {
    377     Builder builder = new Builder("target");
    378 
    379     thrown.expect(IllegalArgumentException.class);
    380     builder.retryBufferSize(0L);
    381   }
    382 
    383   @Test
    384   public void perRpcBufferLimitInvalidArg() {
    385     Builder builder = new Builder("target");
    386 
    387     thrown.expect(IllegalArgumentException.class);
    388     builder.perRpcBufferLimit(0L);
    389   }
    390 
    391   @Test
    392   public void disableRetry() {
    393     Builder builder = new Builder("target");
    394 
    395     builder.enableRetry();
    396     assertTrue(builder.retryEnabled);
    397 
    398     builder.disableRetry();
    399     assertFalse(builder.retryEnabled);
    400 
    401     builder.enableRetry();
    402     assertTrue(builder.retryEnabled);
    403 
    404     builder.disableRetry();
    405     assertFalse(builder.retryEnabled);
    406   }
    407 
    408   static class Builder extends AbstractManagedChannelImplBuilder<Builder> {
    409     Builder(String target) {
    410       super(target);
    411       overrideCensusStatsModule(
    412           new CensusStatsModule(
    413               new FakeTagger(),
    414               new FakeTagContextBinarySerializer(),
    415               new FakeStatsRecorder(),
    416               GrpcUtil.STOPWATCH_SUPPLIER,
    417               true));
    418     }
    419 
    420     Builder(SocketAddress directServerAddress, String authority) {
    421       super(directServerAddress, authority);
    422       overrideCensusStatsModule(
    423           new CensusStatsModule(
    424               new FakeTagger(),
    425               new FakeTagContextBinarySerializer(),
    426               new FakeStatsRecorder(),
    427               GrpcUtil.STOPWATCH_SUPPLIER,
    428               true));
    429     }
    430 
    431     @Override
    432     protected ClientTransportFactory buildTransportFactory() {
    433       throw new UnsupportedOperationException();
    434     }
    435   }
    436 }
    437