/* * Copyright Terracotta, 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 org.ehcache.clustered.client.internal.store; import org.ehcache.clustered.client.config.ClusteredResourceType; import org.ehcache.clustered.client.config.DedicatedClusteredResourcePool; import org.ehcache.clustered.client.internal.config.DedicatedClusteredResourcePoolImpl; import org.ehcache.clustered.client.service.ClusteringService; import org.ehcache.config.Eviction; import org.ehcache.config.EvictionAdvisor; import org.ehcache.config.ResourcePool; import org.ehcache.config.ResourcePools; import org.ehcache.config.ResourceType; import org.ehcache.config.units.MemoryUnit; import org.ehcache.core.config.ResourcePoolsImpl; import org.ehcache.core.internal.service.ServiceLocator; import org.ehcache.core.spi.service.DiskResourceService; import org.ehcache.core.spi.store.Store; import org.ehcache.expiry.Expirations; import org.ehcache.expiry.Expiry; import org.ehcache.impl.internal.store.disk.OffHeapDiskStore; import org.ehcache.impl.internal.store.heap.OnHeapStore; import org.ehcache.impl.internal.store.offheap.OffHeapStore; import org.ehcache.impl.internal.store.tiering.TieredStore; import org.ehcache.impl.serialization.LongSerializer; import org.ehcache.impl.serialization.StringSerializer; import org.ehcache.spi.serialization.Serializer; import org.ehcache.spi.service.ServiceConfiguration; import org.junit.Test; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import static org.ehcache.core.internal.service.ServiceLocator.dependencySet; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; /** * Provides basic tests for {@link org.ehcache.clustered.client.internal.store.ClusteredStore.Provider ClusteredStore.Provider}. */ public class ClusteredStoreProviderTest { @Test public void testRank() throws Exception { ClusteredStore.Provider provider = new ClusteredStore.Provider(); ServiceLocator serviceLocator = dependencySet() .with(new TieredStore.Provider()) .with(new OnHeapStore.Provider()) .with(new OffHeapStore.Provider()) .with(mock(DiskResourceService.class)) .with(new OffHeapDiskStore.Provider()) .with(mock(ClusteringService.class)).build(); provider.start(serviceLocator); assertRank(provider, 1, ClusteredResourceType.Types.DEDICATED); assertRank(provider, 1, ClusteredResourceType.Types.SHARED); assertRank(provider, 0, new UnmatchedResourceType()); } @Test public void testRankTiered() throws Exception { TieredStore.Provider provider = new TieredStore.Provider(); ServiceLocator serviceLocator = dependencySet() .with(provider) .with(new ClusteredStore.Provider()) .with(new OnHeapStore.Provider()) .with(new OffHeapStore.Provider()) .with(new OffHeapDiskStore.Provider()) .with(mock(DiskResourceService.class)) .with(mock(ClusteringService.class)).build(); serviceLocator.startAllServices(); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.DISK); assertRank(provider, 2, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.DISK, ResourceType.Core.HEAP); assertRank(provider, 3, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK); assertRank(provider, 2, ClusteredResourceType.Types.SHARED, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.SHARED, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.HEAP); assertRank(provider, 3, ClusteredResourceType.Types.SHARED, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); // Multiple clustered resources not currently supported assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); assertRank(provider, 0, ClusteredResourceType.Types.DEDICATED, ClusteredResourceType.Types.SHARED, ResourceType.Core.DISK, ResourceType.Core.OFFHEAP, ResourceType.Core.HEAP); } @Test public void testAuthoritativeRank() throws Exception { ClusteredStore.Provider provider = new ClusteredStore.Provider(); ServiceLocator serviceLocator = dependencySet().with(mock(ClusteringService.class)).build(); provider.start(serviceLocator); assertThat(provider.rankAuthority(ClusteredResourceType.Types.DEDICATED, Collections.<ServiceConfiguration<?>>emptyList()), is(1)); assertThat(provider.rankAuthority(ClusteredResourceType.Types.SHARED, Collections.<ServiceConfiguration<?>>emptyList()), is(1)); assertThat(provider.rankAuthority(new UnmatchedResourceType(), Collections.<ServiceConfiguration<?>>emptyList()), is(0)); } private void assertRank(final Store.Provider provider, final int expectedRank, final ResourceType<?>... resources) { final List<ServiceConfiguration<?>> serviceConfigs = Collections.emptyList(); if (expectedRank == -1) { try { provider.rank(new HashSet<ResourceType<?>>(Arrays.asList(resources)), serviceConfigs); fail(); } catch (IllegalStateException e) { // Expected assertThat(e.getMessage(), startsWith("No Store.Provider ")); } } else { assertThat(provider.rank(new HashSet<ResourceType<?>>(Arrays.asList(resources)), serviceConfigs), is(expectedRank)); } } private Store.Configuration<Long, String> getStoreConfig() { return new Store.Configuration<Long, String>() { @Override public Class<Long> getKeyType() { return Long.class; } @Override public Class<String> getValueType() { return String.class; } @Override public EvictionAdvisor<? super Long, ? super String> getEvictionAdvisor() { return Eviction.noAdvice(); } @Override public ClassLoader getClassLoader() { return getClass().getClassLoader(); } @Override public Expiry<? super Long, ? super String> getExpiry() { return Expirations.noExpiration(); } @Override @SuppressWarnings("unchecked") public ResourcePools getResourcePools() { Map<ClusteredResourceType<DedicatedClusteredResourcePool>, DedicatedClusteredResourcePoolImpl> poolMap = Collections .singletonMap(ClusteredResourceType.Types.DEDICATED, new DedicatedClusteredResourcePoolImpl("test", 10, MemoryUnit.MB)); return new ResourcePoolsImpl((Map) poolMap); } @Override public Serializer<Long> getKeySerializer() { return new LongSerializer(); } @Override public Serializer<String> getValueSerializer() { return new StringSerializer(); } @Override public int getDispatcherConcurrency() { return 1; } }; } private static class UnmatchedResourceType implements ResourceType<ResourcePool> { @Override public Class<ResourcePool> getResourcePoolClass() { return ResourcePool.class; } @Override public boolean isPersistable() { return true; } @Override public boolean requiresSerialization() { return true; } @Override public int getTierHeight() { return 10; } } }