/* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.geowebcache.storage; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import java.io.InputStream; import org.geowebcache.io.ByteArrayResource; import org.geowebcache.io.Resource; import org.junit.Before; import org.junit.Test; import com.google.common.base.Ticker; /** * * @author Kevin Smith, Boundless * */ public class TransientCacheTest { TransientCache transCache; TestTicker ticker; final public static long EXPIRE_TIME = 2000; final public static int MAX_TILES = 5; final public static int MAX_SPACE_KiB = 5; @Before public void setUp() throws Exception { transCache = new TransientCache(MAX_TILES, MAX_SPACE_KiB, EXPIRE_TIME); ticker = new TestTicker(System.nanoTime()); transCache.setTicker(ticker); } @Test public void testHit() throws Exception { Resource r = new ByteArrayResource(new byte[]{1,2,3}); transCache.put("foo", r); ticker.advanceMilli(EXPIRE_TIME-1); Resource result = transCache.get("foo"); assertThat(result, notNullValue()); assertThat(r.getLastModified(), equalTo(r.getLastModified())); try (InputStream is = result.getInputStream();){ assertThat(is.read(), equalTo(1)); assertThat(is.read(), equalTo(2)); assertThat(is.read(), equalTo(3)); assertThat(is.read(), equalTo(-1)); } } @Test public void testRemoveOnHit() throws Exception { Resource r = new ByteArrayResource(new byte[]{1,2,3}); transCache.put("foo", r); ticker.advanceMilli(EXPIRE_TIME-1); transCache.get("foo"); // Hit Resource result = transCache.get("foo"); assertThat(result, nullValue()); // Should have been cleared } @Test public void testRemoveOnExpire() throws Exception { Resource r = new ByteArrayResource(new byte[]{1,2,3}); transCache.put("foo", r); ticker.advanceMilli(EXPIRE_TIME+1); Resource result = transCache.get("foo"); assertThat(result, nullValue()); // Should have expired } @Test public void testRemoveWhenMaxTiles() throws Exception { for (byte i = 0; i<MAX_TILES; i++) { Resource r = new ByteArrayResource(new byte[]{(byte)(i+1),(byte)(i+2),(byte)(i+3)}); transCache.put("foo"+i, r); assertThat(transCache.size(), is(i+1)); } assertThat(transCache.storageSize(), is((long)MAX_TILES*3)); Resource r = new ByteArrayResource(new byte[]{(byte)(MAX_TILES+1),(byte)(MAX_TILES+2)}); transCache.put("foo"+MAX_TILES, r); assertThat(transCache.size(), is(MAX_TILES)); assertThat(transCache.storageSize(), is((long)MAX_TILES*3-1)); // remove a 3 byte and add a 2 byte ticker.advanceMilli(1); Resource result1 = transCache.get("foo0"); assertThat(result1, nullValue()); // Should have expired Resource result2 = transCache.get("foo1"); assertThat(result2, notNullValue()); // Should still be cached } @Test public void testRemoveWhenMaxSpace() throws Exception { for (long i = 0; i<MAX_SPACE_KiB; i++) { Resource r = new ByteArrayResource(new byte[i==0?1023:1024]); // make the first one 1 byte less than a KiB transCache.put("foo"+i, r); assertThat(transCache.storageSize(), is((i+1)*1024-1)); // 1 KiB per resource, less a byte for the first ticker.advanceMilli(1); } assertThat(transCache.storageSize(), is((long)MAX_SPACE_KiB*1024-1)); // 1 KiB per resource, less a byte for the first assertThat(transCache.size(), is(MAX_SPACE_KiB)); Resource r = new ByteArrayResource(new byte[2]); // 2 bytes will go over the maximum transCache.put("foo"+MAX_SPACE_KiB, r); assertThat(transCache.storageSize(), is((long)(MAX_SPACE_KiB-1)*1024+2)); // 1 KiB for each of the resources except the first should be removed, and the last is only 2 bytes. assertThat(transCache.size(), is(MAX_SPACE_KiB)); ticker.advanceMilli(1); Resource result1 = transCache.get("foo0"); assertThat(result1, nullValue()); // Should have expired Resource result2 = transCache.get("foo1"); assertThat(result2, notNullValue()); // Should still be cached } static private class TestTicker extends Ticker { long time; public TestTicker(long startAt) { super(); this.time = startAt; } @Override public long read() { // TODO Auto-generated method stub return time; } public void advanceMilli(long millis) { advanceNano(millis*1000); } public void advanceNano(long nanos) { time+=nanos; } } }