Ignore:
Timestamp:
2018-05-12T14:18:57+02:00 (6 years ago)
Author:
wiktorn
Message:

Imagery definition refactor

Extend imagery definitions by:

  • allowing setting default layers for WMS_ENDPOINT and WMTS
  • allowing setting minimum expires time for tile for this imagery
  • allowing setting custom headers that will be sent for all requests

(get map, get capabilities) for this imagery

Additional changes in code:

  • use TileJobOptions to pass miscellaneous options to loaders
  • refactor WMSImagery to use SAX parser

See: #15981, #7953, #16224, #15940, #16249

Location:
trunk/test/unit/org/openstreetmap/josm
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/TestUtils.java

    r13489 r13733  
    1515import java.security.AccessController;
    1616import java.security.PrivilegedAction;
     17import java.time.Instant;
     18import java.time.ZoneOffset;
     19import java.time.format.DateTimeFormatter;
     20import java.time.temporal.Temporal;
    1721import java.util.Arrays;
    1822import java.util.Collection;
     
    3842import org.openstreetmap.josm.tools.JosmRuntimeException;
    3943import org.openstreetmap.josm.tools.Utils;
     44
     45import com.github.tomakehurst.wiremock.WireMockServer;
     46import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
    4047
    4148import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    380387        }
    381388    }
     389
     390    /**
     391     * Return WireMock server serving files under ticker directory
     392     * @param ticketId Ticket numeric identifier
     393     * @return WireMock HTTP server on dynamic port
     394     */
     395    public static WireMockServer getWireMockServer(int ticketId) {
     396            return new WireMockServer(
     397                    WireMockConfiguration.options()
     398                        .dynamicPort()
     399                        .usingFilesUnderDirectory(getRegressionDataDir(ticketId))
     400                    );
     401    }
     402
     403    /**
     404     * Return WireMock server serving files under ticker directory
     405     * @return WireMock HTTP server on dynamic port
     406     */
     407    public static WireMockServer getWireMockServer() {
     408            return new WireMockServer(
     409                    WireMockConfiguration.options()
     410                        .dynamicPort()
     411                    );
     412    }
     413    /**
     414     * Renders Temporal to RFC 1123 Date Time
     415     * @param time
     416     * @return string representation according to RFC1123 of time
     417     */
     418    public static String getHTTPDate(Temporal time) {
     419        return DateTimeFormatter.RFC_1123_DATE_TIME.withZone(ZoneOffset.UTC).format(time);
     420    }
     421
     422    /**
     423     * Renders java time stamp to RFC 1123 Date Time
     424     * @param time
     425     * @return string representation according to RFC1123 of time
     426     */
     427    public static String getHTTPDate(long time) {
     428        return getHTTPDate(Instant.ofEpochMilli(time));
     429    }
     430
     431
    382432}
  • trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java

    r12636 r13733  
    7070    @Test
    7171    public void testActionPerformedEnabledWms() {
    72         wireMockRule.stubFor(get(urlEqualTo("/wms?VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities"))
     72        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1"))
    7373                .willReturn(aResponse()
    74                     .withStatus(200)
    75                     .withHeader("Content-Type", "text/xml")
    76                     .withBodyFile("imagery/wms-capabilities.xml")));
     74                        .withStatus(200)
     75                        .withHeader("Content-Type", "text/xml")
     76                        .withBodyFile("imagery/wms-capabilities.xml")));
     77        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities"))
     78                .willReturn(aResponse()
     79                        .withStatus(404)));
     80        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0"))
     81                .willReturn(aResponse()
     82                        .withStatus(404)));
     83
    7784        new AddImageryLayerAction(new ImageryInfo("localhost", "http://localhost:" + wireMockRule.port() + "/wms?",
    7885                "wms_endpoint", null, null)).actionPerformed(null);
  • trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java

    r12620 r13733  
    1414import org.junit.Rule;
    1515import org.junit.Test;
     16import org.openstreetmap.josm.data.imagery.TileJobOptions;
    1617import org.openstreetmap.josm.testutils.JOSMTestRules;
    1718import org.openstreetmap.josm.tools.Logging;
     
    5455
    5556        Task(ICacheAccess<String, CacheEntry> cache, URL url, AtomicInteger counter) {
    56             super(cache, 1, 1, null);
     57            super(cache, new TileJobOptions(1, 1, null, 10));
    5758            this.url = url;
    5859            this.counter = counter;
  • trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java

    r13358 r13733  
    22package org.openstreetmap.josm.data.cache;
    33
     4import static org.junit.Assert.assertArrayEquals;
    45import static org.junit.Assert.assertEquals;
    56import static org.junit.Assert.assertFalse;
     7import static org.junit.Assert.assertTrue;
    68
    79import java.io.IOException;
     
    911import java.net.URL;
    1012import java.nio.charset.StandardCharsets;
     13import java.util.concurrent.TimeUnit;
    1114
    1215import org.apache.commons.jcs.access.behavior.ICacheAccess;
     16import org.apache.commons.jcs.engine.behavior.ICacheElement;
    1317import org.junit.Before;
    1418import org.junit.Rule;
    1519import org.junit.Test;
     20import org.openstreetmap.josm.TestUtils;
    1621import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult;
     22import org.openstreetmap.josm.data.imagery.TileJobOptions;
    1723import org.openstreetmap.josm.testutils.JOSMTestRules;
    1824import org.openstreetmap.josm.tools.Logging;
     25
     26import com.github.tomakehurst.wiremock.client.WireMock;
     27import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
     28import com.github.tomakehurst.wiremock.junit.WireMockRule;
     29import com.github.tomakehurst.wiremock.matching.UrlPattern;
    1930
    2031import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    2536public class JCSCachedTileLoaderJobTest {
    2637
     38    /**
     39     * mocked tile server
     40     */
     41    @Rule
     42    public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options()
     43            .dynamicPort());
     44
    2745    private static class TestCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, CacheEntry> {
    2846        private String url;
    2947        private String key;
    3048
    31         TestCachedTileLoaderJob(String url, String key) throws IOException {
    32             super(getCache(), 30000, 30000, null);
     49        TestCachedTileLoaderJob(String url, String key)  {
     50            this(url, key, (int) TimeUnit.DAYS.toSeconds(1));
     51        }
     52
     53        TestCachedTileLoaderJob(String url, String key, int minimumExpiry)  {
     54            super(getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry));
    3355
    3456            this.url = url;
    3557            this.key = key;
    3658        }
     59
    3760
    3861        @Override
     
    5275        @Override
    5376        protected CacheEntry createCacheEntry(byte[] content) {
    54             return new CacheEntry("dummy".getBytes(StandardCharsets.UTF_8));
     77            return new CacheEntry(content);
    5578        }
    5679    }
     
    6083        private boolean ready;
    6184        private LoadResult result;
     85        private byte[] data;
    6286
    6387        @Override
     
    6690            this.ready = true;
    6791            this.result = result;
     92            if (data != null) {
     93                this.data = data.content;
     94            }
    6895            this.notifyAll();
    6996        }
     
    113140        String key = "key_unknown_host";
    114141        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key);
    115         Listener listener = new Listener();
    116         job.submit(listener, true);
    117         synchronized (listener) {
    118             while (!listener.ready) {
    119                 try {
    120                     listener.wait();
    121                 } catch (InterruptedException e1) {
    122                     // do nothing, still wait
    123                     Logging.trace(e1);
    124                 }
    125             }
    126         }
     142        Listener listener = submitJob(job);
    127143        assertEquals(LoadResult.FAILURE, listener.result); // because response will be cached, and that is checked below
    128144        assertEquals("java.net.UnknownHostException: unkownhost.unkownhost", listener.attributes.getErrorMessage());
     
    135151
    136152        job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key);
    137         listener = new Listener();
    138         job.submit(listener, true);
     153        listener = submitJob(job);
     154        assertEquals(LoadResult.SUCCESS, listener.result);
     155        assertFalse(job.isCacheElementValid());
     156    }
     157
     158    private void doTestStatusCode(int responseCode) throws IOException {
     159        TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode);
     160        Listener listener = submitJob(job);
     161        assertEquals(responseCode, listener.attributes.getResponseCode());
     162    }
     163
     164    private Listener submitJob(TestCachedTileLoaderJob job) throws IOException {
     165        return submitJob(job, true);
     166    }
     167
     168    private Listener submitJob(TestCachedTileLoaderJob job, boolean force) throws IOException {
     169        Listener listener = new Listener();
     170        job.submit(listener, force);
    139171        synchronized (listener) {
    140172            while (!listener.ready) {
    141173                try {
    142174                    listener.wait();
    143                 } catch (InterruptedException e1) {
     175                } catch (InterruptedException e) {
    144176                    // do nothing, wait
    145                     Logging.trace(e1);
     177                    Logging.trace(e);
    146178                }
    147179            }
    148180        }
    149         assertEquals(LoadResult.SUCCESS, listener.result);
    150         assertFalse(job.isCacheElementValid());
    151     }
    152 
    153     @SuppressFBWarnings(value = "WA_NOT_IN_LOOP")
    154     private void doTestStatusCode(int responseCode) throws IOException, InterruptedException {
    155         TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode);
    156         Listener listener = new Listener();
    157         job.submit(listener, true);
    158         synchronized (listener) {
    159             if (!listener.ready) {
    160                 listener.wait();
    161             }
    162         }
    163         assertEquals(responseCode, listener.attributes.getResponseCode());
    164     }
    165 
    166     private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode) throws IOException {
     181        return listener;
     182    }
     183
     184    /**
     185     * That no requst is made when entry is in cache and force == false
     186     * @throws IOException
     187     */
     188    @Test
     189    public void testNoRequestMadeWhenEntryInCache() throws IOException {
     190        ICacheAccess<String, CacheEntry> cache = getCache();
     191        long expires = TimeUnit.DAYS.toMillis(1);
     192        long testStart = System.currentTimeMillis();
     193        cache.put("test",
     194                new CacheEntry("cached entry".getBytes(StandardCharsets.UTF_8)),
     195                createEntryAttributes(expires, 200, testStart, "eTag")
     196                );
     197        createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry");
     198
     199        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     200        Listener listener = submitJob(job, false);
     201        tileServer.verify(0, WireMock.getRequestedFor(WireMock.anyUrl()));
     202        assertArrayEquals("cached entry".getBytes(StandardCharsets.UTF_8), listener.data);
     203    }
     204
     205    /**
     206     * that request is made, when object is in cache, but force mode is used
     207     * @throws IOException
     208     */
     209    @Test
     210    public void testRequestMadeWhenEntryInCacheAndForce() throws IOException {
     211        ICacheAccess<String, CacheEntry> cache = getCache();
     212        long expires =  TimeUnit.DAYS.toMillis(1);
     213        long testStart = System.currentTimeMillis();
     214        cache.put("test",
     215                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
     216                createEntryAttributes(expires, 200, testStart + expires, "eTag")
     217                );
     218        createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry");
     219
     220        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     221        Listener listener = submitJob(job, true);
     222        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     223        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     224    }
     225
     226    /**
     227     * Mock returns no cache-control / expires headers
     228     * Expire time should be set to DEFAULT_EXPIRE_TIME
     229     * @throws IOException
     230     */
     231    @Test
     232    public void testSettingMinimumExpiryWhenNoExpires() throws IOException {
     233        long testStart = System.currentTimeMillis();
     234        tileServer.stubFor(
     235                WireMock.get(WireMock.urlEqualTo("/test"))
     236                .willReturn(WireMock.aResponse()
     237                        .withBody("mock entry")
     238                        )
     239                );
     240
     241        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     242        Listener listener = submitJob(job, false);
     243        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     244
     245        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
     246                JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)",
     247                listener.attributes.getExpirationTime() >= testStart + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME);
     248
     249        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
     250                JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)",
     251                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME);
     252
     253        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     254    }
     255
     256    /**
     257     * Mock returns expires headers, but Cache-Control
     258     * Expire time should be set to max-age
     259     * @throws IOException
     260     */
     261    @Test
     262    public void testSettingExpireByMaxAge() throws IOException {
     263        long testStart = System.currentTimeMillis();
     264        long expires =  TimeUnit.DAYS.toSeconds(1);
     265        tileServer.stubFor(
     266                WireMock.get(WireMock.urlEqualTo("/test"))
     267                .willReturn(WireMock.aResponse()
     268                        .withHeader("Cache-control", "max-age=" + expires)
     269                        .withBody("mock entry")
     270                        )
     271                );
     272
     273        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     274        Listener listener = submitJob(job, false);
     275        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     276
     277        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
     278                TimeUnit.SECONDS.toMillis(expires) + " (max-age)",
     279                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(expires));
     280
     281        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
     282                TimeUnit.SECONDS.toMillis(expires) + " (max-age)",
     283                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expires));
     284
     285        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     286    }
     287
     288    /**
     289     * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10
     290     * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2
     291     * @throws IOException
     292     */
     293    @Test
     294    public void testSettingMinimumExpiryByMinimumExpiryTimeLessThanDefault() throws IOException {
     295        long testStart = System.currentTimeMillis();
     296        int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2);
     297
     298        createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry");
     299
     300        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds);
     301        Listener listener = submitJob(job, false);
     302        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     303        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     304
     305
     306        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
     307                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
     308                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) );
     309
     310        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
     311                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
     312                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds));
     313    }
     314
     315    /**
     316     * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10
     317     * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2
     318     * @throws IOException
     319     */
     320
     321    @Test
     322    public void testSettingMinimumExpiryByMinimumExpiryTimeGreaterThanDefault() throws IOException {
     323        long testStart = System.currentTimeMillis();
     324        int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2);
     325
     326        createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry");
     327
     328        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds);
     329        Listener listener = submitJob(job, false);
     330        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     331        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     332
     333
     334        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
     335                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
     336                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) );
     337
     338        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
     339                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
     340                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds));
     341    }
     342
     343    /**
     344     * Check if verifying cache entries using HEAD requests work properly
     345     * @throws IOException
     346     */
     347    @Test
     348    public void testCheckUsingHead() throws IOException {
     349        ICacheAccess<String, CacheEntry> cache = getCache();
     350        long expires = TimeUnit.DAYS.toMillis(1);
     351        long testStart = System.currentTimeMillis();
     352        cache.put("test",
     353                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
     354                createEntryAttributes(-1 * expires, 200, testStart, "eTag--gzip") // Jetty adds --gzip to etags when compressing output
     355                );
     356
     357        tileServer.stubFor(
     358                WireMock.get(WireMock.urlEqualTo("/test"))
     359                .willReturn(WireMock.aResponse()
     360                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
     361                        .withHeader("Last-Modified", Long.toString(testStart))
     362                        .withHeader("ETag", "eTag") // Jetty adds "--gzip" suffix for compressed content
     363                        .withBody("mock entry")
     364                        )
     365                );
     366        tileServer.stubFor(
     367                WireMock.head(WireMock.urlEqualTo("/test"))
     368                .willReturn(WireMock.aResponse()
     369                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
     370                        .withHeader("Last-Modified", Long.toString(testStart))
     371                        .withHeader("ETag", "eTag--gzip") // but doesn't add to uncompressed
     372                        )
     373                );
     374
     375        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     376        Listener listener = submitJob(job, false); // cache entry is expired, no need to force refetch
     377        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     378        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     379
     380        // cache entry should be retrieved from cache
     381        listener = submitJob(job, false);
     382        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     383        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     384
     385        // invalidate entry in cache
     386        ICacheElement<String, CacheEntry> cacheEntry = cache.getCacheElement("test");
     387        CacheEntryAttributes attributes = (CacheEntryAttributes)cacheEntry.getElementAttributes();
     388        attributes.setExpirationTime(testStart - TimeUnit.DAYS.toMillis(1));
     389        cache.put("test", cacheEntry.getVal(), attributes);
     390
     391        // because cache entry is invalid - HEAD request shall be made
     392        tileServer.verify(0, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // no head requests were made until now
     393        listener = submitJob(job, false);
     394        tileServer.verify(1, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // verify head requests were made
     395        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // verify no more get requests were made
     396        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     397        assertTrue(listener.attributes.getExpirationTime() >= testStart + expires);
     398
     399        // cache entry should be retrieved from cache
     400        listener = submitJob(job, false); // cache entry is expired, no need to force refetch
     401        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     402        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     403        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
     404    }
     405
     406    /**
     407     * Check if server returns 304 - it will update cache attributes and not ask again for it
     408     * @throws IOException
     409     */
     410    @Test
     411    public void testCheckUsing304() throws IOException {
     412        ICacheAccess<String, CacheEntry> cache = getCache();
     413        long expires = TimeUnit.DAYS.toMillis(1);
     414        long testStart = System.currentTimeMillis();
     415        cache.put("test",
     416                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
     417                createEntryAttributes(-1 * expires, 200, testStart, "eTag")
     418                );
     419
     420        tileServer.stubFor(
     421                WireMock.get(WireMock.urlEqualTo("/test"))
     422                .willReturn(WireMock.status(304)
     423                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
     424                        .withHeader("Last-Modified", Long.toString(testStart))
     425                        .withHeader("ETag", "eTag")
     426                        )
     427                );
     428
     429        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
     430        Listener listener = submitJob(job, false);
     431        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     432        assertArrayEquals("cached dummy".getBytes(StandardCharsets.UTF_8), listener.data);
     433        assertTrue(testStart + expires <= listener.attributes.getExpirationTime());
     434        listener = submitJob(job, false);
     435        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // no more requests were made
     436    }
     437
     438    private void createHeadGetStub(UrlPattern url, long expires, long lastModified, String eTag, String body) {
     439        tileServer.stubFor(
     440                WireMock.get(url)
     441                .willReturn(WireMock.aResponse()
     442                        .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires))
     443                        .withHeader("Last-Modified", Long.toString(lastModified))
     444                        .withHeader("ETag", eTag)
     445                        .withBody(body)
     446                        )
     447                );
     448        tileServer.stubFor(
     449                WireMock.head(url)
     450                .willReturn(WireMock.aResponse()
     451                        .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires))
     452                        .withHeader("Last-Modified", Long.toString(lastModified))
     453                        .withHeader("ETag", eTag)
     454                        )
     455                );
     456    }
     457
     458    private CacheEntryAttributes createEntryAttributes(long maxAge, int responseCode, String eTag) {
     459        long validTo = maxAge + System.currentTimeMillis();
     460        return createEntryAttributes(maxAge, responseCode, validTo, eTag);
     461    }
     462
     463    private CacheEntryAttributes createEntryAttributes(long expirationTime, int responseCode, long lastModification, String eTag) {
     464        CacheEntryAttributes entryAttributes = new CacheEntryAttributes();
     465        entryAttributes.setExpirationTime(lastModification + expirationTime);
     466        entryAttributes.setResponseCode(responseCode);
     467        entryAttributes.setLastModification(lastModification);
     468        entryAttributes.setEtag(eTag);
     469        return entryAttributes;
     470    }
     471
     472    private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode)  {
    167473        return new TestCachedTileLoaderJob("http://httpstat.us/" + responseCode, "key_" + responseCode);
    168474    }
    169475
    170     private static ICacheAccess<String, CacheEntry> getCache() throws IOException {
     476    private static ICacheAccess<String, CacheEntry> getCache() {
    171477        return JCSCacheManager.getCache("test");
    172478    }
  • trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java

    r13631 r13733  
    22package org.openstreetmap.josm.data.imagery;
    33
     4import static org.junit.Assert.assertArrayEquals;
    45import static org.junit.Assert.assertEquals;
    56import static org.junit.Assert.assertTrue;
    67
     8import java.io.IOException;
     9import java.net.MalformedURLException;
     10import java.net.URL;
     11import java.nio.charset.StandardCharsets;
     12import java.util.concurrent.Executors;
     13import java.util.concurrent.ThreadPoolExecutor;
     14import java.util.concurrent.TimeUnit;
    715import java.util.regex.Matcher;
    816
     17import org.apache.commons.jcs.access.behavior.ICacheAccess;
     18import org.junit.Before;
    919import org.junit.Rule;
    1020import org.junit.Test;
     21import org.openstreetmap.gui.jmapviewer.Tile;
     22import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
     23import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource;
     24import org.openstreetmap.josm.TestUtils;
     25import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
     26import org.openstreetmap.josm.data.cache.CacheEntryAttributes;
     27import org.openstreetmap.josm.data.cache.JCSCacheManager;
    1128import org.openstreetmap.josm.testutils.JOSMTestRules;
     29import org.openstreetmap.josm.tools.Logging;
    1230import org.openstreetmap.josm.tools.Utils;
     31
     32import com.github.tomakehurst.wiremock.client.WireMock;
     33import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
     34import com.github.tomakehurst.wiremock.junit.WireMockRule;
    1335
    1436import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    2446    @Rule
    2547    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    26     public JOSMTestRules test = new JOSMTestRules();
     48    public JOSMTestRules test = new JOSMTestRules().preferences();
     49
     50    /**
     51     * mocked tile server
     52     */
     53    @Rule
     54    public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options()
     55            .dynamicPort());
     56
     57    @Before
     58    public void clearCache() throws Exception {
     59        getCache().clear();
     60    }
     61
     62    private static ICacheAccess<String, BufferedImageCacheEntry> getCache() {
     63        return JCSCacheManager.getCache("test");
     64    }
     65
     66    private static class TestCachedTileLoaderJob extends TMSCachedTileLoaderJob {
     67        private String url;
     68        private String key;
     69
     70        TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key) throws IOException  {
     71            this(listener, tile, key,  (int) TimeUnit.DAYS.toSeconds(1));
     72        }
     73
     74        TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key, int minimumExpiry) throws IOException  {
     75            super(listener, tile, getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry),
     76                    (ThreadPoolExecutor) Executors.newFixedThreadPool(1));
     77
     78            this.url = tile.getUrl();
     79            this.key = key;
     80        }
     81
     82        @Override
     83        public URL getUrl() {
     84            try {
     85                return new URL(url);
     86            } catch (MalformedURLException e) {
     87                throw new RuntimeException(e);
     88            }
     89        }
     90
     91        @Override
     92        protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
     93            return new BufferedImageCacheEntry(content);
     94        }
     95
     96        public CacheEntryAttributes getAttributes() {
     97            return attributes;
     98        }
     99
     100        @Override
     101        public boolean isObjectLoadable() {
     102            // use implementation from grand parent, to avoid calling getImage on dummy data
     103            if (cacheData == null) {
     104                return false;
     105            }
     106            return cacheData.getContent().length > 0;        }
     107    }
     108
     109    private static class Listener implements TileLoaderListener {
     110        private CacheEntryAttributes attributes;
     111        private boolean ready;
     112        private byte[] data;
     113
     114
     115        @Override
     116        public synchronized void tileLoadingFinished(Tile tile, boolean success) {
     117            ready = true;
     118            this.notifyAll();
     119        }
     120    }
     121
     122    private static class MockTile extends Tile {
     123        MockTile(String url) {
     124            super(new MockTileSource(url), 0, 0, 0);
     125        }
     126    }
     127
     128    private static class MockTileSource extends TMSTileSource {
     129        private final String url;
     130
     131        public MockTileSource(String url) {
     132            super(new ImageryInfo("mock"));
     133            this.url = url;
     134        }
     135
     136        @Override
     137        public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
     138            return url;
     139        }
     140    }
    27141
    28142    /**
     
    53167        assertEquals(expected, Utils.strip(m.group(1)));
    54168    }
     169
     170    private TestCachedTileLoaderJob submitJob(MockTile tile, String key, boolean force) throws IOException {
     171        return submitJob(tile, key, 0, force);
     172    }
     173
     174    private TestCachedTileLoaderJob submitJob(MockTile tile, String key, int minimumExpiry, boolean force) throws IOException {
     175        Listener listener = new Listener();
     176        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(listener, tile, key, minimumExpiry);
     177        job.submit(force);
     178        synchronized (listener) {
     179            while (!listener.ready) {
     180                try {
     181                    listener.wait();
     182                } catch (InterruptedException e) {
     183                    // do nothing, wait
     184                    Logging.trace(e);
     185                }
     186            }
     187        }
     188        return job;
     189    }
     190
     191    /**
     192     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least MINIMUM_EXPIRES
     193     * @throws IOException
     194     */
     195    @Test
     196    public void testNoCacheHeaders() throws IOException {
     197        long testStart = System.currentTimeMillis();
     198        tileServer.stubFor(
     199                WireMock.get(WireMock.urlEqualTo("/test"))
     200                .willReturn(WireMock.aResponse()
     201                        .withBody("mock entry")
     202                        )
     203                );
     204
     205        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
     206        assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job);
     207        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     208        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
     209        // only one request to tile server should be made, second should come from cache
     210        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     211        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     212    }
     213
     214    /**
     215     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter
     216     * @throws IOException
     217     */
     218    @Test
     219    public void testNoCacheHeadersMinimumExpires() throws IOException {
     220        noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() * 2));
     221    }
     222
     223    /**
     224     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter,
     225     * which is larger than MAXIMUM_EXPIRES
     226     * @throws IOException
     227     */
     228
     229    @Test
     230    public void testNoCacheHeadersMinimumExpiresLargerThanMaximum() throws IOException {
     231        noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2));
     232    }
     233
     234    private void noCacheHeadersMinimumExpires(int minimumExpires) throws IOException {
     235        long testStart = System.currentTimeMillis();
     236        tileServer.stubFor(
     237                WireMock.get(WireMock.urlEqualTo("/test"))
     238                .willReturn(WireMock.aResponse()
     239                        .withBody("mock entry")
     240                        )
     241                );
     242        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", minimumExpires, false);
     243        assertExpirationAtLeast(testStart + minimumExpires, job);
     244        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     245        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
     246        // only one request to tile server should be made, second should come from cache
     247        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     248        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     249    }
     250
     251    /**
     252     * When tile server returns Expires header shorter than MINIMUM_EXPIRES, we should cache if for at least MINIMUM_EXPIRES
     253     * @throws IOException
     254     */
     255    @Test
     256    public void testShortExpire() throws IOException {
     257        long testStart = System.currentTimeMillis();
     258        long expires = TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() / 2;
     259        tileServer.stubFor(
     260                WireMock.get(WireMock.urlEqualTo("/test"))
     261                .willReturn(WireMock.aResponse()
     262                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
     263                        .withBody("mock entry")
     264                        )
     265                );
     266        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
     267        assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job);
     268        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     269        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
     270        // only one request to tile server should be made, second should come from cache
     271        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     272        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     273    }
     274
     275    private void assertExpirationAtLeast(long duration, TestCachedTileLoaderJob job) {
     276        assertTrue(
     277                "Expiration time shorter by " +
     278                        -1 * (job.getAttributes().getExpirationTime() - duration) +
     279                        " than expected",
     280                job.getAttributes().getExpirationTime() >= duration);
     281    }
     282
     283    private void assertExpirationAtMost(long duration, TestCachedTileLoaderJob job) {
     284        assertTrue(
     285                "Expiration time longer by " +
     286                        (job.getAttributes().getExpirationTime() - duration) +
     287                        " than expected",
     288                job.getAttributes().getExpirationTime() <= duration);
     289    }
     290
     291
     292    @Test
     293    public void testLongExpire() throws IOException {
     294        long testStart = System.currentTimeMillis();
     295        long expires = TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2;
     296        tileServer.stubFor(
     297                WireMock.get(WireMock.urlEqualTo("/test"))
     298                .willReturn(WireMock.aResponse()
     299                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
     300                        .withBody("mock entry")
     301                        )
     302                );
     303        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
     304        // give 1 second margin
     305        assertExpirationAtMost(testStart + TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() + TimeUnit.SECONDS.toMillis(1), job);
     306
     307        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     308        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
     309        // only one request to tile server should be made, second should come from cache
     310        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
     311        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
     312    }
     313
    55314}
  • trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java

    r12669 r13733  
    88import java.io.IOException;
    99import java.net.MalformedURLException;
     10import java.nio.file.Files;
     11import java.nio.file.Paths;
    1012import java.util.ArrayList;
    11 import java.util.Collection;
    12 
     13import java.util.Arrays;
     14import java.util.List;
     15
     16import org.junit.ClassRule;
    1317import org.junit.Ignore;
    14 import org.junit.Rule;
    1518import org.junit.Test;
    1619import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
     
    1922import org.openstreetmap.josm.data.Bounds;
    2023import org.openstreetmap.josm.data.coor.LatLon;
     24import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
     25import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
    2126import org.openstreetmap.josm.data.projection.Projections;
     27import org.openstreetmap.josm.spi.preferences.Config;
    2228import org.openstreetmap.josm.testutils.JOSMTestRules;
     29
     30import com.github.tomakehurst.wiremock.WireMockServer;
     31import com.github.tomakehurst.wiremock.client.WireMock;
    2332
    2433import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    2837 */
    2938public class WMTSTileSourceTest {
     39
     40    /**
     41     * Setup test.
     42     */
     43    @ClassRule
     44    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     45    public static JOSMTestRules test = new JOSMTestRules().preferences().platform();
    3046
    3147    private ImageryInfo testImageryTMS = new ImageryInfo("test imagery", "http://localhost", "tms", null, null);
     
    4460            "wmts/bug13975-multiple-tile-matrices-for-one-layer-projection.xml");
    4561
    46     /**
    47      * Setup test.
    48      */
    49     @Rule
    50     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    51     public JOSMTestRules test = new JOSMTestRules();
    5262
    5363    private static ImageryInfo getImagery(String path) {
    5464        try {
    55             return new ImageryInfo(
     65            ImageryInfo ret = new ImageryInfo(
    5666                    "test",
    5767                    new File(path).toURI().toURL().toString()
    5868                    );
     69            ret.setImageryType(ImageryType.WMTS);
     70            return ret;
    5971        } catch (MalformedURLException e) {
    6072            e.printStackTrace();
     
    6476
    6577    @Test
    66     public void testPseudoMercator() throws IOException {
     78    public void testPseudoMercator() throws IOException, WMTSGetCapabilitiesException {
    6779        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    6880        WMTSTileSource testSource = new WMTSTileSource(testImageryPSEUDO_MERCATOR);
     
    94106
    95107    @Test
    96     public void testWALLONIE() throws IOException {
     108    public void testWALLONIE() throws IOException, WMTSGetCapabilitiesException {
    97109        Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
    98110        WMTSTileSource testSource = new WMTSTileSource(testImageryWALLONIE);
     
    114126    @Test
    115127    @Ignore("disable this test, needs further working") // XXX
    116     public void testWALLONIENoMatrixDimension() throws IOException {
     128    public void testWALLONIENoMatrixDimension() throws IOException, WMTSGetCapabilitiesException {
    117129        Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
    118130        WMTSTileSource testSource = new WMTSTileSource(getImagery("test/data/wmts/WMTSCapabilities-Wallonie-nomatrixdimension.xml"));
     
    138150
    139151    @Test
    140     public void testWIEN() throws IOException {
     152    public void testWIEN() throws IOException, WMTSGetCapabilitiesException {
    141153        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    142154        WMTSTileSource testSource = new WMTSTileSource(testImageryWIEN);
     
    180192
    181193    @Test
    182     public void testGeoportalTOPOPL() throws IOException {
     194    public void testGeoportalTOPOPL() throws IOException, WMTSGetCapabilitiesException {
    183195        Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
    184196        WMTSTileSource testSource = new WMTSTileSource(testImageryTOPO_PL);
     
    202214
    203215    @Test
    204     public void testGeoportalORTOPL4326() throws IOException {
     216    public void testGeoportalORTOPL4326() throws IOException, WMTSGetCapabilitiesException {
    205217        Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
    206218        WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
     
    211223
    212224    @Test
    213     public void testGeoportalORTOPL2180() throws IOException {
     225    public void testGeoportalORTOPL2180() throws IOException, WMTSGetCapabilitiesException {
    214226        Main.setProjection(Projections.getProjectionByCode("EPSG:2180"));
    215227        WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
     
    221233
    222234    @Test
    223     public void testTicket12168() throws IOException {
     235    public void testTicket12168() throws IOException, WMTSGetCapabilitiesException {
    224236        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    225237        WMTSTileSource testSource = new WMTSTileSource(testImagery12168);
     
    231243
    232244    @Test
    233     @Ignore("disabled as this needs user action") // XXX
    234245    public void testTwoTileSetsForOneProjection() throws Exception {
    235246        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    236         WMTSTileSource testSource = new WMTSTileSource(testImageryOntario);
    237         testSource.initProjection(Main.getProjection());
    238         verifyTile(new LatLon(45.4105023, -75.7153702), testSource, 303751, 375502, 12);
    239         verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 1186, 1466, 4);
    240     }
    241 
    242     @Test
    243     @Ignore("disabled as this needs user action") // XXX
     247        ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
     248        ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
     249                new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "default028mm")
     250        }));
     251        WMTSTileSource testSource = new WMTSTileSource(ontario);
     252        testSource.initProjection(Main.getProjection());
     253        assertEquals(
     254                "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/default028mm/4/2932/2371.jpg",
     255                testSource.getTileUrl(4, 2371, 2932));
     256        verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 2372, 2932, 4);
     257        verifyTile(new LatLon(45.4602510, -75.7617187), testSource, 607232, 750591, 12);
     258    }
     259
     260    @Test
     261    public void testTwoTileSetsForOneProjectionSecondLayer() throws Exception {
     262        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
     263        ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
     264        ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
     265                new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "GoogleMapsCompatible")
     266        }));
     267        WMTSTileSource testSource = new WMTSTileSource(ontario);
     268        testSource.initProjection(Main.getProjection());
     269        assertEquals(
     270                "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/GoogleMapsCompatible/4/2932/2371.jpg",
     271                testSource.getTileUrl(4, 2371, 2932));
     272        verifyMercatorTile(testSource, 74, 91, 8);
     273        verifyMercatorTile(testSource, 37952, 46912, 17);
     274    }
     275
     276    @Test
    244277    public void testManyLayersScrollbars() throws Exception {
    245278        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
     
    271304        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    272305        ImageryInfo copy = new ImageryInfo(testMultipleTileMatrixForLayer);
    273         Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
    274         defaultLayers.add(new WMTSDefaultLayer("Mashhad_BaseMap_1", "default028mm"));
     306        List<DefaultLayer> defaultLayers = new ArrayList<>(1);
     307        defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "Mashhad_BaseMap_1", null, "default028mm"));
    275308        copy.setDefaultLayers(defaultLayers);
    276309        WMTSTileSource testSource = new WMTSTileSource(copy);
     
    286319     * Test WMTS dimension.
    287320     * @throws IOException if any I/O error occurs
     321     * @throws WMTSGetCapabilitiesException
    288322     */
    289323    @Test
    290     public void testDimension() throws IOException {
     324    public void testDimension() throws IOException, WMTSGetCapabilitiesException {
    291325        Main.setProjection(Projections.getProjectionByCode("EPSG:21781"));
    292326        ImageryInfo info = new ImageryInfo(testImageryGeoAdminCh);
    293         Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
    294         defaultLayers.add(new WMTSDefaultLayer("ch.are.agglomerationen_isolierte_staedte", "21781_26"));
     327        List<DefaultLayer> defaultLayers = new ArrayList<>(1);
     328        defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "ch.are.agglomerationen_isolierte_staedte", null, "21781_26"));
    295329        info.setDefaultLayers(defaultLayers);
    296330        WMTSTileSource testSource = new WMTSTileSource(info);
     
    300334                testSource.getTileUrl(1, 2, 3)
    301335                );
     336    }
     337
     338    @Test
     339    public void testDefaultLayer() throws Exception {
     340        // https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/1.0.0/WMTSCapabilities.xml
     341        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
     342        String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wmts/getCapabilities-lots-of-layers.xml")), "UTF-8");
     343        // do not use withFileBody as it needs different directory layout :(
     344        getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody)));
     345        getCapabilitiesMock.start();
     346
     347        WireMockServer mapsMock = TestUtils.getWireMockServer();
     348        mapsMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(
     349                "<?xml version='1.0' encoding='UTF-8'?>\n" +
     350                "<imagery xmlns=\"http://josm.openstreetmap.de/maps-1.0\">\n" +
     351                "<entry>\n" +
     352                "<name>Landsat</name>\n" +
     353                "<id>landsat</id>\n" +
     354                "<type>wmts</type>\n" +
     355                "<url><![CDATA[" + getCapabilitiesMock.url("/getcapabilities.xml") + "]]></url>\n" +
     356                "<defaultLayers>" +
     357                "<layer name=\"GEOGRAPHICALGRIDSYSTEMS.MAPS\" />" +
     358                "</defaultLayers>" +
     359                "</entry>\n" +
     360                "</imagery>"
     361                )));
     362        mapsMock.start();
     363        Config.getPref().put("josm.url", mapsMock.url("/"));
     364
     365        ImageryLayerInfo.instance.loadDefaults(true, null, false);
     366
     367        assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size());
     368        ImageryInfo wmtsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0);
     369        assertEquals(1, wmtsImageryInfo.getDefaultLayers().size());
     370        assertEquals("GEOGRAPHICALGRIDSYSTEMS.MAPS", wmtsImageryInfo.getDefaultLayers().get(0).getLayerName());
     371        WMTSTileSource tileSource = new WMTSTileSource(wmtsImageryInfo);
     372        tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857"));
     373        assertEquals("http://wxs.ign.fr/61fs25ymczag0c67naqvvmap/geoportail/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&"
     374                + "LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS"
     375                + "&STYLE=normal&FORMAT=image/jpeg&tileMatrixSet=PM&tileMatrix=1&tileRow=1&tileCol=1", tileSource.getTileUrl(1, 1, 1));
     376
    302377    }
    303378
  • trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java

    r12636 r13733  
    120120            return new TileLoaderFactory() {
    121121                @Override
    122                 public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers) {
     122                public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers,
     123                        long minimumExpiryTime) {
    123124                    return null;
    124125                }
  • trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java

    r13710 r13733  
    2222    @Rule
    2323    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    24     public JOSMTestRules test = new JOSMTestRules().timeout(20000);
     24    public JOSMTestRules test = new JOSMTestRules().preferences().timeout(20000);
    2525
    2626    /**
  • trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java

    r13699 r13733  
    66
    77import java.io.IOException;
    8 import java.io.InputStream;
     8import java.nio.file.Files;
     9import java.nio.file.Path;
     10import java.nio.file.Paths;
     11import java.util.List;
    912
    1013import org.junit.Rule;
     
    1316import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
    1417import org.openstreetmap.josm.testutils.JOSMTestRules;
     18
     19import com.github.tomakehurst.wiremock.WireMockServer;
     20import com.github.tomakehurst.wiremock.client.WireMock;
    1521
    1622import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    2632    @Rule
    2733    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    28     public JOSMTestRules test = new JOSMTestRules();
     34    public JOSMTestRules test = new JOSMTestRules().platform().projection();
    2935
    3036    /**
     
    4955    @Test
    5056    public void testTicket15730() throws IOException, WMSGetCapabilitiesException {
    51         try (InputStream is = TestUtils.getRegressionDataStream(15730, "capabilities.xml")) {
    52             WMSImagery wms = new WMSImagery();
    53             wms.parseCapabilities(null, is);
    54             assertEquals(1, wms.getLayers().size());
    55             assertTrue(wms.getLayers().get(0).abstr.startsWith("South Carolina  NAIP Imagery 2017    Resolution: 100CM "));
    56         }
     57       WireMockServer wm = TestUtils.getWireMockServer(15730);
     58       wm.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBodyFile("capabilities.xml")));
     59       wm.start();
     60       WMSImagery wms = new WMSImagery(wm.url("capabilities.xml"));
     61       assertEquals(1, wms.getLayers().size());
     62       assertTrue(wms.getLayers().get(0).getAbstract().startsWith("South Carolina  NAIP Imagery 2017    Resolution: 100CM "));
     63       wm.shutdown();
     64    }
     65
     66    @Test
     67    public void testNestedLayers() throws Exception {
     68        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
     69        String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wms/mapa-um-warszawa-pl.xml")), "UTF-8");
     70        getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody)));
     71        getCapabilitiesMock.start();
     72        WMSImagery wmsi = new WMSImagery(getCapabilitiesMock.url("/serwis"));
     73        assertEquals(1, wmsi.getLayers().size());
     74        assertEquals("Server WMS m.st. Warszawy", wmsi.getLayers().get(0).toString());
     75        assertEquals(202, wmsi.getLayers().get(0).getChildren().size());
    5776    }
    5877
     
    6483    @Test
    6584    public void testTicket16248() throws IOException, WMSGetCapabilitiesException {
    66         try (InputStream is = TestUtils.getRegressionDataStream(16248, "capabilities.xml")) {
    67             WMSImagery wms = new WMSImagery();
    68             wms.parseCapabilities(null, is);
    69             assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.getServiceUrl().toExternalForm());
    70         }
     85        Path capabilitiesPath = Paths.get(TestUtils.getRegressionDataFile(16248, "capabilities.xml"));
     86        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
     87        getCapabilitiesMock.stubFor(
     88                WireMock.get(WireMock.anyUrl())
     89                .willReturn(WireMock.aResponse().withBody(Files.readAllBytes(capabilitiesPath))));
     90        getCapabilitiesMock.start();
     91        WMSImagery wms = new WMSImagery(getCapabilitiesMock.url("any"));
     92        assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.buildRootUrl());
     93        assertEquals("wms.hgis.cartomatic.pl", wms.getLayers().get(0).getName());
     94        assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25kFORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&"
     95                + "LAYERS=wms.hgis.cartomatic.pl&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}",
     96                wms.buildGetMapUrl(wms.getLayers(), (List<String>)null, true));
    7197    }
    7298}
     99
Note: See TracChangeset for help on using the changeset viewer.