Skip to content

Commit

Permalink
additional test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed May 2, 2021
1 parent 08511fd commit 99bf56b
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,22 @@ public void bulk_function_null() {
AsyncCacheLoader.bulk(f);
}

@Test
public void bulk_function_absent() throws Exception {
AsyncCacheLoader<Integer, Integer> loader = AsyncCacheLoader.bulk(keys -> Map.of());
assertThat(loader.asyncLoadAll(Set.of(), Runnable::run).join(), is(Map.of()));
assertThat(loader.asyncLoad(1, Runnable::run).join(), is(nullValue()));
}

@Test
public void bulk_function_present() throws Exception {
AsyncCacheLoader<Integer, Integer> loader = AsyncCacheLoader.bulk(keys -> {
return keys.stream().collect(toMap(identity(), identity()));
});
assertThat(loader.asyncLoadAll(Set.of(1, 2), Runnable::run).join(), is(Map.of(1, 1, 2, 2)));
assertThat(loader.asyncLoad(1, Runnable::run).join(), is(1));
}

@SuppressWarnings("CheckReturnValue")
@Test(expectedExceptions = NullPointerException.class)
public void bulk_bifunction_null() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@
public final class CaffeineSpecTest {
static final long UNSET_LONG = UNSET_INT;

@Test(expectedExceptions = IllegalArgumentException.class)
public void parseInt_exception() {
CaffeineSpec.parseInt("key", "value");
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void parseLong_exception() {
CaffeineSpec.parseLong("key", "value");
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void parseTimeUnit_exception() {
CaffeineSpec.parseTimeUnit("key", "value");
}

@Test(dataProvider = "caches")
@CacheSpec(initialCapacity = {InitialCapacity.DEFAULT, InitialCapacity.FULL},
population = Population.EMPTY, compute = Compute.SYNC,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,14 @@ public void iterator_removal(LinkedDeque<LinkedValue> deque) {
assertThat(deque, hasSize(SIZE - 1));
}

@Test(dataProvider = "full", expectedExceptions = IllegalStateException.class)
public void iterator_removal_exception(LinkedDeque<LinkedValue> deque) {
PeekingIterator<LinkedValue> iterator = deque.iterator();
iterator.next();
iterator.remove();
iterator.remove();
}

@Test(dataProvider = "empty", expectedExceptions = NoSuchElementException.class)
public void descendingIterator_noMoreElements(LinkedDeque<LinkedValue> deque) {
deque.descendingIterator().next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -397,16 +398,27 @@ public void refreshes(LoadingCache<Integer, Integer> cache, CacheContext context

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, refreshAfterWrite = Expire.ONE_MINUTE)
public void getExpiresAfter(CacheContext context,
public void getRefreshesAfter(CacheContext context,
@RefreshAfterWrite FixedRefresh<Integer, Integer> refreshAfterWrite) {
assertThat(refreshAfterWrite.getRefreshesAfter().toMinutes(), is(1L));
assertThat(refreshAfterWrite.getRefreshesAfter(TimeUnit.MINUTES), is(1L));
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, refreshAfterWrite = Expire.ONE_MINUTE)
public void setExpiresAfter(CacheContext context,
public void setRefreshesAfter(CacheContext context,
@RefreshAfterWrite FixedRefresh<Integer, Integer> refreshAfterWrite) {
refreshAfterWrite.setRefreshesAfter(2, TimeUnit.MINUTES);
assertThat(refreshAfterWrite.getRefreshesAfter().toMinutes(), is(2L));
assertThat(refreshAfterWrite.getRefreshesAfter(TimeUnit.MINUTES), is(2L));
}

@Test(dataProvider = "caches")
@CacheSpec(implementation = Implementation.Caffeine, refreshAfterWrite = Expire.ONE_MINUTE)
public void setRefreshesAfter_duration(CacheContext context,
@RefreshAfterWrite FixedRefresh<Integer, Integer> refreshAfterWrite) {
refreshAfterWrite.setRefreshesAfter(Duration.ofMinutes(2));
assertThat(refreshAfterWrite.getRefreshesAfter().toMinutes(), is(2L));
assertThat(refreshAfterWrite.getRefreshesAfter(TimeUnit.MINUTES), is(2L));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
Expand All @@ -44,6 +45,7 @@
import com.github.benmanes.caffeine.testing.ConcurrentTestHarness;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.NullPointerTester;
import com.google.common.util.concurrent.Futures;

/**
* @author [email protected] (Ben Manes)
Expand Down Expand Up @@ -90,6 +92,16 @@ public void disabledScheduler() {
assertThat(future, is(DisabledFuture.INSTANCE));
}

@Test
public void disabledFuture() throws Exception {
assertThat(DisabledFuture.INSTANCE.isDone(), is(true));
assertThat(DisabledFuture.INSTANCE.isCancelled(), is(false));
assertThat(DisabledFuture.INSTANCE.cancel(false), is(false));
assertThat(DisabledFuture.INSTANCE.cancel(true), is(false));
assertThat(DisabledFuture.INSTANCE.get(), is(nullValue()));
assertThat(DisabledFuture.INSTANCE.get(0, TimeUnit.SECONDS), is(nullValue()));
}

@Test
public void disabledFuture_null() {
npeTester.testAllPublicInstanceMethods(DisabledFuture.INSTANCE);
Expand Down Expand Up @@ -117,7 +129,14 @@ public void guardedScheduler_nullFuture() {

@Test
public void guardedScheduler() {
Future<?> future = Scheduler.guardedScheduler(Scheduler.disabledScheduler())
Future<?> future = Scheduler.guardedScheduler((r, e, d, u) -> Futures.immediateVoidFuture())
.schedule(Runnable::run, () -> {}, 1, TimeUnit.MINUTES);
assertThat(future, is(Futures.immediateVoidFuture()));
}

@Test
public void guardedScheduler_exception() {
Future<?> future = Scheduler.guardedScheduler((r, e, d, u) -> { throw new RuntimeException(); })
.schedule(Runnable::run, () -> {}, 1, TimeUnit.MINUTES);
assertThat(future, is(DisabledFuture.INSTANCE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.times;
Expand All @@ -48,6 +49,7 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
Expand Down Expand Up @@ -135,6 +137,23 @@ public void advance(long clock) {
verify(cache).evictEntry(any(), any(), anyLong());
}

@Test
public void advance_exception() {
Mockito.doThrow(new IllegalStateException())
.when(cache).evictEntry(captor.capture(), any(), anyLong());
var timer = new Timer(timerWheel.nanos + SPANS[1]);

timerWheel.nanos = 0L;
timerWheel.schedule(timer);
try {
timerWheel.advance(Long.MAX_VALUE);
Assert.fail();
} catch (IllegalStateException e) {
assertThat(timerWheel.nanos, is(0L));
assertThat(timerWheel.wheel[1][1].getNextInVariableOrder(), is(sameInstance(timer)));
}
}

@Test(dataProvider = "clock")
public void getExpirationDelay_empty(long clock) {
when(cache.evictEntry(any(), any(), anyLong())).thenReturn(true);
Expand Down Expand Up @@ -232,7 +251,7 @@ public Iterator<Object> providesClock() {
@DataProvider(name = "schedule")
public Iterator<Object[]> providesSchedule() {
var args = new ArrayList<Object[]>();
for (var clock : CLOCKS) {
for (long clock : CLOCKS) {
args.add(new Object[] { clock, TimeUnit.SECONDS.toNanos(10), 0 });
args.add(new Object[] { clock, TimeUnit.MINUTES.toNanos(3), 2 });
args.add(new Object[] { clock, TimeUnit.MINUTES.toNanos(10), 3 });
Expand Down Expand Up @@ -268,7 +287,7 @@ private void checkTimerWheel(long duration) {
private LongArrayList getTimers(Node<?, ?> sentinel) {
LongArrayList timers = new LongArrayList();
for (Node<?, ?> node = sentinel.getNextInVariableOrder();
node != sentinel; node = node.getNextInVariableOrder()) {
node != sentinel; node = node.getNextInVariableOrder()) {
timers.add(node.getVariableTime());
}
return timers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
Expand Down Expand Up @@ -96,6 +97,12 @@ public void guarded() {
assertThat(counter.snapshot().toString(), is(expected.toString()));
}

@Test
public void guarded_sameInstance() {
StatsCounter counter = StatsCounter.guardedStatsCounter(new ConcurrentStatsCounter());
assertThat(StatsCounter.guardedStatsCounter(counter), is(sameInstance(counter)));
}

@Test
public void guarded_exception() {
StatsCounter statsCounter = Mockito.mock(StatsCounter.class);
Expand Down
2 changes: 1 addition & 1 deletion gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ ext {
"org.osgi:org.osgi.util.promise:${testVersions.osgiUtilPromise}",
"org.ops4j.pax.exam:pax-exam-container-native:${testVersions.paxExam}",
"org.ops4j.pax.exam:pax-exam-link-mvn:${testVersions.paxExam}",
"org.ops4j.pax.url:pax-url-aether:2.6.5",
"org.ops4j.pax.url:pax-url-aether:2.6.7",
],
testng: [
dependencies.create("org.testng:testng:${testVersions.testng}") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,8 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
Expand All @@ -55,16 +51,13 @@ public abstract class AbstractCopier<A> implements Copier {
private static final Set<Class<?>> JAVA_IMMUTABLE;

static {
JAVA_IMMUTABLE = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Boolean.class,
Byte.class, Character.class, Double.class, Float.class, Short.class, Integer.class,
Long.class, BigInteger.class, BigDecimal.class, String.class, Class.class, UUID.class,
URL.class, URI.class, Pattern.class, Inet4Address.class, Inet6Address.class,
InetSocketAddress.class, LocalDate.class, LocalTime.class, LocalDateTime.class,
Instant.class, Duration.class)));
Map<Class<?>, Function<Object, Object>> strategies = new HashMap<>();
strategies.put(Calendar.class, o -> ((Calendar) o).clone());
strategies.put(Date.class, o -> ((Date) o).clone());
JAVA_DEEP_COPY = Collections.unmodifiableMap(strategies);
JAVA_IMMUTABLE = Set.of(Boolean.class, Byte.class, Character.class, Double.class, Float.class,
Short.class, Integer.class, Long.class, BigInteger.class, BigDecimal.class, String.class,
Class.class, UUID.class, URL.class, URI.class, Pattern.class, Inet4Address.class,
Inet6Address.class, InetSocketAddress.class, LocalDate.class, LocalTime.class,
LocalDateTime.class, Instant.class, Duration.class);
JAVA_DEEP_COPY = Map.of(Date.class, o -> ((Date) o).clone(),
Calendar.class, o -> ((Calendar) o).clone());
}

private final Set<Class<?>> immutableClasses;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,76 +27,98 @@
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
* @author [email protected] (Ben Manes)
*/
public final class JavaSerializationCopierTest {
final Copier copier = new JavaSerializationCopier();

@Test(expectedExceptions = NullPointerException.class)
public void null_object() {
copy(null);
@Test(dataProvider = "nullArgs", expectedExceptions = NullPointerException.class)
public void constructor_null(Set<Class<?>> immutableClasses,
Map<Class<?>, Function<Object, Object>> deepCopyStrategies) {
new JavaSerializationCopier(immutableClasses, deepCopyStrategies);
}

@Test(expectedExceptions = NullPointerException.class)
public void null_classLoader() {
@Test(dataProvider = "copier", expectedExceptions = NullPointerException.class)
public void null_object(Copier copier) {
copy(copier, null);
}

@Test(dataProvider = "copier", expectedExceptions = NullPointerException.class)
public void null_classLoader(Copier copier) {
copier.copy(1, null);
}

@Test(expectedExceptions = UncheckedIOException.class)
public void notSerializable() {
copy(new ByteArrayInputStream(new byte[0]));
@Test(dataProvider = "copier", expectedExceptions = UncheckedIOException.class)
public void notSerializable(Copier copier) {
copy(copier, new ByteArrayInputStream(new byte[0]));
}

@Test
public void mutable() {
@Test(dataProvider = "copier")
public void mutable(Copier copier) {
List<Integer> ints = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
assertThat(copy(ints), is(equalTo(ints)));
assertThat(copy(copier, ints), is(equalTo(ints)));
}

@Test
public void immutable() {
String text = "test";
assertThat(copy(text), is(sameInstance(text)));
assertThat(copy(new JavaSerializationCopier(), text), is(sameInstance(text)));
}

@Test
@Test(dataProvider = "copier")
@SuppressWarnings({"JdkObsolete", "JavaUtilDate"})
public void deepCopy_date() {
public void deepCopy_date(Copier copier) {
Date date = new Date();
assertThat(copy(date), is(equalTo(date)));
assertThat(copy(copier, date), is(equalTo(date)));
}

@Test
@Test(dataProvider = "copier")
@SuppressWarnings({"JdkObsolete", "JavaUtilDate"})
public void deepCopy_calendar() {
public void deepCopy_calendar(Copier copier) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
assertThat(copy(calendar), is(equalTo(calendar)));
assertThat(copy(copier, calendar), is(equalTo(calendar)));
}

@Test
public void array_primitive() {
@Test(dataProvider = "copier")
public void array_primitive(Copier copier) {
int[] ints = { 0, 1, 2, 3, 4 };
assertThat(copy(ints), is(equalTo(ints)));
assertThat(copy(copier, ints), is(equalTo(ints)));
}

@Test
public void array_immutable() {
@Test(dataProvider = "copier")
public void array_immutable(Copier copier) {
Integer[] ints = { 0, 1, 2, 3, 4 };
assertThat(copy(ints), is(equalTo(ints)));
assertThat(copy(copier, ints), is(equalTo(ints)));
}

@Test
public void array_mutable() {
@Test(dataProvider = "copier")
public void array_mutable(Copier copier) {
Object array = new Object[] { new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4)) };
assertThat(copy(array), is(equalTo(array)));
assertThat(copy(copier, array), is(equalTo(array)));
}

private <T> T copy(T object) {
private <T> T copy(Copier copier, T object) {
return copier.copy(object, Thread.currentThread().getContextClassLoader());
}

@DataProvider(name = "copier")
public Object[] providesCopiers() {
return new Object[] {
new JavaSerializationCopier(),
new JavaSerializationCopier(Set.of(), Map.of())
};
}

@DataProvider(name = "nullArgs")
public Object[][] providesNullArgs() {
return new Object[][] { { null, null }, { null, Map.of() }, { Set.of(), null } };
}
}

0 comments on commit 99bf56b

Please sign in to comment.