package com.netflix.discovery.shared.resolver; import com.netflix.discovery.shared.resolver.aws.SampleCluster; import com.netflix.discovery.shared.transport.EurekaTransportConfig; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * @author David Liu */ public class AsyncResolverTest { private final EurekaTransportConfig transportConfig = mock(EurekaTransportConfig.class); private final ClusterResolver delegateResolver = mock(ClosableResolver.class); private AsyncResolver resolver; @Before public void setUp() { when(transportConfig.getAsyncExecutorThreadPoolSize()).thenReturn(3); when(transportConfig.getAsyncResolverRefreshIntervalMs()).thenReturn(200); when(transportConfig.getAsyncResolverWarmUpTimeoutMs()).thenReturn(100); resolver = spy(new AsyncResolver( "test", delegateResolver, transportConfig.getAsyncExecutorThreadPoolSize(), transportConfig.getAsyncResolverRefreshIntervalMs(), transportConfig.getAsyncResolverWarmUpTimeoutMs() )); } @After public void shutDown() { resolver.shutdown(); } @Test public void testHappyCase() { List delegateReturns1 = new ArrayList(SampleCluster.UsEast1a.builder().withServerPool(2).build()); List delegateReturns2 = new ArrayList(SampleCluster.UsEast1b.builder().withServerPool(3).build()); when(delegateResolver.getClusterEndpoints()) .thenReturn(delegateReturns1) .thenReturn(delegateReturns2); List endpoints = resolver.getClusterEndpoints(); assertThat(endpoints.size(), equalTo(delegateReturns1.size())); verify(delegateResolver, times(1)).getClusterEndpoints(); verify(resolver, times(1)).doWarmUp(); // try again, should be async endpoints = resolver.getClusterEndpoints(); assertThat(endpoints.size(), equalTo(delegateReturns1.size())); verify(delegateResolver, times(1)).getClusterEndpoints(); verify(resolver, times(1)).doWarmUp(); // wait for the next async update cycle verify(delegateResolver, timeout(1000).times(2)).getClusterEndpoints(); endpoints = resolver.getClusterEndpoints(); assertThat(endpoints.size(), equalTo(delegateReturns2.size())); verify(delegateResolver, times(2)).getClusterEndpoints(); verify(resolver, times(1)).doWarmUp(); } @Test public void testDelegateFailureAtWarmUp() { when(delegateResolver.getClusterEndpoints()) .thenReturn(null); // override the scheduling which will be triggered immediately if warmUp fails (as is intended). // do this to avoid thread race conditions for a more predictable test doNothing().when(resolver).scheduleTask(anyLong()); List endpoints = resolver.getClusterEndpoints(); assertThat(endpoints.isEmpty(), is(true)); verify(delegateResolver, times(1)).getClusterEndpoints(); verify(resolver, times(1)).doWarmUp(); } }