distributed-cache: Spring Cache abstraction over Hazelcast, Infinispan and Redis (post 29)
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
package com.ankurm.distributedcache;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* The same two behaviours, asserted identically, against whichever
|
||||
* CacheManager the active Spring profile wired up. That's deliberate:
|
||||
* the point of the Spring Cache abstraction is that ExchangeRateLookupService
|
||||
* and this test never change when the backend does - only the
|
||||
* subclass's @ActiveProfiles (and, for Redis, the container) changes.
|
||||
*
|
||||
* ExchangeRateLookupService's callCount() is a singleton counter shared
|
||||
* across every @Test method in a subclass's Spring context (JUnit does
|
||||
* not create a fresh context per test method), so each test reads the
|
||||
* counter before and after its own calls and asserts the *delta* rather
|
||||
* than an absolute value - that way test execution order inside one
|
||||
* class can never affect the result.
|
||||
*/
|
||||
abstract class CacheHitAndEvictionContractTest {
|
||||
|
||||
@Autowired
|
||||
ExchangeRateLookupService service;
|
||||
|
||||
abstract String backendName();
|
||||
|
||||
@Test
|
||||
void secondCallForSameKeyIsServedFromCache() {
|
||||
int before = service.callCount();
|
||||
|
||||
service.rateFor("USD/INR");
|
||||
int afterFirstCall = service.callCount();
|
||||
|
||||
service.rateFor("USD/INR");
|
||||
int afterSecondCall = service.callCount();
|
||||
|
||||
Transcript t = new Transcript("29-" + backendName() + "-cache-hit.txt");
|
||||
t.line("backend=%s", backendName());
|
||||
t.line("rateFor(\"USD/INR\") call 1 -> method body ran, callCount %d -> %d", before, afterFirstCall);
|
||||
t.line("rateFor(\"USD/INR\") call 2 -> served from cache, callCount stays %d", afterSecondCall);
|
||||
t.write();
|
||||
|
||||
assertThat(afterFirstCall).isEqualTo(before + 1);
|
||||
assertThat(afterSecondCall).isEqualTo(afterFirstCall);
|
||||
}
|
||||
|
||||
@Test
|
||||
void evictingAKeyForcesTheNextCallToRecompute() {
|
||||
int before = service.callCount();
|
||||
|
||||
service.rateFor("USD/EUR");
|
||||
int afterFirstCall = service.callCount();
|
||||
|
||||
service.evict("USD/EUR");
|
||||
service.rateFor("USD/EUR");
|
||||
int afterEvictAndRecall = service.callCount();
|
||||
|
||||
Transcript t = new Transcript("29-" + backendName() + "-cache-evict.txt");
|
||||
t.line("backend=%s", backendName());
|
||||
t.line("rateFor(\"USD/EUR\") call 1 -> method body ran, callCount %d -> %d", before, afterFirstCall);
|
||||
t.line("evict(\"USD/EUR\") then rateFor(\"USD/EUR\") again -> method body ran again, callCount %d -> %d",
|
||||
afterFirstCall, afterEvictAndRecall);
|
||||
t.write();
|
||||
|
||||
assertThat(afterFirstCall).isEqualTo(before + 1);
|
||||
assertThat(afterEvictAndRecall).isEqualTo(afterFirstCall + 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user