Package org.geowebcache.diskquota.jdbc

Source Code of org.geowebcache.diskquota.jdbc.JDBCQuotaStoreTest

package org.geowebcache.diskquota.jdbc;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;

import javax.sql.DataSource;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.easymock.classextension.EasyMock;
import org.geowebcache.config.Configuration;
import org.geowebcache.config.XMLConfiguration;
import org.geowebcache.config.XMLConfigurationBackwardsCompatibilityTest;
import org.geowebcache.diskquota.DiskQuotaMonitor;
import org.geowebcache.diskquota.QuotaStore;
import org.geowebcache.diskquota.storage.PageStats;
import org.geowebcache.diskquota.storage.PageStatsPayload;
import org.geowebcache.diskquota.storage.Quota;
import org.geowebcache.diskquota.storage.StorageUnit;
import org.geowebcache.diskquota.storage.SystemUtils;
import org.geowebcache.diskquota.storage.TilePage;
import org.geowebcache.diskquota.storage.TilePageCalculator;
import org.geowebcache.diskquota.storage.TileSet;
import org.geowebcache.diskquota.storage.TileSetVisitor;
import org.geowebcache.grid.GridSetBroker;
import org.geowebcache.layer.TileLayerDispatcher;
import org.geowebcache.storage.DefaultStorageFinder;

public abstract class JDBCQuotaStoreTest extends OnlineTestCase {

    JDBCQuotaStore store;

    File targetDir;

    DefaultStorageFinder cacheDirFinder;

    TileLayerDispatcher layerDispatcher;

    TilePageCalculator tilePageCalculator;

    private BasicDataSource dataSource;

    private TileSet testTileSet;


    protected abstract SQLDialect getDialect();
   
    protected BasicDataSource getDataSource() throws IOException, SQLException {
        BasicDataSource dataSource = new BasicDataSource();

        dataSource.setDriverClassName(fixture.getProperty("driver"));
        dataSource.setUrl(fixture.getProperty("url"));
        dataSource.setUsername(fixture.getProperty("username"));
        dataSource.setPassword(fixture.getProperty("password"));
        dataSource.setPoolPreparedStatements(true);
        dataSource.setAccessToUnderlyingConnectionAllowed(true);
        dataSource.setMinIdle(1);
        dataSource.setMaxActive(4);
        // if we cannot get a connection within 5 seconds give up
        dataSource.setMaxWait(5000);
       
        cleanupDatabase(dataSource);

        return dataSource;
    }
   
    protected void cleanupDatabase(DataSource dataSource) throws SQLException {
        // cleanup
        Connection cx = null;
        Statement st = null;
        try {
            cx = dataSource.getConnection();
            st = cx.createStatement();
            try {
                st.execute("DROP TABLE TILEPAGE CASCADE");
            } catch(Exception e) {
                // fine
            }
            try {
                st.execute("DROP TABLE TILESET CASCADE");
            } catch(Exception e) {
                // fine too
            }
        } finally {
            if(st != null) {
                st.close();
            }
            if(cx != null) {
                cx.close();
            }
        }

    }

   
    @Override
    protected void disconnect() throws Exception {
        store.close();
    }
   
    @Override
    protected boolean isOnline() throws Exception {
        return true;
    }
   
   
    @Override
    protected void setUpInternal() throws Exception {
        // prepare a mock target directory for tiles
        targetDir = new File("target", "mockStore");
        FileUtils.deleteDirectory(targetDir);
        targetDir.mkdirs();

        cacheDirFinder = EasyMock.createMock(DefaultStorageFinder.class);
        EasyMock.expect(cacheDirFinder.getDefaultPath()).andReturn(targetDir.getAbsolutePath())
                .anyTimes();
        EasyMock.expect(
                cacheDirFinder.findEnvVar(EasyMock.eq(DiskQuotaMonitor.GWC_DISKQUOTA_DISABLED)))
                .andReturn(null).anyTimes();
        EasyMock.replay(cacheDirFinder);

        XMLConfiguration xmlConfig = loadXMLConfig();
        LinkedList<Configuration> configList = new LinkedList<Configuration>();
        configList.add(xmlConfig);

        layerDispatcher = new TileLayerDispatcher(new GridSetBroker(true, true), configList);

        tilePageCalculator = new TilePageCalculator(layerDispatcher);

        // prepare a connection pool for tests against a H2 database
        dataSource = getDataSource();
        SQLDialect dialect = getDialect();

        // setup the quota store
        store = new JDBCQuotaStore(cacheDirFinder, tilePageCalculator);
        store.setDataSource(dataSource);
        store.setDialect(dialect);

        // finally initialize the store
        store.initialize();

        testTileSet = tilePageCalculator.getTileSetsFor("topp:states2").iterator().next();
    }

   
    @Override
    protected void tearDownInternal() throws Exception {
        store.close();
    }

    private XMLConfiguration loadXMLConfig() {
        InputStream is = null;
        XMLConfiguration xmlConfig = null;
        try {
            is = XMLConfiguration.class
                    .getResourceAsStream(XMLConfigurationBackwardsCompatibilityTest.LATEST_FILENAME);
            xmlConfig = new XMLConfiguration(is);
        } catch (Exception e) {
            // Do nothing
        } finally {
            IOUtils.closeQuietly(is);
        }

        return xmlConfig;
    }

    public void testTableSetup() throws Exception {
        // on initialization we should have the tilesets setup properly

        // check the global quota
        Quota global = store.getGloballyUsedQuota();
        assertNotNull(global);
        assertEquals(JDBCQuotaStore.GLOBAL_QUOTA_NAME, global.getTileSetId());
        assertEquals(0, global.getBytes().longValue());

        Set<TileSet> tileSets = store.getTileSets();
        // two formats for topp:states2, four formats and two tilesets for topp:states
        assertNotNull(tileSets);
        assertEquals(10, tileSets.size());

        // check every possibility
        TileSet tileSet = new TileSet("topp:states", "EPSG:900913", "image/png", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:900913", "image/jpeg", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:900913", "image/gif", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:900913", "application/vnd.google-earth.kml+xml",
                null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:4326", "image/png", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:4326", "image/jpeg", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:4326", "image/gif", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states", "EPSG:4326", "application/vnd.google-earth.kml+xml",
                null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states2", "EPSG:2163", "image/png", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states2", "EPSG:2163", "image/jpeg", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        // check the layer wide quotas
        assertQuotaZero("topp:states");
        assertQuotaZero("topp:states2");

        // remove one layer from the dispatcher
        Configuration configuration = layerDispatcher.removeLayer("topp:states");
        configuration.save();
        // and make sure at the next startup the store catches up (note this behaviour is just a
        // startup consistency check in case the store got out of sync for some reason. On normal
        // situations the store should have been notified through store.deleteLayer(layerName) if
        // the layer was removed programmatically through StorageBroker.deleteLayer
        store.close();
        store.setDataSource(getDataSource());
        store.initialize();

        tileSets = store.getTileSets();
        assertNotNull(tileSets);
        assertEquals(2, tileSets.size());
        tileSet = new TileSet("topp:states2", "EPSG:2163", "image/png", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);

        tileSet = new TileSet("topp:states2", "EPSG:2163", "image/jpeg", null);
        assertTrue(tileSets.contains(tileSet));
        assertQuotaZero(tileSet);
    }

    public void testRenameLayer() throws InterruptedException {
        assertEquals(8, countTileSetsByLayerName("topp:states"));
        store.renameLayer("topp:states", "states_renamed");
        assertEquals(0, countTileSetsByLayerName("topp:states"));
        assertEquals(8, countTileSetsByLayerName("states_renamed"));
    }

    public void testRenameLayer2() throws InterruptedException {
        final String oldLayerName = tilePageCalculator.getLayerNames().iterator().next();
        final String newLayerName = "renamed_layer";

        // make sure the layer is there and has stuff
        Quota usedQuota = store.getUsedQuotaByLayerName(oldLayerName);
        assertNotNull(usedQuota);

        TileSet tileSet = tilePageCalculator.getTileSetsFor(oldLayerName).iterator().next();
        TilePage page = new TilePage(tileSet.getId(), 0, 0, (byte) 0);
        store.addHitsAndSetAccesTime(Collections.singleton(new PageStatsPayload(page)));
        store.addToQuotaAndTileCounts(tileSet, new Quota(BigInteger.valueOf(1024)),
                Collections.EMPTY_LIST);

        Quota expectedQuota = store.getUsedQuotaByLayerName(oldLayerName);
        assertEquals(1024L, expectedQuota.getBytes().longValue());

        assertNotNull(store.getTileSetById(tileSet.getId()));

        store.renameLayer(oldLayerName, newLayerName);

        // cascade deleted old layer?
        assertNull(store.getLeastRecentlyUsedPage(Collections.singleton(oldLayerName)));
        usedQuota = store.getUsedQuotaByLayerName(oldLayerName);
        assertNotNull(usedQuota);
        assertEquals(0L, usedQuota.getBytes().longValue());

        // created new layer?
        Quota newLayerUsedQuota = store.getUsedQuotaByLayerName(newLayerName);
        assertEquals(expectedQuota.getBytes(), newLayerUsedQuota.getBytes());
    }

    public void testDeleteGridSet() throws InterruptedException {
        // put some data into the two gridsets
        String layerName = "topp:states";
        TileSet tset1 = new TileSet(layerName, "EPSG:4326", "image/jpeg", null);
        addToQuotaStore(tset1);
        TileSet tset2 = new TileSet(layerName, "EPSG:900913", "image/jpeg", null);
        addToQuotaStore(tset2);
        Quota tset1Quota = store.getUsedQuotaByTileSetId(tset1.getId());
        Quota tset2Quota = store.getUsedQuotaByTileSetId(tset2.getId());
        Quota globalQuota = store.getGloballyUsedQuota();
        Quota sum = new Quota();
        sum.add(tset1Quota);
        sum.add(tset2Quota);
        assertEquals(globalQuota.getBytes(), sum.getBytes());
       
        assertEquals(8, countTileSetsByLayerName("topp:states"));
        store.deleteGridSubset("topp:states", "EPSG:900913");
        assertEquals(4, countTileSetsByLayerName("topp:states"));

        // verify the quota for tset2 got erased and that now the total is equal to tset1
        tset1Quota = store.getUsedQuotaByTileSetId(tset1.getId());
        tset2Quota = store.getUsedQuotaByTileSetId(tset2.getId());
        globalQuota = store.getGloballyUsedQuota();
        assertNull(tset2Quota);
        assertEquals(tset1Quota.getBytes(), globalQuota.getBytes());
    }

    private void addToQuotaStore(TileSet tset) throws InterruptedException {
        Quota quotaDiff = new Quota(5, StorageUnit.MiB);
        PageStatsPayload stats = new PageStatsPayload(new TilePage(tset.getId(), 0, 0, 3));
        stats.setNumTiles(10);
        store.addToQuotaAndTileCounts(tset, quotaDiff, Collections.singletonList(stats));
    }

    public void testDeleteLayer() throws InterruptedException {
        // put some data into the layer
        String layerName = "topp:states2";
        TileSet tset = new TileSet(layerName, "EPSG:2163", "image/jpeg", null);

        addToQuotaStore(tset);

        // make sure the layer is there and has stuff
        Quota oldUsedQuota = store.getUsedQuotaByLayerName(layerName);
        assertNotNull(oldUsedQuota);
        Quota globalQuotaBefore = store.getGloballyUsedQuota();
        assertTrue(oldUsedQuota.getBytes().longValue() > 0);
        assertTrue(globalQuotaBefore.getBytes().longValue() > 0);

        TileSet tileSet = tilePageCalculator.getTileSetsFor(layerName).iterator().next();
        TilePage page = new TilePage(tileSet.getId(), 0, 0, (byte) 0);
        store.addHitsAndSetAccesTime(Collections.singleton(new PageStatsPayload(page)));

        assertNotNull(store.getTileSetById(tileSet.getId()));

        store.deleteLayer(layerName);

        // cascade deleted?
        assertNull(store.getLeastRecentlyUsedPage(Collections.singleton(layerName)));
        Quota usedQuota = store.getUsedQuotaByLayerName(layerName);
        assertNotNull(usedQuota);
        assertEquals(0L, usedQuota.getBytes().longValue());
       
        // make sure the global quota got updated
        Quota globalQuotaAfter = store.getGloballyUsedQuota();
        assertEquals(0, globalQuotaAfter.getBytes().longValue());
    }

    public void testVisitor() throws Exception {
        Set<TileSet> tileSets1 = store.getTileSets();
        final Set<TileSet> tileSets2 = new HashSet<TileSet>();
        store.accept(new TileSetVisitor() {

            public void visit(TileSet tileSet, QuotaStore quotaStore) {
                tileSets2.add(tileSet);
            }
        });
        assertEquals(tileSets1, tileSets2);
    }

    public void testGetTileSetById() throws Exception {
        TileSet tileSet = store.getTileSetById(testTileSet.getId());
        assertNotNull(tileSet);
        assertEquals(testTileSet, tileSet);

        try {
            store.getTileSetById("NonExistentTileSetId");
            fail("Expected IAE");
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
    }

    @SuppressWarnings("unchecked")
    public void testGetUsedQuotaByLayerName() throws Exception {
        String layerName = "topp:states2";
        List<TileSet> tileSets;
        tileSets = new ArrayList<TileSet>(tilePageCalculator.getTileSetsFor(layerName));

        Quota expected = new Quota();
        for (TileSet tset : tileSets) {
            Quota quotaDiff = new Quota(10, StorageUnit.MiB);
            expected.add(quotaDiff);
            store.addToQuotaAndTileCounts(tset, quotaDiff, Collections.EMPTY_SET);
        }

        Quota usedQuotaByLayerName = store.getUsedQuotaByLayerName(layerName);
        assertEquals(expected.getBytes(), usedQuotaByLayerName.getBytes());
    }

    @SuppressWarnings("unchecked")
    public void testGetUsedQuotaByTileSetId() throws Exception {
        String layerName = "topp:states2";
        List<TileSet> tileSets;
        tileSets = new ArrayList<TileSet>(tilePageCalculator.getTileSetsFor(layerName));

        Map<String, Quota> expectedById = new HashMap<String, Quota>();

        for (TileSet tset : tileSets) {
            Quota quotaDiff = new Quota(10D * Math.random(), StorageUnit.MiB);
            store.addToQuotaAndTileCounts(tset, quotaDiff, Collections.EMPTY_SET);
            store.addToQuotaAndTileCounts(tset, quotaDiff, Collections.EMPTY_SET);
            Quota tsetQuota = new Quota(quotaDiff);
            tsetQuota.add(quotaDiff);
            expectedById.put(tset.getId(), tsetQuota);
        }

        for (Map.Entry<String, Quota> expected : expectedById.entrySet()) {
            BigInteger expectedValaue = expected.getValue().getBytes();
            String tsetId = expected.getKey();
            assertEquals(expectedValaue, store.getUsedQuotaByTileSetId(tsetId).getBytes());
        }
    }

    @SuppressWarnings("unchecked")
    public void testUpdateUsedQuotaWithParameters() throws Exception {
        // prepare a tileset with params
        String paramId = DigestUtils.shaHex("&styles=polygon");
        TileSet tset = new TileSet("topp:states2", "EPSG:2163", "image/jpeg", paramId);

        Quota quotaDiff = new Quota(10D * Math.random(), StorageUnit.MiB);
        PageStatsPayload stats = new PageStatsPayload(new TilePage(tset.getId(), 0, 0, 3));
        stats.setNumTiles(10);
        store.addToQuotaAndTileCounts(tset, quotaDiff, Collections.singletonList(stats));

        assertEquals(quotaDiff.getBytes(), store.getUsedQuotaByTileSetId(tset.getId()).getBytes());
    }

    /**
     * Combined test for {@link BDBQuotaStore#addToQuotaAndTileCounts(TileSet, Quota, Collection)}
     * and {@link BDBQuotaStore#addHitsAndSetAccesTime(Collection)}
     *
     * @throws Exception
     */
    public void testPageStatsGathering() throws Exception {
        final MockSystemUtils sysUtils = new MockSystemUtils();
        sysUtils.setCurrentTimeMinutes(10);
        sysUtils.setCurrentTimeMillis(10 * 60 * 1000);
        SystemUtils.set(sysUtils);

        TileSet tileSet = testTileSet;

        TilePage page = new TilePage(tileSet.getId(), 0, 0, (byte) 0);

        PageStatsPayload payload = new PageStatsPayload(page);
        int numHits = 100;
        payload.setTileSet(tileSet);
        payload.setLastAccessTime(sysUtils.currentTimeMillis() - 1 * 60 * 1000);
        payload.setNumHits(numHits);
        payload.setNumTiles(1);

        store.addToQuotaAndTileCounts(tileSet, new Quota(1, StorageUnit.MiB),
                Collections.singleton(payload));

        Future<List<PageStats>> result = store.addHitsAndSetAccesTime(Collections
                .singleton(payload));
        List<PageStats> allStats = result.get();
        PageStats stats = allStats.get(0);
        float fillFactor = stats.getFillFactor();
        assertEquals(1.0f, fillFactor, 1e-6);

        int lastAccessTimeMinutes = stats.getLastAccessTimeMinutes();
        assertEquals(sysUtils.currentTimeMinutes(), lastAccessTimeMinutes);

        float frequencyOfUsePerMinute = stats.getFrequencyOfUsePerMinute();
        assertEquals(100f, frequencyOfUsePerMinute);

        // now 1 minute later...
        sysUtils.setCurrentTimeMinutes(sysUtils.currentTimeMinutes() + 2);
        sysUtils.setCurrentTimeMillis(sysUtils.currentTimeMillis() + 2 * 60 * 1000);

        numHits = 10;
        payload.setLastAccessTime(sysUtils.currentTimeMillis() - 1 * 60 * 1000);
        payload.setNumHits(numHits);

        result = store.addHitsAndSetAccesTime(Collections.singleton(payload));
        allStats = result.get();
        stats = allStats.get(0);

        lastAccessTimeMinutes = stats.getLastAccessTimeMinutes();
        assertEquals(11, lastAccessTimeMinutes);

        frequencyOfUsePerMinute = stats.getFrequencyOfUsePerMinute();
        float expected = 55.0f;// the 100 previous + the 10 added now / the 2 minutes that elapsed
        assertEquals(expected, frequencyOfUsePerMinute, 1e-6f);
    }

    public void testGetGloballyUsedQuota() throws InterruptedException {
        Quota usedQuota = store.getGloballyUsedQuota();
        assertNotNull(usedQuota);
        assertEquals(0, usedQuota.getBytes().intValue());

        String layerName = tilePageCalculator.getLayerNames().iterator().next();
        TileSet tileSet = tilePageCalculator.getTileSetsFor(layerName).iterator().next();

        Quota quotaDiff = new Quota(BigInteger.valueOf(1000));
        Collection<PageStatsPayload> tileCountDiffs = Collections.emptySet();
        store.addToQuotaAndTileCounts(tileSet, quotaDiff, tileCountDiffs);

        usedQuota = store.getGloballyUsedQuota();
        assertNotNull(usedQuota);
        assertEquals(1000, usedQuota.getBytes().intValue());

        quotaDiff = new Quota(BigInteger.valueOf(-500));
        store.addToQuotaAndTileCounts(tileSet, quotaDiff, tileCountDiffs);

        usedQuota = store.getGloballyUsedQuota();
        assertNotNull(usedQuota);
        assertEquals(500, usedQuota.getBytes().intValue());
    }

    public void testSetTruncated() throws Exception {
        String tileSetId = testTileSet.getId();
        TilePage page = new TilePage(tileSetId, 0, 0, 2);

        PageStatsPayload payload = new PageStatsPayload(page);
        payload.setTileSet(testTileSet);
        int numHits = 100;
        payload.setNumHits(numHits);
        payload.setNumTiles(5);

        store.addToQuotaAndTileCounts(testTileSet, new Quota(1, StorageUnit.MiB),
                Collections.singleton(payload));
        List<PageStats> stats = store.addHitsAndSetAccesTime(Collections.singleton(payload)).get();
        assertTrue(stats.get(0).getFillFactor() > 0f);
        PageStats pageStats = store.setTruncated(page);
        assertEquals(0f, pageStats.getFillFactor());
    }

    public void testGetLeastFrequentlyUsedPage() throws Exception {
        final String layerName = testTileSet.getLayerName();
        Set<String> layerNames = Collections.singleton(layerName);

        TilePage lfuPage;
        lfuPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertNull(lfuPage);

        TilePage page1 = new TilePage(testTileSet.getId(), 0, 1, 2);
        TilePage page2 = new TilePage(testTileSet.getId(), 1, 1, 2);

        PageStatsPayload payload1 = new PageStatsPayload(page1, testTileSet);
        PageStatsPayload payload2 = new PageStatsPayload(page2, testTileSet);

        payload1.setNumHits(100);
        payload2.setNumHits(10);
        Collection<PageStatsPayload> statsUpdates = Arrays.asList(payload1, payload2);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        TilePage leastFrequentlyUsedPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertEquals(page2, leastFrequentlyUsedPage);

        payload2.setNumHits(1000);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        leastFrequentlyUsedPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertEquals(page1, leastFrequentlyUsedPage);
    }
   
    public void testGetLeastFrequentlyUsedPageSkipEmpty() throws Exception {
        final String layerName = testTileSet.getLayerName();
        Set<String> layerNames = Collections.singleton(layerName);

        TilePage lfuPage;
        lfuPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertNull(lfuPage);

        TilePage page1 = new TilePage(testTileSet.getId(), 0, 1, 2);
        TilePage page2 = new TilePage(testTileSet.getId(), 1, 1, 2);

        PageStatsPayload payload1 = new PageStatsPayload(page1, testTileSet);
        PageStatsPayload payload2 = new PageStatsPayload(page2, testTileSet);

        payload1.setNumHits(100);
        payload2.setNumHits(10);
        Collection<PageStatsPayload> statsUpdates = Arrays.asList(payload1, payload2);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        TilePage leastFrequentlyUsedPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertEquals(page2, leastFrequentlyUsedPage);

        store.setTruncated(page2);

        leastFrequentlyUsedPage = store.getLeastFrequentlyUsedPage(layerNames);
        assertEquals(page1, leastFrequentlyUsedPage);
    }

    public void testGetLeastRecentlyUsedPage() throws Exception {
        MockSystemUtils mockSystemUtils = new MockSystemUtils();
        mockSystemUtils.setCurrentTimeMinutes(1000);
        mockSystemUtils.setCurrentTimeMillis(mockSystemUtils.currentTimeMinutes() * 60 * 1000);
        SystemUtils.set(mockSystemUtils);

        final String layerName = testTileSet.getLayerName();
        Set<String> layerNames = Collections.singleton(layerName);

        TilePage leastRecentlyUsedPage;
        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertNull(leastRecentlyUsedPage);

        TilePage page1 = new TilePage(testTileSet.getId(), 0, 1, 2);
        TilePage page2 = new TilePage(testTileSet.getId(), 1, 1, 2);

        PageStatsPayload payload1 = new PageStatsPayload(page1, testTileSet);
        PageStatsPayload payload2 = new PageStatsPayload(page2, testTileSet);

        payload1.setLastAccessTime(mockSystemUtils.currentTimeMillis() + 1 * 60 * 1000);
        payload2.setLastAccessTime(mockSystemUtils.currentTimeMillis() + 2 * 60 * 1000);

        Collection<PageStatsPayload> statsUpdates = Arrays.asList(payload1, payload2);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertEquals(page1, leastRecentlyUsedPage);

        payload1.setLastAccessTime(mockSystemUtils.currentTimeMillis() + 10 * 60 * 1000);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertEquals(page2, leastRecentlyUsedPage);
    }
   
    public void testGetLeastRecentlyUsedPageSkipEmpty() throws Exception {
        MockSystemUtils mockSystemUtils = new MockSystemUtils();
        mockSystemUtils.setCurrentTimeMinutes(1000);
        mockSystemUtils.setCurrentTimeMillis(mockSystemUtils.currentTimeMinutes() * 60 * 1000);
        SystemUtils.set(mockSystemUtils);

        final String layerName = testTileSet.getLayerName();
        Set<String> layerNames = Collections.singleton(layerName);

        TilePage leastRecentlyUsedPage;
        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertNull(leastRecentlyUsedPage);

        TilePage page1 = new TilePage(testTileSet.getId(), 0, 1, 2);
        TilePage page2 = new TilePage(testTileSet.getId(), 1, 1, 2);

        PageStatsPayload payload1 = new PageStatsPayload(page1, testTileSet);
        PageStatsPayload payload2 = new PageStatsPayload(page2, testTileSet);

        payload1.setLastAccessTime(mockSystemUtils.currentTimeMillis() + 1 * 60 * 1000);
        payload2.setLastAccessTime(mockSystemUtils.currentTimeMillis() + 2 * 60 * 1000);

        Collection<PageStatsPayload> statsUpdates = Arrays.asList(payload1, payload2);
        store.addHitsAndSetAccesTime(statsUpdates).get();

        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertEquals(page1, leastRecentlyUsedPage);

        // truncate the page, setting its fill to 0
        store.setTruncated(page1);

        leastRecentlyUsedPage = store.getLeastRecentlyUsedPage(layerNames);
        assertEquals(page2, leastRecentlyUsedPage);
    }

    public void testGetTilesForPage() throws Exception {
        TilePage page = new TilePage(testTileSet.getId(), 0, 0, 0);

        long[][] expected = tilePageCalculator.toGridCoverage(testTileSet, page);
        long[][] tilesForPage = store.getTilesForPage(page);

        assertTrue(Arrays.equals(expected[0], tilesForPage[0]));

        page = new TilePage(testTileSet.getId(), 0, 0, 1);

        expected = tilePageCalculator.toGridCoverage(testTileSet, page);
        tilesForPage = store.getTilesForPage(page);

        assertTrue(Arrays.equals(expected[1], tilesForPage[1]));
    }

    private int countTileSetsByLayerName(String layerName) {
        int count = 0;
        for (TileSet ts : store.getTileSets()) {
            if (layerName.equals(ts.getLayerName())) {
                count++;
            }
        }

        return count;
    }

    /**
     * Asserts the quota used by this tile set is null
     *
     * @param tileSet
     */
    private void assertQuotaZero(TileSet tileSet) {
        Quota quota = store.getUsedQuotaByTileSetId(tileSet.getId());
        assertNotNull(quota);
        assertEquals(0, quota.getBytes().longValue());
    }

    /**
     * Asserts the quota used by this tile set is null
     *
     * @param tileSet
     * @throws InterruptedException
     */
    private void assertQuotaZero(String layerName) throws InterruptedException {
        Quota quota = store.getUsedQuotaByLayerName(layerName);
        assertNotNull(quota);
        assertEquals(0, quota.getBytes().longValue());
    }
}
TOP

Related Classes of org.geowebcache.diskquota.jdbc.JDBCQuotaStoreTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.