/**
* 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/>.
*
* @author Kevin Smith, Boundless, 2017
*/
package org.geowebcache.storage;
import static org.easymock.EasyMock.anyLong;
import static org.easymock.EasyMock.isNull;
import static org.easymock.classextension.EasyMock.capture;
import static org.easymock.classextension.EasyMock.eq;
import static org.easymock.classextension.EasyMock.geq;
import static org.geowebcache.util.FileMatchers.resource;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.describedAs;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import org.geowebcache.filter.parameters.ParametersUtils;
import org.geowebcache.filter.parameters.StringParameterFilter;
import org.geowebcache.io.ByteArrayResource;
import org.geowebcache.layer.TileLayer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.easymock.Capture;
import org.easymock.classextension.EasyMock;
/**
* Test to do
*/
public abstract class AbstractBlobStoreTest<TestClass extends BlobStore> {
protected TestClass store;
protected boolean events = true;
/**
* Set up the test store in {@link store}.
*/
@Before
public abstract void createTestUnit() throws Exception;
/**
* Override and add tear down assertions after calling super
* @throws Exception
*/
@After
public void destroyTestUnit() throws Exception {
// Might be null if an Assumption failed during createTestUnit
if(Objects.nonNull(store)) {
store.destroy();
}
}
@Test
public void testEmpty() throws Exception {
TileObject fromCache = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
assertThat(store.get(fromCache), equalTo(false));
//assertThat(fromCache, hasProperty("status", is(Status.MISS)));
}
@Test
public void testStoreTile() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
final long size = toCache.getBlobSize();
TileObject fromCache = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
geq(size) // Some stores have minimum block sizes and so have to pad this
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache);
EasyMock.verify(listener);
assertThat(store.get(fromCache), is(true));
//assertThat(fromCache, hasProperty("status", is(Status.HIT)));
assertThat(fromCache, hasProperty("blobSize", is((int)size)));
assertThat(fromCache, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testStoreTilesInMultipleLayers() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer1", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer2", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject fromCache1 = TileObject.createQueryTileObject("testLayer1", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer2", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer2", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
if(events) {
listener.tileStored(eq("testLayer1"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0), geq(size1));
listener.tileStored(eq("testLayer2"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0), geq(size2));
}
EasyMock.replay(listener);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
assertThat(fromCache2_1, hasProperty("blobSize", is(0)));
store.put(toCache2);
EasyMock.verify(listener);
assertThat(store.get(fromCache1), is(true));
assertThat(fromCache1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testDeleteTile() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject remove = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
TileObject fromCache = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
Capture<Long> sizeCapture = new Capture<>();
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
capture(sizeCapture)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache);
EasyMock.verify(listener);
long storedSize = 0;
if(events) {
storedSize=sizeCapture.getValue();
}
EasyMock.reset(listener);
if(events) {
listener.tileDeleted(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
eq(storedSize)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.delete(remove);
EasyMock.verify(listener);
assertThat(store.get(fromCache), is(false));
assertThat(fromCache, hasProperty("blobSize", is(0)));
}
@Test
public void testUpdateTile() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size2 = toCache2.getBlobSize();
TileObject fromCache = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", null);
Capture<Long> sizeCapture = new Capture<>();
if(events){
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
capture(sizeCapture)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache1);
EasyMock.verify(listener);
long storedSize = 0;
if(events){
storedSize = sizeCapture.getValue();
}
EasyMock.reset(listener);
if(events){
listener.tileUpdated(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
geq(size2),
eq(storedSize)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache2);
EasyMock.verify(listener);
assertThat(store.get(fromCache), is(true));
assertThat(fromCache, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testGridsets() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject remove = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
TileObject fromCache1_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
TileObject fromCache2_3 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
Capture<Long> sizeCapture1 = new Capture<>();
Capture<Long> sizeCapture2 = new Capture<>();
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet1"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
capture(sizeCapture1)
);EasyMock.expectLastCall();
listener.tileStored(eq("testLayer"), eq("testGridSet2"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
capture(sizeCapture2)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
store.put(toCache2);
EasyMock.verify(listener);
long storedSize1 = 0;
if(events) {
storedSize1 = sizeCapture1.getValue();
}
assertThat(store.get(fromCache1_1), is(true));
assertThat(fromCache1_1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1_1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
EasyMock.reset(listener);
if(events) {
listener.tileDeleted(eq("testLayer"), eq("testGridSet1"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
eq(storedSize1)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.delete(remove);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
assertThat(store.get(fromCache2_3), is(true));
assertThat(fromCache2_3, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_3, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testDeleteGridset() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
final long size1 = toCache1.getBlobSize();
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet1"), eq("image/png"), eq(null), eq(0L), eq(0L), eq(0),
geq(size1)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache1);
EasyMock.verify(listener);
EasyMock.reset(listener);
if(events) {
listener.gridSubsetDeleted(eq("testLayer"), eq("testGridSet1"));EasyMock.expectLastCall();
}
EasyMock.replay(listener);
assertThat(store.deleteByGridsetId("testLayer", "testGridSet1"), is(true));
EasyMock.verify(listener);
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
}
@Test
public void testDeleteGridsetDoesntDeleteOthers() throws Exception {
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject fromCache1_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet1", "image/png", null);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
TileObject fromCache2_3 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet2", "image/png", null);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
store.put(toCache2);
assertThat(store.get(fromCache1_1), is(true));
assertThat(fromCache1_1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1_1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
store.deleteByGridsetId("testLayer", "testGridSet1");
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
assertThat(store.get(fromCache2_3), is(true));
assertThat(fromCache2_3, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_3, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testParameters() throws Exception {
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject remove = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache1_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
TileObject fromCache2_3 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
Capture<Long> sizeCapture1 = new Capture<>();
Capture<Long> sizeCapture2 = new Capture<>();
Capture<String> pidCapture1 = new Capture<>();
Capture<String> pidCapture2 = new Capture<>();
if(events){
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), capture(pidCapture1), eq(0L), eq(0L), eq(0),
capture(sizeCapture1)
);EasyMock.expectLastCall();
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), capture(pidCapture2), eq(0L), eq(0L), eq(0),
capture(sizeCapture2)
);EasyMock.expectLastCall();
}
EasyMock.replay(listener);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
store.put(toCache2);
EasyMock.verify(listener);
long storedSize1 = 0;
if(events) {
storedSize1 = sizeCapture1.getValue();
// parameter id strings should be non-null and not equal to one another
assertThat(pidCapture1.getValue(), notNullValue());
assertThat(pidCapture2.getValue(), notNullValue());
assertThat(pidCapture2.getValue(), not(pidCapture1.getValue()));
}
assertThat(store.get(fromCache1_1), is(true));
assertThat(fromCache1_1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1_1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
EasyMock.reset(listener);
if(events) {
listener.tileDeleted(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(pidCapture1.getValue()), eq(0L), eq(0L), eq(0),
eq(storedSize1)
);
}
EasyMock.replay(listener);
store.delete(remove);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
assertThat(store.get(fromCache2_3), is(true));
assertThat(fromCache2_3, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_3, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testMetadata() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "testKey"), nullValue());
store.putLayerMetadata("testLayer", "testKey", "testValue");
assertThat(store.getLayerMetadata("testLayer", "testKey"), equalTo("testValue"));
}
@Test
public void testMetadataWithEqualsInKey() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "test=Key"), nullValue());
store.putLayerMetadata("testLayer", "test=Key", "testValue");
assertThat(store.getLayerMetadata("testLayer", "test=Key"), equalTo("testValue"));
}
@Test
public void testMetadataWithEqualsInValue() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "testKey"), nullValue());
store.putLayerMetadata("testLayer", "testKey", "test=Value");
assertThat(store.getLayerMetadata("testLayer", "testKey"), equalTo("test=Value"));
}
@Test
public void testMetadataWithAmpInKey() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "test&Key"), nullValue());
store.putLayerMetadata("testLayer", "test&Key", "testValue");
assertThat(store.getLayerMetadata("testLayer", "test&Key"), equalTo("testValue"));
}
@Test
public void testMetadataWithAmpInValue() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "testKey"), nullValue());
store.putLayerMetadata("testLayer", "testKey", "test&Value");
assertThat(store.getLayerMetadata("testLayer", "testKey"), equalTo("test&Value"));
}
@Test
public void testMetadataWithPercentInKey() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "test%Key"), nullValue());
store.putLayerMetadata("testLayer", "test%Key", "testValue");
assertThat(store.getLayerMetadata("testLayer", "test%Key"), equalTo("testValue"));
}
@Test
public void testMetadataWithPercentInValue() throws Exception {
assertThat(store.getLayerMetadata("testLayer", "testKey"), nullValue());
store.putLayerMetadata("testLayer", "testKey", "test%Value");
assertThat(store.getLayerMetadata("testLayer", "testKey"), equalTo("test%Value"));
}
@SuppressWarnings("unchecked")
@Test
public void testParameterList() throws Exception {
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
assertThat(store.getParameters("testLayer"), empty());
store.put(toCache1);
assertThat(store.getParameters("testLayer"), containsInAnyOrder(params1));
store.put(toCache2);
assertThat(store.getParameters("testLayer"), containsInAnyOrder(params1, params2));
}
@Test
public void testParameterIDList() throws Exception {
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
String params1Id = ParametersUtils.getId(params1);
String params2Id = ParametersUtils.getId(params2);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
assertThat(store.getParameterIds("testLayer"), empty());
store.put(toCache1);
assertThat(store.getParameterIds("testLayer"), containsInAnyOrder(params1Id));
store.put(toCache2);
assertThat(store.getParameterIds("testLayer"), containsInAnyOrder(params1Id, params2Id));
}
@Test
public void testEmptyParameterListIsNotNull() throws Exception {
assertThat(store.getParameters("testLayer"), empty());
}
@Test
public void testDeleteByParametersId() throws Exception {
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
String paramID1 = ParametersUtils.getId(params1);
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
String paramID2 = ParametersUtils.getId(params2);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject fromCache1_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(paramID1), eq(0L), eq(0L), eq(0),
geq(size1)
);
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(paramID2), eq(0L), eq(0L), eq(0),
geq(size2)
);
}
EasyMock.replay(listener);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
store.put(toCache2);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_1), is(true));
assertThat(fromCache1_1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1_1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
EasyMock.reset(listener);
if(events) {
listener.parametersDeleted(eq("testLayer"), eq(paramID1));
}
EasyMock.replay(listener);
store.deleteByParametersId("testLayer", paramID1);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
}
@Test
public void testDeleteByParametersIdDoesNotDeleteOthers() throws Exception {
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
String paramID1 = ParametersUtils.getId(params1);
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
final long size2 = toCache2.getBlobSize();
TileObject fromCache2_3 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
store.put(toCache1);
store.put(toCache2);
store.deleteByParametersId("testLayer", paramID1);
assertThat(store.get(fromCache2_3), is(true));
assertThat(fromCache2_3, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_3, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
}
@Test
public void testPurgeOrphans() throws Exception {
TileLayer layer = EasyMock.createMock("layer", TileLayer.class);
EasyMock.expect(layer.getName()).andStubReturn("testLayer");
StringParameterFilter testFilter = new StringParameterFilter();
testFilter.setDefaultValue("DEFAULT");
testFilter.setKey("testKey");
testFilter.setValues(Arrays.asList("testValue2"));
EasyMock.expect(layer.getParameterFilters()).andStubReturn(Arrays.asList(testFilter));
EasyMock.replay(layer);
Map<String, String> params1 = Collections.singletonMap("testKey", "testValue1");
String paramID1 = ParametersUtils.getId(params1);
Map<String, String> params2 = Collections.singletonMap("testKey", "testValue2");
String paramID2 = ParametersUtils.getId(params2);
TileObject toCache1 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1, new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)));
TileObject toCache2 = TileObject.createCompleteTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2, new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)));
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
final long size1 = toCache1.getBlobSize();
final long size2 = toCache2.getBlobSize();
TileObject fromCache1_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_1 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
TileObject fromCache1_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params1);
TileObject fromCache2_2 = TileObject.createQueryTileObject("testLayer", new long[]{0L, 0L, 0L}, "testGridSet", "image/png", params2);
if(events) {
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(paramID1), eq(0L), eq(0L), eq(0),
geq(size1)
);
listener.tileStored(eq("testLayer"), eq("testGridSet"), eq("image/png"), eq(paramID2), eq(0L), eq(0L), eq(0),
geq(size2)
);
}
EasyMock.replay(listener);
store.put(toCache1);
assertThat(store.get(fromCache2_1), is(false));
store.put(toCache2);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_1), is(true));
assertThat(fromCache1_1, hasProperty("blobSize", is((int)size1)));
assertThat(fromCache1_1, hasProperty("blob",resource(new ByteArrayResource("1,2,4,5,6 test".getBytes(StandardCharsets.UTF_8)))));
assertThat(store.get(fromCache2_2), is(true));
assertThat(fromCache2_2, hasProperty("blobSize", is((int)size2)));
assertThat(fromCache2_2, hasProperty("blob",resource(new ByteArrayResource("7,8,9,10 test".getBytes(StandardCharsets.UTF_8)))));
EasyMock.reset(listener);
if(events) {
listener.parametersDeleted(eq("testLayer"), eq(paramID1));
}
EasyMock.replay(listener);
store.purgeOrphans(layer);
EasyMock.verify(listener);
assertThat(store.get(fromCache1_2), is(false));
assertThat(fromCache1_2, hasProperty("blobSize", is(0)));
}
protected void cacheTile(String layerName, long x, long y, int z, String gridSetId, String format,
Map<String, String> parameters, String content) throws StorageException{
TileObject to = TileObject.createCompleteTileObject(layerName, new long[]{x,y,z}, gridSetId, format,
parameters, new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8)));
store.put(to);
}
protected void assertTile(String layerName, long x, long y, int z, String gridSetId, String format,
Map<String, String> parameters, String content) throws StorageException{
TileObject to = TileObject.createQueryTileObject(layerName, new long[]{x,y,z}, gridSetId, format,
parameters);
assertThat(store.get(to), describedAs("get a tile", is(true)));
assertThat(to, hasProperty("blob",resource(new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8)))));
}
protected void assertNoTile(String layerName, long x, long y, int z, String gridSetId, String format,
Map<String, String> parameters) throws StorageException{
TileObject to = TileObject.createQueryTileObject(layerName, new long[]{x,y,z}, gridSetId, format,
parameters);
assertThat(store.get(to), describedAs("don't get a tile", is(false)));
assertThat(to, hasProperty("blob", nullValue()));
assertThat(to, hasProperty("blobSize", is(0)));
}
@Test
public void testPurgeOrphansWithDefault() throws Exception {
TileLayer layer = EasyMock.createMock("layer", TileLayer.class);
final String layerName = "testLayer";
final String paramKey = "testKey";
EasyMock.expect(layer.getName()).andStubReturn(layerName);
StringParameterFilter testFilter = new StringParameterFilter();
testFilter.setDefaultValue("DEFAULT");
testFilter.setKey(paramKey);
testFilter.setValues(Arrays.asList("keep1", "keep2", "keep3"));
EasyMock.expect(layer.getParameterFilters()).andStubReturn(Arrays.asList(testFilter));
EasyMock.replay(layer);
Map<String, String> params1 = Collections.singletonMap(paramKey, "purge1");
String paramID1 = ParametersUtils.getId(params1);
Map<String, String> params2 = Collections.singletonMap(paramKey, "keep1");
String paramID2 = ParametersUtils.getId(params2);
final String gridset = "testGridSet";
final String format = "image/png";
BlobStoreListener listener = EasyMock.createMock(BlobStoreListener.class);
store.addListener(listener);
if(events) {
listener.tileStored(eq(layerName), eq(gridset), eq(format), eq(paramID1), eq(0L), eq(0L), eq(0),
anyLong()
);
listener.tileStored(eq(layerName), eq(gridset), eq(format), eq(paramID2), eq(0L), eq(0L), eq(0),
anyLong()
);
listener.tileStored(eq(layerName), eq(gridset), eq(format), isNull(), eq(0L), eq(0L), eq(0),
anyLong()
);
}
EasyMock.replay(listener);
cacheTile(layerName, 0,0,0, gridset, format, params1, "purge");
cacheTile(layerName, 0,0,0, gridset, format, params2, "keep param");
cacheTile(layerName, 0,0,0, gridset, format, null, "keep default");
EasyMock.verify(listener);
assertTile(layerName, 0,0,0, gridset, format, params1, "purge");
assertTile(layerName, 0,0,0, gridset, format, params2, "keep param");
assertTile(layerName, 0,0,0, gridset, format, null, "keep default");
EasyMock.reset(listener);
if(events) {
listener.parametersDeleted(eq(layerName), eq(paramID1));
}
EasyMock.replay(listener);
store.purgeOrphans(layer);
EasyMock.verify(listener);
assertNoTile(layerName, 0,0,0, gridset, format, params1);
assertTile(layerName, 0,0,0, gridset, format, params2, "keep param");
assertTile(layerName, 0,0,0, gridset, format, null, "keep default");
}
}