From 4d874858bcaed17777335e7f66658513f530ece7 Mon Sep 17 00:00:00 2001 From: Ben Manes Date: Sun, 10 Jan 2021 19:28:15 -0800 Subject: [PATCH] Enable recursive compute test cases --- .../benmanes/caffeine/cache/AsMapTest.java | 60 ++++++++++--------- .../caffeine/cache/AsyncAsMapTest.java | 58 +++++++++--------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java index 7f989c5767..5094d0c334 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsMapTest.java @@ -54,6 +54,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -1097,31 +1098,32 @@ public void computeIfAbsent_nullValue(Map map, CacheContext co verifyStats(context, verifier -> verifier.hits(0).misses(1).success(0).failures(1)); } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = IllegalStateException.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void computeIfAbsent_recursive(Map map, CacheContext context) { Function mappingFunction = new Function() { @Override public Integer apply(Integer key) { return map.computeIfAbsent(key, this); } }; - map.computeIfAbsent(context.absentKey(), mappingFunction); + try { + map.computeIfAbsent(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = IllegalStateException.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void computeIfAbsent_pingpong(Map map, CacheContext context) { Function mappingFunction = new Function() { @Override public Integer apply(Integer key) { - Integer value = context.original().get(key); - return map.computeIfAbsent(value, this); + return map.computeIfAbsent(-key, this); } }; - map.computeIfAbsent(context.absentKey(), mappingFunction); + try { + map.computeIfAbsent(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } @Test(dataProvider = "caches") @@ -1352,10 +1354,8 @@ public void compute_remove(Map map, CacheContext context) { verifyRemovalListener(context, verifier -> verifier.hasOnly(count, RemovalCause.EXPLICIT)); } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = StackOverflowError.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void compute_recursive(Map map, CacheContext context) { BiFunction mappingFunction = new BiFunction() { @@ -1363,33 +1363,39 @@ public void compute_recursive(Map map, CacheContext context) { return map.compute(key, this); } }; - map.compute(context.absentKey(), mappingFunction); + try { + map.compute(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, - removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = StackOverflowError.class) + @Test(dataProvider = "caches") + @CacheSpec(population = Population.EMPTY, implementation = Implementation.Caffeine) public void compute_pingpong(Map map, CacheContext context) { + var key1 = 1; + var key2 = 2; BiFunction mappingFunction = new BiFunction() { @Override public Integer apply(Integer key, Integer value) { - return map.computeIfPresent(context.lastKey(), this); + return map.compute((key == key1) ? key2 : key1, this); } }; - map.computeIfPresent(context.firstKey(), mappingFunction); + try { + map.compute(key1, mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } @CacheSpec @Test(dataProvider = "caches") public void compute_error(Map map, CacheContext context) { try { - map.compute(context.absentKey(), (key, value) -> { throw new Error(); }); - } catch (Error e) {} + map.compute(context.absentKey(), (key, value) -> { throw new IllegalStateException(); }); + Assert.fail(); + } catch (IllegalStateException e) { /* ignored */ } assertThat(map, is(equalTo(context.original()))); verifyStats(context, verifier -> verifier.hits(0).misses(0).success(0).failures(1)); - assertThat(map.computeIfPresent(context.absentKey(), (k, v) -> -k), is(nullValue())); + assertThat(map.compute(context.absentKey(), (k, v) -> -k), is(-context.absentKey())); } @CheckNoWriter diff --git a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java index 96cc3f38d1..a4fd41d43b 100644 --- a/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java +++ b/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncAsMapTest.java @@ -60,6 +60,7 @@ import com.github.benmanes.caffeine.cache.testing.CacheContext; import com.github.benmanes.caffeine.cache.testing.CacheProvider; import com.github.benmanes.caffeine.cache.testing.CacheSpec; +import com.github.benmanes.caffeine.cache.testing.CacheSpec.Implementation; import com.github.benmanes.caffeine.cache.testing.CacheSpec.Listener; import com.github.benmanes.caffeine.cache.testing.CacheSpec.Population; import com.github.benmanes.caffeine.cache.testing.CacheValidationListener; @@ -748,10 +749,8 @@ public void computeIfAbsent_nullValue(AsyncCache cache, CacheC assertThat(cache.asMap().size(), is(context.original().size())); } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = IllegalStateException.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void computeIfAbsent_recursive(AsyncCache cache, CacheContext context) { Function> mappingFunction = new Function>() { @@ -759,22 +758,25 @@ public void computeIfAbsent_recursive(AsyncCache cache, CacheC return cache.asMap().computeIfAbsent(key, this); } }; - cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); + try { + cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = IllegalStateException.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void computeIfAbsent_pingpong(AsyncCache cache, CacheContext context) { Function> mappingFunction = new Function>() { @Override public CompletableFuture apply(Integer key) { - Integer value = context.original().get(key); - return cache.asMap().computeIfAbsent(value, this); + return cache.asMap().computeIfAbsent(-key, this); } }; - cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); + try { + cache.asMap().computeIfAbsent(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } @Test(dataProvider = "caches") @@ -964,10 +966,8 @@ public void compute_remove(AsyncCache cache, CacheContext cont verifyRemovalListener(context, verifier -> verifier.hasOnly(count, RemovalCause.EXPLICIT)); } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = StackOverflowError.class) + @Test(dataProvider = "caches") + @CacheSpec(implementation = Implementation.Caffeine) public void compute_recursive(AsyncCache cache, CacheContext context) { BiFunction, CompletableFuture> mappingFunction = new BiFunction, CompletableFuture>() { @@ -976,26 +976,30 @@ public void compute_recursive(AsyncCache cache, CacheContext c return cache.asMap().compute(key, this); } }; - cache.asMap().compute(context.absentKey(), mappingFunction); + try { + cache.asMap().compute(context.absentKey(), mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } - // FIXME: Requires JDK8 release with JDK-8062841 fix - @CheckNoStats - @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, - removalListener = { Listener.DEFAULT, Listener.REJECTING }) - @Test(enabled = false, dataProvider = "caches", expectedExceptions = StackOverflowError.class) + @CacheSpec(population = Population.EMPTY, implementation = Implementation.Caffeine) + @Test(dataProvider = "caches") public void compute_pingpong(AsyncCache cache, CacheContext context) { + var key1 = 1; + var key2 = 2; BiFunction, CompletableFuture> mappingFunction = new BiFunction, CompletableFuture>() { @Override public CompletableFuture apply( Integer key, CompletableFuture value) { - return cache.asMap().computeIfPresent(context.lastKey(), this); + return cache.asMap().compute((key == key1) ? key2 : key1, this); } }; - cache.asMap().computeIfPresent(context.firstKey(), mappingFunction); + try { + cache.asMap().compute(key1, mappingFunction); + Assert.fail(); + } catch (StackOverflowError | IllegalStateException e) { /* ignored */ } } - @CheckNoStats @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void compute_error(AsyncCache cache, CacheContext context) { @@ -1007,8 +1011,8 @@ public void compute_error(AsyncCache cache, CacheContext conte assertThat(cache.synchronous().asMap(), is(equalTo(context.original()))); verifyStats(context, verifier -> verifier.hits(0).misses(0).success(0).failures(0)); - assertThat(cache.asMap().computeIfPresent(context.absentKey(), - (k, v) -> CompletableFuture.completedFuture(-k)), is(nullValue())); + var future = CompletableFuture.completedFuture(-context.absentKey()); + assertThat(cache.asMap().compute(context.absentKey(), (k, v) -> future), is(future)); } @CheckNoStats