Skip to content

Commit

Permalink
build cleanups and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed Mar 13, 2022
1 parent 144e903 commit 2c09076
Show file tree
Hide file tree
Showing 24 changed files with 165 additions and 1,002 deletions.
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ jobs:
image: ubuntu-2004:202101-01
environment:
JAVA_VERSION: << pipeline.parameters.java_version >>
TERM: dumb
steps:
- run_tests:
cache_key: strong_keys
Expand All @@ -115,6 +116,7 @@ jobs:
image: ubuntu-2004:202101-01
environment:
JAVA_VERSION: << pipeline.parameters.java_version >>
TERM: dumb
steps:
- run_tests:
cache_key: weak_keys
Expand All @@ -137,6 +139,7 @@ jobs:
image: ubuntu-2004:202101-01
environment:
JAVA_VERSION: << pipeline.parameters.java_version >>
TERM: dumb
steps:
- run_tests:
cache_key: isolated
Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ name: analysis
permissions: read-all
on: [ push, pull_request ]

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true

jobs:
analyze:
runs-on: ubuntu-latest
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ permissions: read-all
on: [ push, pull_request ]

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true
MIN_JVM: 11
MAX_JVM: 17

Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/dependency-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ on: [ push, pull_request ]
permissions: read-all

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true
JAVA_VERSION: 17

jobs:
Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ name: examples
permissions: read-all
on: [ push, pull_request ]

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true

jobs:
examples:
runs-on: ubuntu-latest
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/lincheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ permissions: read-all
on: [ push, pull_request ]

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true
JAVA_VERSION: 17

jobs:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/qodana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ permissions: read-all
on: [ push, pull_request ]

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true
JAVA_VERSION: 11

jobs:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/snyke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ on:
permissions: read-all

env:
ORG_GRADLE_PROJECT_checksumFailOn: never
ORG_GRADLE_PROJECT_checksumIgnore: false
ORG_GRADLE_PROJECT_checksumPrint: true
JAVA_VERSION: 17

jobs:
Expand Down
4 changes: 0 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ allprojects {
apply plugin: 'com.github.ethankhall.semantic-versioning'
apply from: "${rootDir}/gradle/eclipse.gradle"

repositories {
mavenCentral()
}

group = 'com.github.ben-manes.caffeine'
version.with {
major = 3 // incompatible API changes
Expand Down
3 changes: 3 additions & 0 deletions caffeine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ tasks.named('compileJava').configure {
tasks.named('compileJavaPoetJava').configure {
finalizedBy generateLocalCaches, generateNodes
}
tasks.named('compileTestJava').configure {
dependsOn(jar)
}
['compileTestJava', 'pmdMain', 'spotbugsMain'].collect { tasks.named(it) }*.configure {
dependsOn compileCodeGenJava
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ public void notifyRemoval(@Nullable K key, @Nullable V value, RemovalCause cause

/* --------------- Eviction Listener Support --------------- */

private void notifyEviction(@Nullable K key, @Nullable V value, RemovalCause cause) {
void notifyEviction(@Nullable K key, @Nullable V value, RemovalCause cause) {
if (evictionListener == null) {
return;
}
Expand Down Expand Up @@ -914,7 +914,7 @@ void expireVariableEntries(long now) {

/** Returns the duration until the next item expires, or {@link Long.MAX_VALUE} if none. */
@GuardedBy("evictionLock")
private long getExpirationDelay(long now) {
long getExpirationDelay(long now) {
long delay = Long.MAX_VALUE;
if (expiresAfterAccess()) {
Node<K, V> node = accessOrderWindowDeque().peekFirst();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;

/**
Expand Down Expand Up @@ -295,6 +296,7 @@ public static CacheStats empty() {
* @param other the statistics to subtract with
* @return the difference between this instance and {@code other}
*/
@CheckReturnValue
public CacheStats minus(CacheStats other) {
return CacheStats.of(
Math.max(0L, saturatedSubtract(hitCount, other.hitCount)),
Expand All @@ -317,6 +319,7 @@ public CacheStats minus(CacheStats other) {
* @param other the statistics to add with
* @return the sum of the statistics
*/
@CheckReturnValue
public CacheStats plus(CacheStats other) {
return CacheStats.of(
saturatedAdd(hitCount, other.hitCount),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@
import com.github.benmanes.caffeine.testing.Int;
import com.github.valfirst.slf4jtest.TestLogger;
import com.github.valfirst.slf4jtest.TestLoggerFactory;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Range;
import com.google.common.testing.GcFinalization;
import com.google.common.util.concurrent.Uninterruptibles;

Expand Down Expand Up @@ -1156,6 +1158,139 @@ public void unschedule_invalidateAll(BoundedLocalCache<Int, Int> cache, CacheCon
assertThat(cache.pacer().future).isNull();
}

@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY, expireAfterAccess = Expire.ONE_MINUTE,
maximumSize = {Maximum.DISABLED, Maximum.FULL}, weigher = CacheWeigher.DEFAULT)
public void expirationDelay_window(BoundedLocalCache<Int, Int> cache, CacheContext context) {
int maximum = cache.evicts() ? (int) context.maximumSize() : 100;
long stepSize = context.expireAfterAccess().timeNanos() / (2 * maximum);
for (int i = 0; i < maximum; i++) {
var key = CacheContext.intern(Int.valueOf(i));
cache.put(key, key);
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
}

if (cache.evicts()) {
for (var node : List.copyOf(cache.accessOrderProbationDeque())) {
node.setAccessTime(context.ticker().read());
}
for (var node : List.copyOf(cache.accessOrderProtectedDeque())) {
node.setAccessTime(context.ticker().read());
}
for (var node : FluentIterable.from(cache.accessOrderProbationDeque()).skip(5).toList()) {
cache.get(node.getKey());
}
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
cache.cleanUp();
}

var expectedDelay = context.expireAfterAccess().timeNanos()
- (context.ticker().read() - cache.accessOrderWindowDeque().getFirst().getAccessTime());
assertThat(cache.getExpirationDelay(context.ticker().read())).isEqualTo(expectedDelay);
}

@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY, expireAfterAccess = Expire.ONE_MINUTE,
maximumSize = Maximum.FULL, weigher = CacheWeigher.DEFAULT)
public void expirationDelay_probation(BoundedLocalCache<Int, Int> cache, CacheContext context) {
long stepSize = context.expireAfterAccess().timeNanos() / (2 * context.maximumSize());
for (int i = 0; i < (int) context.maximumSize(); i++) {
var key = CacheContext.intern(Int.valueOf(i));
cache.put(key, key);
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
}

for (var node : List.copyOf(cache.accessOrderWindowDeque())) {
node.setAccessTime(context.ticker().read());
}
for (var node : List.copyOf(cache.accessOrderProtectedDeque())) {
node.setAccessTime(context.ticker().read());
}
for (var node : FluentIterable.from(cache.accessOrderProbationDeque()).skip(5).toList()) {
cache.get(node.getKey());
}
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
cache.cleanUp();

var expectedDelay = context.expireAfterAccess().timeNanos()
- (context.ticker().read() - cache.accessOrderProbationDeque().getFirst().getAccessTime());
assertThat(cache.getExpirationDelay(context.ticker().read())).isEqualTo(expectedDelay);
}

@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY, expireAfterAccess = Expire.ONE_MINUTE,
maximumSize = Maximum.FULL, weigher = CacheWeigher.DEFAULT)
public void expirationDelay_protected(BoundedLocalCache<Int, Int> cache, CacheContext context) {
long stepSize = context.expireAfterAccess().timeNanos() / (2 * context.maximumSize());
for (int i = 0; i < (int) context.maximumSize(); i++) {
var key = CacheContext.intern(Int.valueOf(i));
cache.put(key, key);
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
}

for (var node : FluentIterable.from(cache.accessOrderProbationDeque()).skip(5).toList()) {
cache.get(node.getKey());
}
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
cache.cleanUp();


for (var node : List.copyOf(cache.accessOrderWindowDeque())) {
node.setAccessTime(context.ticker().read());
}
for (var node : List.copyOf(cache.accessOrderProbationDeque())) {
node.setAccessTime(context.ticker().read());
}

var expectedDelay = context.expireAfterAccess().timeNanos()
- (context.ticker().read() - cache.accessOrderProtectedDeque().getFirst().getAccessTime());
assertThat(cache.getExpirationDelay(context.ticker().read())).isEqualTo(expectedDelay);
}

@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY, expireAfterWrite = Expire.ONE_MINUTE,
maximumSize = Maximum.FULL, weigher = CacheWeigher.DEFAULT)
public void expirationDelay_writeOrder(BoundedLocalCache<Int, Int> cache, CacheContext context) {
long stepSize = context.expireAfterWrite().timeNanos() / (2 * context.maximumSize());
for (int i = 0; i < (int) context.maximumSize(); i++) {
var key = CacheContext.intern(Int.valueOf(i));
cache.put(key, key);
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
}
for (var key : cache.keySet()) {
cache.get(key);
}
cache.cleanUp();

var expectedDelay = context.expireAfterWrite().timeNanos()
- (context.ticker().read() - cache.writeOrderDeque().getFirst().getWriteTime());
assertThat(cache.getExpirationDelay(context.ticker().read())).isEqualTo(expectedDelay);
}

@Test(dataProvider = "caches")
@CacheSpec(population = Population.EMPTY, maximumSize = {Maximum.DISABLED, Maximum.FULL},
expiry = CacheExpiry.WRITE, expiryTime = Expire.ONE_MINUTE)
public void expirationDelay_varTime(BoundedLocalCache<Int, Int> cache, CacheContext context) {
long startTime = context.ticker().read();
int maximum = cache.evicts() ? (int) context.maximumSize() : 100;
long stepSize = context.expiryTime().timeNanos() / (2 * maximum);
for (int i = 0; i < maximum; i++) {
var key = CacheContext.intern(Int.valueOf(i));
cache.put(key, key);
context.ticker().advance(stepSize, TimeUnit.NANOSECONDS);
}
for (var key : cache.keySet()) {
cache.get(key);
}
cache.cleanUp();

var expectedDelay = context.expiryTime().timeNanos() - (context.ticker().read() - startTime);
assertThat(cache.getExpirationDelay(context.ticker().read())).isIn(
Range.closed(expectedDelay - TimerWheel.SPANS[0], expectedDelay));
}

/* --------------- Refresh --------------- */

@Test(dataProvider = "caches", groups = "isolated")
@CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY,
refreshAfterWrite = Expire.ONE_MINUTE, executor = CacheExecutor.THREADED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ public void ageOf_duration(CacheContext context,
@CacheSpec(expireAfterAccess = Expire.ONE_MINUTE)
public void ageOf_absent(CacheContext context,
@ExpireAfterAccess FixedExpiration<Int, Int> expireAfterAccess) {
assertThat(expireAfterAccess.ageOf(context.absentKey())).isEmpty();
assertThat(expireAfterAccess.ageOf(context.absentKey(), TimeUnit.SECONDS)).isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ public void ageOf_duration(CacheContext context,
@CacheSpec(expireAfterWrite = Expire.ONE_MINUTE)
public void ageOf_absent(CacheContext context,
@ExpireAfterWrite FixedExpiration<Int, Int> expireAfterWrite) {
assertThat(expireAfterWrite.ageOf(context.absentKey())).isEmpty();
assertThat(expireAfterWrite.ageOf(context.absentKey(), TimeUnit.SECONDS)).isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ public void getAll_iterable_empty(LoadingCache<Int, Int> cache, CacheContext con
assertThat(context).stats().hits(0).misses(0);
}

// TODO(ben): Update for Guava's fix
// https://github.com/google/guava/issues/5810
@CacheSpec(implementation = Implementation.Caffeine, loader = Loader.BULK_MODIFY_KEYS)
@CacheSpec(loader = Loader.BULK_MODIFY_KEYS)
@Test(dataProvider = "caches", expectedExceptions = UnsupportedOperationException.class)
public void getAll_immutable_keys(LoadingCache<Int, Int> cache, CacheContext context) {
cache.getAll(context.absentKeys());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ public void ageOf_duration(CacheContext context, FixedRefresh<Int, Int> refreshA
@Test(dataProvider = "caches")
@CacheSpec(refreshAfterWrite = Expire.ONE_MINUTE)
public void ageOf_absent(CacheContext context, FixedRefresh<Int, Int> refreshAfterWrite) {
assertThat(refreshAfterWrite.ageOf(context.absentKey())).isEmpty();
assertThat(refreshAfterWrite.ageOf(context.absentKey(), TimeUnit.SECONDS)).isEmpty();
}

Expand Down
3 changes: 0 additions & 3 deletions caffeine/testing.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ test {
useTestNG()
exclude 'com/github/benmanes/caffeine/cache/**'
}
tasks.named('compileTestJava').configure {
dependsOn(jar)
}

def implementations = ['Caffeine', 'Guava']
def testNames = [
Expand Down
Loading

0 comments on commit 2c09076

Please sign in to comment.