/* * Copyright 2016 Ben Manes. All Rights Reserved. * * 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.github.benmanes.caffeine.jcache; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.integration.CacheLoader; import javax.cache.spi.CachingProvider; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.github.benmanes.caffeine.jcache.configuration.CaffeineConfiguration; import com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.testing.FakeTicker; /** * A testing harness for simplifying the unit tests. * * @author ben.manes@gmail.com (Ben Manes) */ @Test(singleThreaded = true) public abstract class AbstractJCacheTest { protected static final long START_TIME_MS = System.currentTimeMillis(); protected static final long EXPIRY_DURATION = TimeUnit.MINUTES.toMillis(1); protected static final Integer KEY_1 = 1, VALUE_1 = -1; protected static final Integer KEY_2 = 2, VALUE_2 = -2; protected static final Integer KEY_3 = 3, VALUE_3 = -3; protected final Set<Integer> keys = ImmutableSet.of(KEY_1, KEY_2, KEY_3); protected final Map<Integer, Integer> entries = ImmutableMap.of( KEY_1, VALUE_1, KEY_2, VALUE_2, KEY_3, VALUE_3); protected LoadingCacheProxy<Integer, Integer> jcacheLoading; protected CacheProxy<Integer, Integer> jcache; protected CacheManager cacheManager; protected FakeTicker ticker; @BeforeClass(alwaysRun = true) public void beforeClass() { CachingProvider provider = Caching.getCachingProvider(CaffeineCachingProvider.class.getName()); cacheManager = provider.getCacheManager( provider.getDefaultURI(), provider.getDefaultClassLoader()); } @BeforeMethod(alwaysRun = true) public void before() { ticker = new FakeTicker().advance(START_TIME_MS, TimeUnit.MILLISECONDS); jcache = (CacheProxy<Integer, Integer>) cacheManager.createCache("jcache", getConfiguration()); jcacheLoading = (LoadingCacheProxy<Integer, Integer>) cacheManager.createCache( "jcacheLoading", getLoadingConfiguration()); } @AfterMethod(alwaysRun = true) public void after() { cacheManager.destroyCache("jcache"); cacheManager.destroyCache("jcacheLoading"); } /** The base configuration used by the test. */ protected abstract CaffeineConfiguration<Integer, Integer> getConfiguration(); /* ---------------- Utility methods ------------- */ @Nullable protected static Expirable<Integer> getExpirable( CacheProxy<Integer, Integer> cache, Integer key) { return cache.cache.getIfPresent(key); } protected void advanceHalfExpiry() { ticker.advance(EXPIRY_DURATION / 2, TimeUnit.MILLISECONDS); } protected void advancePastExpiry() { ticker.advance(2 * EXPIRY_DURATION, TimeUnit.MILLISECONDS); } /** @return the current time in milliseconds */ protected final long currentTimeMillis() { return TimeUnit.NANOSECONDS.toMillis(ticker.read()); } /** The loading configuration used by the test. */ protected CaffeineConfiguration<Integer, Integer> getLoadingConfiguration() { CaffeineConfiguration<Integer, Integer> configuration = getConfiguration(); configuration.setCacheLoaderFactory(this::getCacheLoader); configuration.setReadThrough(true); return configuration; } /** The cache loader used by the test. */ protected CacheLoader<Integer, Integer> getCacheLoader() { return new CacheLoader<Integer, Integer>() { @Override public Integer load(Integer key) { return key; } @Override public Map<Integer, Integer> loadAll(Iterable<? extends Integer> keys) { return Maps.asMap(ImmutableSet.copyOf(keys), this::load); } }; } }