diff options
Diffstat (limited to 'android/guava-testlib/src/com/google/common')
13 files changed, 82 insertions, 121 deletions
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java b/android/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java index b4e5b35e8..f26e6826b 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java @@ -58,7 +58,7 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> { static final PermittedMetaException UOE_OR_ISE = new PermittedMetaException("UnsupportedOperationException or IllegalStateException") { @Override - boolean isPermitted(RuntimeException exception) { + boolean isPermitted(Exception exception) { return exception instanceof UnsupportedOperationException || exception instanceof IllegalStateException; } @@ -66,21 +66,21 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> { static final PermittedMetaException UOE = new PermittedMetaException("UnsupportedOperationException") { @Override - boolean isPermitted(RuntimeException exception) { + boolean isPermitted(Exception exception) { return exception instanceof UnsupportedOperationException; } }; static final PermittedMetaException ISE = new PermittedMetaException("IllegalStateException") { @Override - boolean isPermitted(RuntimeException exception) { + boolean isPermitted(Exception exception) { return exception instanceof IllegalStateException; } }; static final PermittedMetaException NSEE = new PermittedMetaException("NoSuchElementException") { @Override - boolean isPermitted(RuntimeException exception) { + boolean isPermitted(Exception exception) { return exception instanceof NoSuchElementException; } }; @@ -89,9 +89,9 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> { super(message); } - abstract boolean isPermitted(RuntimeException exception); + abstract boolean isPermitted(Exception exception); - void assertPermitted(RuntimeException exception) { + void assertPermitted(Exception exception) { if (!isPermitted(exception)) { String message = "Exception " @@ -313,10 +313,11 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> { protected void verify(List<E> elements) {} /** Executes the test. */ + @SuppressWarnings("CatchingUnchecked") // sneaky checked exception public final void test() { try { recurse(0); - } catch (RuntimeException e) { + } catch (Exception e) { // sneaky checked exception throw new RuntimeException(Arrays.toString(stimuli), e); } } @@ -372,16 +373,17 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> { * * @see Stimulus#executeAndCompare(ListIterator, Iterator) */ + @SuppressWarnings("CatchingUnchecked") // sneaky checked exception private <T extends Iterator<E>> void internalExecuteAndCompare( T reference, T target, IteratorOperation method) { Object referenceReturnValue = null; PermittedMetaException referenceException = null; Object targetReturnValue = null; - RuntimeException targetException = null; + Exception targetException = null; try { targetReturnValue = method.execute(target); - } catch (RuntimeException e) { + } catch (Exception e) { // sneaky checked exception targetException = e; } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java b/android/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java index adbc8dcc6..cd9cbfdea 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java @@ -17,6 +17,7 @@ package com.google.common.collect.testing; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import junit.framework.TestCase; import org.checkerframework.checker.nullness.qual.Nullable; @@ -31,7 +32,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; * parameterize the test. * @author George van den Driessche */ -@GwtCompatible +@GwtCompatible(emulated = true) public class AbstractTester<G> extends TestCase { private G subjectGenerator; private String suiteName; @@ -73,10 +74,12 @@ public class AbstractTester<G> extends TestCase { } /** Returns the name of the test method invoked by this test instance. */ + @GwtIncompatible // not used under GWT, and super.getName() is not available under J2CL public final String getTestMethodName() { return super.getName(); } + @GwtIncompatible // not used under GWT, and super.getName() is not available under J2CL @Override public String getName() { return Platform.format("%s[%s]", super.getName(), suiteName); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java b/android/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java index c447e2922..c1e502272 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java @@ -16,10 +16,13 @@ package com.google.common.collect.testing; +import static java.util.Arrays.asList; +import static java.util.Collections.emptySet; +import static java.util.Collections.unmodifiableSet; + import com.google.common.annotations.GwtCompatible; -import java.util.Collections; -import java.util.EnumSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.ListIterator; import java.util.Set; @@ -49,12 +52,12 @@ public enum IteratorFeature { * A set containing none of the optional features of the {@link Iterator} or {@link ListIterator} * interfaces. */ - public static final Set<IteratorFeature> UNMODIFIABLE = Collections.emptySet(); + public static final Set<IteratorFeature> UNMODIFIABLE = emptySet(); /** * A set containing all of the optional features of the {@link Iterator} and {@link ListIterator} * interfaces. */ public static final Set<IteratorFeature> MODIFIABLE = - Collections.unmodifiableSet(EnumSet.allOf(IteratorFeature.class)); + unmodifiableSet(new LinkedHashSet<>(asList(values()))); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java index 484913878..067973c2a 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java @@ -477,8 +477,8 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { } catch (IllegalStateException expected) { } } else { + iterator.next(); try { - iterator.next(); iterator.remove(); fail("Expected UnsupportedOperationException."); } catch (UnsupportedOperationException expected) { @@ -729,7 +729,7 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { try { entrySet.retainAll(null); // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) { + } catch (NullPointerException tolerated) { } } else { try { @@ -1365,7 +1365,7 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { try { keySet.retainAll(null); // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) { + } catch (NullPointerException tolerated) { } } else { try { @@ -1425,8 +1425,8 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { } catch (IllegalStateException expected) { } } else { + iterator.next(); try { - iterator.next(); iterator.remove(); fail("Expected UnsupportedOperationException."); } catch (UnsupportedOperationException expected) { @@ -1527,7 +1527,7 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { try { values.removeAll(null); // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) { + } catch (NullPointerException tolerated) { } } else { try { @@ -1581,7 +1581,7 @@ public abstract class MapInterfaceTest<K, V> extends TestCase { try { values.retainAll(null); // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) { + } catch (NullPointerException tolerated) { } } else { try { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java b/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java index a72fd9fba..cd28cdc28 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java @@ -188,9 +188,9 @@ public abstract class AbstractMultisetSetCountTester<E> extends AbstractMultiset @CollectionFeature.Require({SUPPORTS_ADD, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) public void testSetCountZeroToOneConcurrentWithIteration() { + Iterator<E> iterator = collection.iterator(); + assertSetCount(e3(), 1); try { - Iterator<E> iterator = collection.iterator(); - assertSetCount(e3(), 1); iterator.next(); fail("Expected ConcurrentModificationException"); } catch (ConcurrentModificationException expected) { @@ -200,9 +200,9 @@ public abstract class AbstractMultisetSetCountTester<E> extends AbstractMultiset @CollectionFeature.Require({SUPPORTS_ADD, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) public void testSetCountZeroToOneConcurrentWithEntrySetIteration() { + Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator(); + assertSetCount(e3(), 1); try { - Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator(); - assertSetCount(e3(), 1); iterator.next(); fail("Expected ConcurrentModificationException"); } catch (ConcurrentModificationException expected) { @@ -248,9 +248,9 @@ public abstract class AbstractMultisetSetCountTester<E> extends AbstractMultiset @CollectionFeature.Require({SUPPORTS_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) @CollectionSize.Require(absent = ZERO) public void testSetCountOneToZeroConcurrentWithIteration() { + Iterator<E> iterator = collection.iterator(); + assertSetCount(e0(), 0); try { - Iterator<E> iterator = collection.iterator(); - assertSetCount(e0(), 0); iterator.next(); fail("Expected ConcurrentModificationException"); } catch (ConcurrentModificationException expected) { @@ -261,9 +261,9 @@ public abstract class AbstractMultisetSetCountTester<E> extends AbstractMultiset @CollectionFeature.Require({SUPPORTS_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION}) @CollectionSize.Require(absent = ZERO) public void testSetCountOneToZeroConcurrentWithEntrySetIteration() { + Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator(); + assertSetCount(e0(), 0); try { - Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator(); - assertSetCount(e0(), 0); iterator.next(); fail("Expected ConcurrentModificationException"); } catch (ConcurrentModificationException expected) { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java index ebb86b615..936783e77 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java @@ -20,6 +20,7 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE; import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; import static com.google.common.collect.testing.features.CollectionSize.ZERO; import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE; +import static org.junit.Assert.assertThrows; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.AbstractMapTester; @@ -162,11 +163,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V> @MapFeature.Require(absent = SUPPORTS_REMOVE) public void testPollFirstUnsupported() { - try { - navigableMap.pollFirstEntry(); - fail(); - } catch (UnsupportedOperationException e) { - } + assertThrows(UnsupportedOperationException.class, () -> navigableMap.pollFirstEntry()); } @CollectionSize.Require(SEVERAL) @@ -229,11 +226,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V> @MapFeature.Require(absent = SUPPORTS_REMOVE) @CollectionSize.Require(SEVERAL) public void testPollLastUnsupported() { - try { - navigableMap.pollLastEntry(); - fail(); - } catch (UnsupportedOperationException e) { - } + assertThrows(UnsupportedOperationException.class, () -> navigableMap.pollLastEntry()); } @CollectionSize.Require(SEVERAL) diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java index 8b056b4cb..354dd608d 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java @@ -20,6 +20,7 @@ import static com.google.common.collect.testing.features.CollectionFeature.SUPPO import static com.google.common.collect.testing.features.CollectionSize.ONE; import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; import static com.google.common.collect.testing.features.CollectionSize.ZERO; +import static org.junit.Assert.assertThrows; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers; @@ -128,11 +129,7 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> { @CollectionFeature.Require(absent = SUPPORTS_REMOVE) public void testPollFirstUnsupported() { - try { - navigableSet.pollFirst(); - fail(); - } catch (UnsupportedOperationException e) { - } + assertThrows(UnsupportedOperationException.class, () -> navigableSet.pollFirst()); } @CollectionSize.Require(SEVERAL) @@ -209,11 +206,7 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> { @CollectionFeature.Require(absent = SUPPORTS_REMOVE) public void testPollLastUnsupported() { - try { - navigableSet.pollLast(); - fail(); - } catch (UnsupportedOperationException e) { - } + assertThrows(UnsupportedOperationException.class, () -> navigableSet.pollLast()); } @CollectionSize.Require(SEVERAL) diff --git a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java index a52373d64..c47ea9113 100644 --- a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java +++ b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java @@ -17,6 +17,7 @@ package com.google.common.testing; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.J2ktIncompatible; @@ -410,7 +411,8 @@ public final class ArbitraryInstances { } private static <T> T createEmptyArray(Class<T> arrayType) { - return arrayType.cast(Array.newInstance(arrayType.getComponentType(), 0)); + // getComponentType() is non-null because we call createEmptyArray only with an array type. + return arrayType.cast(Array.newInstance(requireNonNull(arrayType.getComponentType()), 0)); } // Internal implementations of some classes, with public default constructor that get() needs. diff --git a/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java b/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java index 3a41a7fe1..2c80552ae 100644 --- a/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java +++ b/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java @@ -496,13 +496,14 @@ public final class ClassSanityTester { * @return this tester */ @CanIgnoreReturnValue + @SuppressWarnings("CatchingUnchecked") // sneaky checked exception public FactoryMethodReturnValueTester testSerializable() throws Exception { for (Invokable<?, ?> factory : getFactoriesToTest()) { Object instance = instantiate(factory); if (instance != null) { try { SerializableTester.reserialize(instance); - } catch (RuntimeException e) { + } catch (Exception e) { // sneaky checked exception AssertionError error = new AssertionFailedError("Serialization failed on return value of " + factory); error.initCause(e.getCause()); @@ -522,6 +523,7 @@ public final class ClassSanityTester { * @return this tester */ @CanIgnoreReturnValue + @SuppressWarnings("CatchingUnchecked") // sneaky checked exception public FactoryMethodReturnValueTester testEqualsAndSerializable() throws Exception { for (Invokable<?, ?> factory : getFactoriesToTest()) { try { @@ -533,7 +535,7 @@ public final class ClassSanityTester { if (instance != null) { try { SerializableTester.reserializeAndAssert(instance); - } catch (RuntimeException e) { + } catch (Exception e) { // sneaky checked exception AssertionError error = new AssertionFailedError("Serialization failed on return value of " + factory); error.initCause(e.getCause()); diff --git a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java index d4484702a..5f02dba84 100644 --- a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java +++ b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java @@ -95,6 +95,16 @@ public final class EqualsTester { /** * Adds {@code equalityGroup} with objects that are supposed to be equal to each other and not * equal to any other equality groups added to this tester. + * + * <p>The {@code @Nullable} annotations on the {@code equalityGroup} parameter imply that the + * objects, and the array itself, can be null. That is for programmer convenience, when the + * objects come from factory methods that are themselves {@code @Nullable}. In reality neither the + * array nor its contents can be null, but it is not useful to force the use of {@code + * requireNonNull} or the like just to assert that. + * + * <p>{@code EqualsTester} will always check that every object it is given returns false from + * {@code equals(null)}, so it is neither useful nor allowed to include a null value in any + * equality group. */ @CanIgnoreReturnValue public EqualsTester addEqualityGroup(@Nullable Object @Nullable ... equalityGroup) { diff --git a/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java b/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java index 73c5705ba..d0202b471 100644 --- a/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java +++ b/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java @@ -35,7 +35,6 @@ import com.google.common.reflect.Reflection; import com.google.common.reflect.TypeToken; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedType; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; @@ -43,7 +42,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentMap; @@ -353,9 +351,9 @@ public final class NullPointerTester { @Nullable Object instance, Invokable<?, ?> invokable, int paramIndex, Class<?> testedClass) { /* * com.google.common is starting to rely on type-use annotations, which aren't visible under - * Android VMs. So we skip testing there. + * Android VMs and in open-source guava-android. So we skip testing there. */ - if (isAndroid() && Reflection.getPackageName(testedClass).startsWith("com.google.common")) { + if (Reflection.getPackageName(testedClass).startsWith("com.google.common")) { return; } if (isPrimitiveOrNullable(invokable.getParameters().get(paramIndex))) { @@ -604,47 +602,27 @@ public final class NullPointerTester { * Looks for declaration nullness annotations and, if supported, type-use nullness annotations. * * <p>Under Android VMs, the methods for retrieving type-use annotations don't exist. This means - * that {@link NullPointerException} may misbehave under Android when used on classes that rely on + * that {@link NullPointerTester} may misbehave under Android when used on classes that rely on * type-use annotations. * * <p>Under j2objc, the necessary APIs exist, but some (perhaps all) return stub values, like - * empty arrays. Presumably {@link NullPointerException} could likewise misbehave under j2objc, - * but I don't know that anyone uses it there, anyway. + * empty arrays. Presumably {@link NullPointerTester} could likewise misbehave under j2objc, but I + * don't know that anyone uses it there, anyway. */ private enum NullnessAnnotationReader { - // Usages (which are unsafe only for Android) are guarded by the annotatedTypeExists() check. - @SuppressWarnings({"Java7ApiChecker", "AndroidApiChecker", "DoNotCall", "deprecation"}) + @SuppressWarnings("Java7ApiChecker") FROM_DECLARATION_AND_TYPE_USE_ANNOTATIONS { @Override - @IgnoreJRERequirement boolean isNullable(Invokable<?, ?> invokable) { return FROM_DECLARATION_ANNOTATIONS_ONLY.isNullable(invokable) - || containsNullable(invokable.getAnnotatedReturnType().getAnnotations()); + ; // TODO(cpovirk): Should we also check isNullableTypeVariable? } @Override - @IgnoreJRERequirement boolean isNullable(Parameter param) { return FROM_DECLARATION_ANNOTATIONS_ONLY.isNullable(param) - || containsNullable(param.getAnnotatedType().getAnnotations()) - || isNullableTypeVariable(param.getAnnotatedType().getType()); - } - - @IgnoreJRERequirement - boolean isNullableTypeVariable(Type type) { - if (!(type instanceof TypeVariable)) { - return false; - } - TypeVariable<?> typeVar = (TypeVariable<?>) type; - for (AnnotatedType bound : typeVar.getAnnotatedBounds()) { - // Until Java 15, the isNullableTypeVariable case here won't help: - // https://bugs.openjdk.java.net/browse/JDK-8202469 - if (containsNullable(bound.getAnnotations()) || isNullableTypeVariable(bound.getType())) { - return true; - } - } - return false; + ; } }, FROM_DECLARATION_ANNOTATIONS_ONLY { @@ -663,9 +641,4 @@ public final class NullPointerTester { abstract boolean isNullable(Parameter param); } - - private static boolean isAndroid() { - // Arguably it would make more sense to test "can we see type-use annotations" directly.... - return checkNotNull(System.getProperty("java.runtime.name", "")).contains("Android"); - } } diff --git a/android/guava-testlib/src/com/google/common/testing/Platform.java b/android/guava-testlib/src/com/google/common/testing/Platform.java index bbad5598d..9726d2de0 100644 --- a/android/guava-testlib/src/com/google/common/testing/Platform.java +++ b/android/guava-testlib/src/com/google/common/testing/Platform.java @@ -17,6 +17,7 @@ package com.google.common.testing; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtCompatible; import java.io.ByteArrayInputStream; @@ -42,7 +43,7 @@ final class Platform { ObjectOutputStream out = new ObjectOutputStream(bytes); out.writeObject(object); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray())); - return (T) in.readObject(); + return (T) requireNonNull(in.readObject()); } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java index abe419e05..325388342 100644 --- a/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java +++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java @@ -18,6 +18,7 @@ package com.google.common.util.concurrent.testing; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.Assert.assertThrows; import com.google.common.annotations.GwtIncompatible; import com.google.common.util.concurrent.ListenableFuture; @@ -70,29 +71,17 @@ public abstract class AbstractListenableFutureTest extends TestCase { assertFalse(future.isDone()); assertFalse(future.isCancelled()); - CountDownLatch successLatch = new CountDownLatch(1); - Throwable[] badness = new Throwable[1]; - - // Wait on the future in a separate thread. - new Thread( - () -> { - try { - assertSame(Boolean.TRUE, future.get()); - successLatch.countDown(); - } catch (Throwable t) { - t.printStackTrace(); - badness[0] = t; - } - }) - .start(); + ExecutorService executor = Executors.newSingleThreadExecutor(); - // Release the future value. - latch.countDown(); + try { + Future<Boolean> getResult = executor.submit(() -> future.get()); - assertTrue(successLatch.await(10, SECONDS)); + // Release the future value. + latch.countDown(); - if (badness[0] != null) { - throw badness[0]; + assertTrue(getResult.get(10, SECONDS)); + } finally { + executor.shutdownNow(); } assertTrue(future.isDone()); @@ -127,13 +116,8 @@ public abstract class AbstractListenableFutureTest extends TestCase { // Run cancellation in a separate thread as an extra thread-safety test. new Thread( () -> { - try { - future.get(); - } catch (CancellationException expected) { - successLatch.countDown(); - } catch (Exception ignored) { - // All other errors are ignored, we expect a cancellation. - } + assertThrows(CancellationException.class, future::get); + successLatch.countDown(); }) .start(); @@ -160,13 +144,8 @@ public abstract class AbstractListenableFutureTest extends TestCase { new Thread( () -> { - try { - future.get(); - } catch (CancellationException expected) { - successLatch.countDown(); - } catch (Exception ignored) { - // No success latch count down. - } + assertThrows(CancellationException.class, future::get); + successLatch.countDown(); }) .start(); |