Changeset 13733 in josm for trunk/test/unit/org/openstreetmap/josm/data/cache
- Timestamp:
- 2018-05-12T14:18:57+02:00 (7 years ago)
- Location:
- trunk/test/unit/org/openstreetmap/josm/data/cache
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java
r12620 r13733 14 14 import org.junit.Rule; 15 15 import org.junit.Test; 16 import org.openstreetmap.josm.data.imagery.TileJobOptions; 16 17 import org.openstreetmap.josm.testutils.JOSMTestRules; 17 18 import org.openstreetmap.josm.tools.Logging; … … 54 55 55 56 Task(ICacheAccess<String, CacheEntry> cache, URL url, AtomicInteger counter) { 56 super(cache, 1, 1, null); 57 super(cache, new TileJobOptions(1, 1, null, 10)); 57 58 this.url = url; 58 59 this.counter = counter; -
trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java
r13358 r13733 2 2 package org.openstreetmap.josm.data.cache; 3 3 4 import static org.junit.Assert.assertArrayEquals; 4 5 import static org.junit.Assert.assertEquals; 5 6 import static org.junit.Assert.assertFalse; 7 import static org.junit.Assert.assertTrue; 6 8 7 9 import java.io.IOException; … … 9 11 import java.net.URL; 10 12 import java.nio.charset.StandardCharsets; 13 import java.util.concurrent.TimeUnit; 11 14 12 15 import org.apache.commons.jcs.access.behavior.ICacheAccess; 16 import org.apache.commons.jcs.engine.behavior.ICacheElement; 13 17 import org.junit.Before; 14 18 import org.junit.Rule; 15 19 import org.junit.Test; 20 import org.openstreetmap.josm.TestUtils; 16 21 import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult; 22 import org.openstreetmap.josm.data.imagery.TileJobOptions; 17 23 import org.openstreetmap.josm.testutils.JOSMTestRules; 18 24 import org.openstreetmap.josm.tools.Logging; 25 26 import com.github.tomakehurst.wiremock.client.WireMock; 27 import com.github.tomakehurst.wiremock.core.WireMockConfiguration; 28 import com.github.tomakehurst.wiremock.junit.WireMockRule; 29 import com.github.tomakehurst.wiremock.matching.UrlPattern; 19 30 20 31 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; … … 25 36 public class JCSCachedTileLoaderJobTest { 26 37 38 /** 39 * mocked tile server 40 */ 41 @Rule 42 public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options() 43 .dynamicPort()); 44 27 45 private static class TestCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, CacheEntry> { 28 46 private String url; 29 47 private String key; 30 48 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)); 33 55 34 56 this.url = url; 35 57 this.key = key; 36 58 } 59 37 60 38 61 @Override … … 52 75 @Override 53 76 protected CacheEntry createCacheEntry(byte[] content) { 54 return new CacheEntry( "dummy".getBytes(StandardCharsets.UTF_8));77 return new CacheEntry(content); 55 78 } 56 79 } … … 60 83 private boolean ready; 61 84 private LoadResult result; 85 private byte[] data; 62 86 63 87 @Override … … 66 90 this.ready = true; 67 91 this.result = result; 92 if (data != null) { 93 this.data = data.content; 94 } 68 95 this.notifyAll(); 69 96 } … … 113 140 String key = "key_unknown_host"; 114 141 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); 127 143 assertEquals(LoadResult.FAILURE, listener.result); // because response will be cached, and that is checked below 128 144 assertEquals("java.net.UnknownHostException: unkownhost.unkownhost", listener.attributes.getErrorMessage()); … … 135 151 136 152 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); 139 171 synchronized (listener) { 140 172 while (!listener.ready) { 141 173 try { 142 174 listener.wait(); 143 } catch (InterruptedException e 1) {175 } catch (InterruptedException e) { 144 176 // do nothing, wait 145 Logging.trace(e 1);177 Logging.trace(e); 146 178 } 147 179 } 148 180 } 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) { 167 473 return new TestCachedTileLoaderJob("http://httpstat.us/" + responseCode, "key_" + responseCode); 168 474 } 169 475 170 private static ICacheAccess<String, CacheEntry> getCache() throws IOException{476 private static ICacheAccess<String, CacheEntry> getCache() { 171 477 return JCSCacheManager.getCache("test"); 172 478 }
Note:
See TracChangeset
for help on using the changeset viewer.