/* * Copyright (c) 2016 Couchbase, Inc. * * 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 com.couchbase.client.core.config; import com.couchbase.client.core.ClusterFacade; import com.couchbase.client.core.config.loader.Loader; import com.couchbase.client.core.config.refresher.CarrierRefresher; import com.couchbase.client.core.config.refresher.HttpRefresher; import com.couchbase.client.core.config.refresher.Refresher; import com.couchbase.client.core.env.CoreEnvironment; import com.couchbase.client.core.env.DefaultCoreEnvironment; import com.couchbase.client.core.env.NetworkResolution; import com.couchbase.client.core.lang.Tuple; import com.couchbase.client.core.lang.Tuple2; import com.couchbase.client.core.util.Resources; import org.junit.AfterClass; import org.junit.Test; import org.mockito.internal.util.collections.Sets; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import rx.Observable; import rx.functions.Action1; import rx.functions.Func1; import rx.observers.TestSubscriber; import rx.subjects.AsyncSubject; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Verifies the correct functionality of the {@link DefaultConfigurationProvider}. * * @author Michael Nitschinger * @since 1.0 */ public class DefaultConfigurationProviderTest { private static final CoreEnvironment environment = DefaultCoreEnvironment.create(); @AfterClass public static void cleanup() { environment.shutdown(); } @Test @SuppressWarnings("unchecked") public void shouldOpenBucket() { ClusterFacade cluster = mock(ClusterFacade.class); Loader loader = mock(Loader.class); BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket"); when(loader.loadConfig(any(String.class), anyString(), anyString(), anyString())) .thenReturn(Observable.just(Tuple.create(LoaderType.Carrier, bucketConfig))); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); provider.seedHosts(Sets.newSet("127.0.0.1"), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertTrue(config.hasBucket("bucket")); assertFalse(config.hasBucket("other")); } @Test @SuppressWarnings("unchecked") public void shouldDelegateLoadingToSecondProviderIfFirstFails() throws Exception { ClusterFacade cluster = mock(ClusterFacade.class); Loader successLoader = mock(Loader.class); Loader errorLoader = mock(Loader.class); BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket"); when(successLoader.loadConfig(any(String.class), anyString(), anyString(), anyString())) .thenReturn(Observable.just(Tuple.create(LoaderType.Carrier, bucketConfig))); AsyncSubject<BucketConfig> errorSubject = AsyncSubject.create(); when(errorLoader.loadConfig(any(String.class), anyString(), anyString(), anyString())).thenReturn((Observable) errorSubject); errorSubject.onError(new IllegalStateException()); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(errorLoader, successLoader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); put(LoaderType.HTTP, refresher); }} ); provider.seedHosts(Sets.newSet("127.0.0.1"), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertTrue(config.hasBucket("bucket")); assertFalse(config.hasBucket("other")); } @Test public void shouldOpenBucketIfSubsetOfNodesIsFailing() throws Exception { ClusterFacade cluster = mock(ClusterFacade.class); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); Loader carrierLoader = mock(Loader.class); Loader httpLoader = mock(Loader.class); final String goodNode = "5.6.7.8"; String badNode = "1.2.3.4"; when(carrierLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { String target = (String) in.getArguments()[0]; if (target.equals(goodNode)) { final BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket-carrier-"+target); return Observable.just(Tuple.create(LoaderType.Carrier, bucketConfig)); } else { return Observable.error(new Exception("Could not load config for some reason.")); } } }); when(httpLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { String target = (String) in.getArguments()[0]; if (target.equals(goodNode)) { final BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket-http-"+target); return Observable.just(Tuple.create(LoaderType.HTTP, bucketConfig)); } else { return Observable.error(new Exception("Could not load config for some reason.")); } } }); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(carrierLoader, httpLoader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); put(LoaderType.HTTP, refresher); }} ); provider.seedHosts(Sets.newSet(badNode, goodNode), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertEquals(1, config.bucketConfigs().size()); assertTrue(config.hasBucket("bucket-carrier-" + goodNode)); } @Test public void shouldOpenBucketIfSubsetOfNodesIsFailingAndOnlyHttpAvailable() throws Exception { ClusterFacade cluster = mock(ClusterFacade.class); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); Loader carrierLoader = mock(Loader.class); Loader httpLoader = mock(Loader.class); final String goodNode = "5.6.7.8"; String badNode = "1.2.3.4"; when(carrierLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { return Observable.error(new Exception("Could not load config for some reason.")); } }); when(httpLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { String target = (String) in.getArguments()[0]; if (target.equals(goodNode)) { final BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket-http-"+target); return Observable.just(Tuple.create(LoaderType.HTTP, bucketConfig)); } else { return Observable.error(new Exception("Could not load config for some reason.")); } } }); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(carrierLoader, httpLoader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); put(LoaderType.HTTP, refresher); }} ); provider.seedHosts(Sets.newSet(badNode, goodNode), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertEquals(1, config.bucketConfigs().size()); assertTrue(config.hasBucket("bucket-http-" + goodNode)); } @Test public void shouldOpenBucketIfSubsetOfNodesIsNotResponding() throws Exception { ClusterFacade cluster = mock(ClusterFacade.class); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); Loader carrierLoader = mock(Loader.class); Loader httpLoader = mock(Loader.class); final String goodNode = "5.6.7.8"; String badNode = "1.2.3.4"; when(carrierLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { String target = (String) in.getArguments()[0]; if (target.equals(goodNode)) { final BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket-carrier-"+target); return Observable.just(Tuple.create(LoaderType.Carrier, bucketConfig)); } else { return Observable.timer(1, TimeUnit.MINUTES).map(new Func1<Long, Tuple2<LoaderType, BucketConfig>>() { @Override public Tuple2<LoaderType, BucketConfig> call(Long aLong) { throw new RuntimeException("Could not load config for some reason."); } }); } } }); when(httpLoader.loadConfig(any(String.class), any(String.class), any(String.class), any(String.class))) .thenAnswer(new Answer<Observable<Tuple2<LoaderType, BucketConfig>>>() { @Override public Observable<Tuple2<LoaderType, BucketConfig>> answer(InvocationOnMock in) throws Throwable { String target = (String) in.getArguments()[0]; if (target.equals(goodNode)) { final BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket-http-"+target); return Observable.just(Tuple.create(LoaderType.HTTP, bucketConfig)); } else { return Observable.timer(1, TimeUnit.MINUTES).map(new Func1<Long, Tuple2<LoaderType, BucketConfig>>() { @Override public Tuple2<LoaderType, BucketConfig> call(Long aLong) { throw new RuntimeException("Could not load config for some reason."); } }); } } }); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(carrierLoader, httpLoader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); put(LoaderType.HTTP, refresher); }} ); provider.seedHosts(Sets.newSet(badNode, goodNode), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertEquals(1, config.bucketConfigs().size()); assertTrue(config.hasBucket("bucket-carrier-" + goodNode)); } @Test public void shouldEmitNewClusterConfig() throws Exception { final ClusterFacade cluster = mock(ClusterFacade.class); Loader loader = mock(Loader.class); BucketConfig bucketConfig = mock(BucketConfig.class); when(bucketConfig.name()).thenReturn("bucket"); when(loader.loadConfig(any(String.class), anyString(), anyString(), anyString())) .thenReturn(Observable.just(Tuple.create(LoaderType.Carrier, bucketConfig))); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), nullable(String.class), nullable(String.class))).thenReturn(Observable.just(true)); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference<ClusterConfig> configReference = new AtomicReference<ClusterConfig>(); provider.configs().subscribe(new Action1<ClusterConfig>() { @Override public void call(ClusterConfig clusterConfig) { configReference.set(clusterConfig); latch.countDown(); } }); provider.seedHosts(Sets.newSet("127.0.0.1"), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); ClusterConfig config = configObservable.toBlocking().first(); assertTrue(config.hasBucket("bucket")); assertFalse(config.hasBucket("other")); assertTrue(latch.await(2, TimeUnit.SECONDS)); assertEquals(configReference.get(), config); } @SuppressWarnings("unchecked") @Test public void shouldFailOpeningBucketIfNoConfigLoaded() throws Exception { ClusterFacade cluster = mock(ClusterFacade.class); Loader errorLoader = mock(Loader.class); AsyncSubject<Tuple2<LoaderType, BucketConfig>> errorSubject = AsyncSubject.create(); when(errorLoader.loadConfig(any(String.class), anyString(), anyString(), anyString())).thenReturn(errorSubject); errorSubject.onError(new IllegalStateException()); final Refresher refresher = mock(Refresher.class); when(refresher.configs()).thenReturn(Observable.<ProposedBucketConfigContext>empty()); when(refresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, environment, Arrays.asList(errorLoader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); provider.seedHosts(Sets.newSet("127.0.0.1"), true); Observable<ClusterConfig> configObservable = provider.openBucket("bucket", "password"); try { configObservable.toBlocking().single(); assertTrue(false); } catch(ConfigurationException ex) { assertEquals("Could not open bucket.", ex.getMessage()); } catch(Exception ex) { assertTrue(false); } } @Test public void shouldAcceptProposedConfigIfNoneExists() { DefaultConfigurationProvider provider = new DefaultConfigurationProvider( mock(ClusterFacade.class), environment ); Set<String> seeds = new HashSet<String>(Arrays.asList("127.0.0.1")); provider.seedHosts(seeds, true); assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_rev_placeholder.json", getClass()); raw = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", raw, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(1, provider.config().bucketConfig("default").rev()); } @Test public void shouldAcceptProposedConfigIfNewer() { DefaultConfigurationProvider provider = new DefaultConfigurationProvider( mock(ClusterFacade.class), environment ); Set<String> seeds = new HashSet<String>(Arrays.asList("127.0.0.1")); provider.seedHosts(seeds, true); String raw = Resources.read("config_with_rev_placeholder.json", getClass()); String v1 = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v1, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(1, provider.config().bucketConfig("default").rev()); String v2 = raw.replace("$REV", "2"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v2, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(2, provider.config().bucketConfig("default").rev()); } @Test public void shouldIgnoreConfigIfInvalid() { DefaultConfigurationProvider provider = new DefaultConfigurationProvider( mock(ClusterFacade.class), environment ); Set<String> seeds = new HashSet<String>(Arrays.asList("127.0.0.1")); provider.seedHosts(seeds, true); assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_rev_placeholder.json", getClass()); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", raw, null)); assertTrue(provider.config().bucketConfigs().isEmpty()); String v1 = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v1, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", raw, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); String v2 = raw.replace("$REV", "2"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v2, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(2, provider.config().bucketConfig("default").rev()); } @Test public void shouldIgnoreConfigIfOlder() { DefaultConfigurationProvider provider = new DefaultConfigurationProvider( mock(ClusterFacade.class), environment ); Set<String> seeds = new HashSet<String>(Arrays.asList("127.0.0.1")); provider.seedHosts(seeds, true); String raw = Resources.read("config_with_rev_placeholder.json", getClass()); String v2 = raw.replace("$REV", "2"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v2, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(2, provider.config().bucketConfig("default").rev()); String v1 = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v1, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(2, provider.config().bucketConfig("default").rev()); } @Test public void shouldIgnoreConfigIfSameRev() throws Exception { DefaultConfigurationProvider provider = new DefaultConfigurationProvider( mock(ClusterFacade.class), environment ); Set<String> seeds = new HashSet<String>(Arrays.asList("127.0.0.1")); provider.seedHosts(seeds, true); TestSubscriber<ClusterConfig> subscriber = new TestSubscriber<ClusterConfig>(); provider.configs().subscribe(subscriber); String raw = Resources.read("config_with_rev_placeholder.json", getClass()); String v1 = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v1, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(1, provider.config().bucketConfig("default").rev()); String v2 = raw.replace("$REV", "1"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v2, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(1, provider.config().bucketConfig("default").rev()); String v3 = raw.replace("$REV", "2"); provider.proposeBucketConfig(new ProposedBucketConfigContext("default", v3, null)); assertFalse(provider.config().bucketConfigs().isEmpty()); assertEquals(2, provider.config().bucketConfig("default").rev()); Thread.sleep(100); assertEquals(2, subscriber.getOnNextEvents().size()); } @Test public void shouldForcePickServerDefault() { ClusterFacade cluster = mock(ClusterFacade.class); final Loader loader = mock(Loader.class); final Refresher refresher = mock(Refresher.class); final CoreEnvironment env = mock(CoreEnvironment.class); when(env.networkResolution()).thenReturn(NetworkResolution.DEFAULT); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, env, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); // No configs available assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_external.json", getClass()); provider.proposeBucketConfig(new ProposedBucketConfigContext("bucket", raw, null)); assertNull(provider.config().bucketConfig("default").useAlternateNetwork()); } @Test public void shouldForcePickExternal() { ClusterFacade cluster = mock(ClusterFacade.class); final Loader loader = mock(Loader.class); final Refresher refresher = mock(Refresher.class); final CoreEnvironment env = mock(CoreEnvironment.class); when(env.networkResolution()).thenReturn(NetworkResolution.EXTERNAL); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, env, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); // No configs available assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_external.json", getClass()); provider.proposeBucketConfig(new ProposedBucketConfigContext("bucket", raw, null)); assertNotNull(provider.config().bucketConfig("default").useAlternateNetwork()); } @Test public void shouldAutoPickExternal() { ClusterFacade cluster = mock(ClusterFacade.class); final Loader loader = mock(Loader.class); final Refresher refresher = mock(Refresher.class); final CoreEnvironment env = mock(CoreEnvironment.class); when(env.networkResolution()).thenReturn(NetworkResolution.AUTO); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, env, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); Set<String> seeds = new HashSet<String>(); seeds.add("192.168.132.234"); provider.seedHosts(seeds, true); // No configs available assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_external.json", getClass()); provider.proposeBucketConfig(new ProposedBucketConfigContext("bucket", raw, null)); assertNotNull(provider.config().bucketConfig("default").useAlternateNetwork()); } @Test public void shouldAutoPickServerDefault() { ClusterFacade cluster = mock(ClusterFacade.class); final Loader loader = mock(Loader.class); final Refresher refresher = mock(Refresher.class); final CoreEnvironment env = mock(CoreEnvironment.class); when(env.networkResolution()).thenReturn(NetworkResolution.AUTO); ConfigurationProvider provider = new DefaultConfigurationProvider( cluster, env, Arrays.asList(loader), new HashMap<LoaderType, Refresher>() {{ put(LoaderType.Carrier, refresher); }} ); Set<String> seeds = new HashSet<String>(Arrays.asList("172.17.0.3")); provider.seedHosts(seeds, true); // No configs available assertTrue(provider.config().bucketConfigs().isEmpty()); String raw = Resources.read("config_with_external.json", getClass()); provider.proposeBucketConfig(new ProposedBucketConfigContext("bucket", raw, null)); assertNull(provider.config().bucketConfig("default").useAlternateNetwork()); } @Test public void shouldSelectCarrierRefresherIfCarrierLoader() { Refresher carrierRefresher = mock(CarrierRefresher.class); when(carrierRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Refresher httpRefresher = mock(HttpRefresher.class); when(httpRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Map<LoaderType, Refresher> refreshers = new HashMap<>(); refreshers.put(LoaderType.Carrier, carrierRefresher); refreshers.put(LoaderType.HTTP, httpRefresher); LoaderType loaderType = LoaderType.Carrier; BucketConfig config = mock(CouchbaseBucketConfig.class); when(config.name()).thenReturn("default"); when(config.username()).thenReturn("user"); when(config.password()).thenReturn("pass"); DefaultConfigurationProvider.registerBucketForRefresh(refreshers, loaderType, config); verify(carrierRefresher, times(1)) .registerBucket("default", "user", "pass"); verify(httpRefresher, never()) .registerBucket("default", "user", "pass"); } @Test public void shouldSelectCarrierRefresherIfHttpLoader() { Refresher carrierRefresher = mock(CarrierRefresher.class); when(carrierRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Refresher httpRefresher = mock(HttpRefresher.class); when(httpRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Map<LoaderType, Refresher> refreshers = new HashMap<>(); refreshers.put(LoaderType.Carrier, carrierRefresher); refreshers.put(LoaderType.HTTP, httpRefresher); LoaderType loaderType = LoaderType.HTTP; BucketConfig config = mock(CouchbaseBucketConfig.class); when(config.name()).thenReturn("default"); when(config.username()).thenReturn("user"); when(config.password()).thenReturn("pass"); when(config.capabilities()).thenReturn(Collections.singletonList(BucketCapabilities.NODES_EXT)); DefaultConfigurationProvider.registerBucketForRefresh(refreshers, loaderType, config); verify(carrierRefresher, times(1)) .registerBucket("default", "user", "pass"); verify(httpRefresher, never()) .registerBucket("default", "user", "pass"); } @Test public void shouldSelectHttpRefresherForMemcacheBucket() { Refresher carrierRefresher = mock(CarrierRefresher.class); when(carrierRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Refresher httpRefresher = mock(HttpRefresher.class); when(httpRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Map<LoaderType, Refresher> refreshers = new HashMap<>(); refreshers.put(LoaderType.Carrier, carrierRefresher); refreshers.put(LoaderType.HTTP, httpRefresher); LoaderType loaderType = LoaderType.HTTP; BucketConfig config = mock(MemcachedBucketConfig.class); when(config.name()).thenReturn("default"); when(config.username()).thenReturn("user"); when(config.password()).thenReturn("pass"); when(config.capabilities()).thenReturn(Collections.singletonList(BucketCapabilities.NODES_EXT)); DefaultConfigurationProvider.registerBucketForRefresh(refreshers, loaderType, config); verify(carrierRefresher, never()) .registerBucket("default", "user", "pass"); verify(httpRefresher, times(1)) .registerBucket("default", "user", "pass"); } @Test public void shouldSelectHttpRefresherForOldCluster() { Refresher carrierRefresher = mock(CarrierRefresher.class); when(carrierRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Refresher httpRefresher = mock(HttpRefresher.class); when(httpRefresher.registerBucket(anyString(), anyString(), anyString())).thenReturn(Observable.just(true)); Map<LoaderType, Refresher> refreshers = new HashMap<>(); refreshers.put(LoaderType.Carrier, carrierRefresher); refreshers.put(LoaderType.HTTP, httpRefresher); LoaderType loaderType = LoaderType.HTTP; BucketConfig config = mock(CouchbaseBucketConfig.class); when(config.name()).thenReturn("default"); when(config.username()).thenReturn("user"); when(config.password()).thenReturn("pass"); when(config.capabilities()).thenReturn(Collections.<BucketCapabilities>emptyList()); DefaultConfigurationProvider.registerBucketForRefresh(refreshers, loaderType, config); verify(carrierRefresher, never()) .registerBucket("default", "user", "pass"); verify(httpRefresher, times(1)) .registerBucket("default", "user", "pass"); } }