@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, mustExpireWithAnyOf = AFTER_WRITE, expireAfterWrite = Expire.ONE_MINUTE) public void getExpiresAfter_duration(CacheContext context, @ExpireAfterWrite Expiration<Integer, Integer> expireAfterWrite) { assertThat(expireAfterWrite.getExpiresAfter(), is(Duration.ofMinutes(1L))); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE) public void getExpiresAfter_duration(CacheContext context, @ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) { assertThat(expireAfterAccess.getExpiresAfter(), is(Duration.ofMinutes(1L))); }
@Test public void shouldSlowRequestRateOnMultipleFailedAttempts() { testSlowRequestRateOnMultipleFailedAttempts( 3, Duration.ofSeconds( 5 ) ); testSlowRequestRateOnMultipleFailedAttempts( 1, Duration.ofSeconds( 10 ) ); testSlowRequestRateOnMultipleFailedAttempts( 6, Duration.ofMinutes( 1 ) ); testSlowRequestRateOnMultipleFailedAttempts( 42, Duration.ofMinutes( 2 ) ); }
@Test void shouldConvertNanosOfDayToUTC() { int nanosOfDayLocal = 42; Duration offsetDuration = Duration.ofMinutes( 35 ); long nanosOfDayUTC = TemporalUtil.nanosOfDayToUTC( nanosOfDayLocal, (int) offsetDuration.getSeconds() ); assertEquals( nanosOfDayLocal - offsetDuration.toNanos(), nanosOfDayUTC ); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL, expiry = CacheExpiry.WRITE, expiryTime = Expire.ONE_MINUTE) public void putIfAbsent_insert(Cache<Integer, Integer> cache, CacheContext context, VarExpiration<Integer, Integer> expireAfterVar) { Integer key = context.absentKey(); Integer value = context.absentValue(); assertThat(expireAfterVar.putIfAbsent(key, value, Duration.ofMinutes(2L)), is(true)); assertThat(cache.getIfPresent(key), is(value)); assertThat(expireAfterVar.getExpiresAfter(key), is(Optional.of(Duration.ofMinutes(2L)))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(1L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL, expiry = CacheExpiry.WRITE, expiryTime = Expire.ONE_MINUTE) public void putIfAbsent_present(Cache<Integer, Integer> cache, CacheContext context, VarExpiration<Integer, Integer> expireAfterVar) { Integer key = context.firstKey(); Integer value = context.absentValue(); assertThat(expireAfterVar.putIfAbsent(key, value, Duration.ofMinutes(2L)), is(false)); assertThat(cache.getIfPresent(key), is(context.original().get(key))); assertThat(expireAfterVar.getExpiresAfter(key), is(Optional.of(Duration.ofMinutes(1L)))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(0L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, expireAfterAccess = Expire.ONE_MINUTE) public void setExpiresAfter_duration(Cache<Integer, Integer> cache, CacheContext context, @ExpireAfterAccess Expiration<Integer, Integer> expireAfterAccess) { expireAfterAccess.setExpiresAfter(Duration.ofMinutes(2L)); assertThat(expireAfterAccess.getExpiresAfter(), is(Duration.ofMinutes(2L))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, mustExpireWithAnyOf = AFTER_WRITE, expireAfterWrite = Expire.ONE_MINUTE) public void setExpiresAfter_duration(Cache<Integer, Integer> cache, CacheContext context, @ExpireAfterWrite Expiration<Integer, Integer> expireAfterWrite) { expireAfterWrite.setExpiresAfter(Duration.ofMinutes(2)); assertThat(expireAfterWrite.getExpiresAfter(), is(Duration.ofMinutes(2L))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL, expiry = CacheExpiry.MOCKITO, expiryTime = Expire.ONE_MINUTE) public void setExpiresAfter_duration(Cache<Integer, Integer> cache, CacheContext context, VarExpiration<Integer, Integer> expireAfterVar) { expireAfterVar.setExpiresAfter(context.firstKey(), Duration.ofMinutes(2L)); assertThat(expireAfterVar.getExpiresAfter(context.firstKey()), is(Optional.of(Duration.ofMinutes(2L)))); expireAfterVar.setExpiresAfter(context.absentKey(), Duration.ofMinutes(4L)); assertThat(expireAfterVar.getExpiresAfter(context.absentKey()), is(Optional.empty())); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(1L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL, expiry = CacheExpiry.WRITE, expiryTime = Expire.ONE_MINUTE) public void put_insert(Cache<Integer, Integer> cache, CacheContext context, VarExpiration<Integer, Integer> expireAfterVar) { Integer key = context.absentKey(); Integer value = context.absentValue(); expireAfterVar.put(key, value, Duration.ofMinutes(2L)); assertThat(cache.getIfPresent(key), is(value)); assertThat(expireAfterVar.getExpiresAfter(key), is(Optional.of(Duration.ofMinutes(2L)))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(1L)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.FULL, expiry = CacheExpiry.WRITE, expiryTime = Expire.ONE_MINUTE) public void put_replace(Cache<Integer, Integer> cache, CacheContext context, VarExpiration<Integer, Integer> expireAfterVar) { Integer key = context.firstKey(); Integer value = context.absentValue(); expireAfterVar.put(key, value, Duration.ofMinutes(2L)); assertThat(cache.getIfPresent(key), is(value)); assertThat(expireAfterVar.getExpiresAfter(key), is(Optional.of(Duration.ofMinutes(2L)))); context.ticker().advance(90, TimeUnit.SECONDS); cache.cleanUp(); assertThat(cache.estimatedSize(), is(1L)); }
@Test void durationValueIsRepresentedWithUnit() { assertEquals( "120000ms", valueToString( Duration.ofMinutes( 2 ) ) ); }
@Test public void initShouldCreateThreadPool() throws Throwable { ExecutorFactory mockExecutorFactory = mock( ExecutorFactory.class ); when( mockExecutorFactory.create( anyInt(), anyInt(), any(), anyInt(), anyBoolean(), any() ) ).thenReturn( Executors.newCachedThreadPool() ); ExecutorBoltScheduler scheduler = new ExecutorBoltScheduler( CONNECTOR_KEY, mockExecutorFactory, jobScheduler, logService, 0, 10, Duration.ofMinutes( 1 ), 0, ForkJoinPool.commonPool() ); scheduler.start(); verify( jobScheduler ).threadFactory( Group.BOLT_WORKER ); verify( mockExecutorFactory, times( 1 ) ).create( anyInt(), anyInt(), any( Duration.class ), anyInt(), anyBoolean(), any( ThreadFactory.class ) ); }
@Test public void expirationCheckPeriod() { DirectFieldAccessor accessor = new DirectFieldAccessor(this.store); Map<?,?> sessions = (Map<?, ?>) accessor.getPropertyValue("sessions"); assertNotNull(sessions); // Create 100 sessions IntStream.range(0, 100).forEach(i -> insertSession()); assertEquals(100, sessions.size()); // Force a new clock (31 min later), don't use setter which would clean expired sessions accessor.setPropertyValue("clock", Clock.offset(this.store.getClock(), Duration.ofMinutes(31))); assertEquals(100, sessions.size()); // Create 1 more which forces a time-based check (clock moved forward) insertSession(); assertEquals(1, sessions.size()); }
@Test public void shutdownShouldTerminateThreadPool() throws Throwable { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); ExecutorFactory mockExecutorFactory = mock( ExecutorFactory.class ); when( mockExecutorFactory.create( anyInt(), anyInt(), any(), anyInt(), anyBoolean(), any() ) ).thenReturn( cachedThreadPool ); ExecutorBoltScheduler scheduler = new ExecutorBoltScheduler( CONNECTOR_KEY, mockExecutorFactory, jobScheduler, logService, 0, 10, Duration.ofMinutes( 1 ), 0, ForkJoinPool.commonPool() ); scheduler.start(); scheduler.stop(); assertTrue( cachedThreadPool.isShutdown() ); }
@Test public void shouldSlowRequestRateOnMultipleFailedAttemptsWhereAttemptIsValid() { testSlowRequestRateOnMultipleFailedAttemptsWhereAttemptIsValid( 3, Duration.ofSeconds( 5 ) ); testSlowRequestRateOnMultipleFailedAttemptsWhereAttemptIsValid( 1, Duration.ofSeconds( 11 ) ); testSlowRequestRateOnMultipleFailedAttemptsWhereAttemptIsValid( 22, Duration.ofMinutes( 2 ) ); testSlowRequestRateOnMultipleFailedAttemptsWhereAttemptIsValid( 42, Duration.ofDays( 4 ) ); }
@Test public void retrieveExpiredSession() { WebSession session = this.store.createWebSession().block(); assertNotNull(session); session.getAttributes().put("foo", "bar"); session.save().block(); String id = session.getId(); WebSession retrieved = this.store.retrieveSession(id).block(); assertNotNull(retrieved); assertSame(session, retrieved); // Fast-forward 31 minutes this.store.setClock(Clock.offset(this.store.getClock(), Duration.ofMinutes(31))); WebSession retrievedAgain = this.store.retrieveSession(id).block(); assertNull(retrievedAgain); }
@Test public void expiredSessionEnds() throws Exception { // First request: no session yet, new session created RequestEntity<Void> request = RequestEntity.get(createUri()).build(); ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class); assertEquals(HttpStatus.OK, response.getStatusCode()); String id = extractSessionId(response.getHeaders()); assertNotNull(id); // Now fast-forward by 31 minutes InMemoryWebSessionStore store = (InMemoryWebSessionStore) this.sessionManager.getSessionStore(); store.setClock(Clock.offset(store.getClock(), Duration.ofMinutes(31))); // Second request: session expires URI uri = new URI("http://localhost:" + this.port + "/?expire"); request = RequestEntity.get(uri).header("Cookie", "SESSION=" + id).build(); response = this.restTemplate.exchange(request, Void.class); assertEquals(HttpStatus.OK, response.getStatusCode()); String value = response.getHeaders().getFirst("Set-Cookie"); assertNotNull(value); assertTrue("Actual value: " + value, value.contains("Max-Age=0")); }
@Test public void expiredSessionIsRecreated() throws Exception { // First request: no session yet, new session created RequestEntity<Void> request = RequestEntity.get(createUri()).build(); ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class); assertEquals(HttpStatus.OK, response.getStatusCode()); String id = extractSessionId(response.getHeaders()); assertNotNull(id); assertEquals(1, this.handler.getSessionRequestCount()); // Second request: same session request = RequestEntity.get(createUri()).header("Cookie", "SESSION=" + id).build(); response = this.restTemplate.exchange(request, Void.class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNull(response.getHeaders().get("Set-Cookie")); assertEquals(2, this.handler.getSessionRequestCount()); // Now fast-forward by 31 minutes InMemoryWebSessionStore store = (InMemoryWebSessionStore) this.sessionManager.getSessionStore(); WebSession session = store.retrieveSession(id).block(); assertNotNull(session); store.setClock(Clock.offset(store.getClock(), Duration.ofMinutes(31))); // Third request: expired session, new session created request = RequestEntity.get(createUri()).header("Cookie", "SESSION=" + id).build(); response = this.restTemplate.exchange(request, Void.class); assertEquals(HttpStatus.OK, response.getStatusCode()); id = extractSessionId(response.getHeaders()); assertNotNull("Expected new session id", id); assertEquals(1, this.handler.getSessionRequestCount()); }