Update JSR166 tck tests.
The following tests have been omitted because they are
unsupported :
- Atomic8Test.java
- CompletableFutureTest.java
- ConcurrentHashMap8Test.java
- DoubleAccumulatorTest.java
- DoubleAdderTest.java
- ForkJoinPool8Test.java
- ForkJoinTask8Test.java
- LongAccumulatorTest.java
- LongAdderTest.java
- SplittableRandomTest.java
- StampedLockTest.java
- ThreadLocalRandom8Test.java
- ThreadPoolExecutor9Test.java
A package declaration has been added to all files (package jsr166;)
and the base-class JSR166Test has been changed not to rely on features
that aren't available on android / junit in the android environment.
We also avoid using junit4 style TestSuite declarations. While the CTS
test runner handles them properly usually, it trips over itself when it
encounters a failure and tries to run each test in an invidual process
and fails each test for no good reason (needs investigation on the CTS
side of things)
bug: 20628776
(cherry picked from commit 5da8b2b3cac51f0f592a5e1941bd84eade9648cd)
Change-Id: If35be0881ad8da4c604ce6683149b15c1a85f289
diff --git a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
index d9bf255..d07d936 100644
--- a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
+++ b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
@@ -8,24 +8,14 @@
package jsr166;
-import junit.framework.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.PropertyPermission;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
@@ -33,6 +23,34 @@
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.SecurityPermission;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PropertyPermission;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Pattern;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
/**
* Base class for JSR166 Junit TCK tests. Defines some constants,
@@ -108,6 +126,7 @@
* </ul>
*/
public class JSR166TestCase extends TestCase {
+ // Delays for timing-dependent tests, in milliseconds.
protected static final boolean expensiveTests = false;
@@ -116,7 +135,6 @@
public static long MEDIUM_DELAY_MS;
public static long LONG_DELAY_MS;
-
/**
* Returns the shortest timed delay. This could
* be reimplemented to use for example a Property.
@@ -204,7 +222,7 @@
}
/**
- * Find missing try { ... } finally { joinPool(e); }
+ * Finds missing try { ... } finally { joinPool(e); }
*/
void checkForkJoinPoolThreadLeaks() throws InterruptedException {
Thread[] survivors = new Thread[5];
@@ -302,11 +320,11 @@
public void threadAssertEquals(Object x, Object y) {
try {
assertEquals(x, y);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (AssertionFailedError fail) {
+ threadRecordFailure(fail);
+ throw fail;
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
@@ -318,9 +336,9 @@
public void threadAssertSame(Object x, Object y) {
try {
assertSame(x, y);
- } catch (AssertionFailedError t) {
- threadRecordFailure(t);
- throw t;
+ } catch (AssertionFailedError fail) {
+ threadRecordFailure(fail);
+ throw fail;
}
}
@@ -385,16 +403,23 @@
void joinPool(ExecutorService exec) {
try {
exec.shutdown();
- assertTrue("ExecutorService did not terminate in a timely manner",
- exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS));
+ if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS))
+ fail("ExecutorService " + exec +
+ " did not terminate in a timely manner");
} catch (SecurityException ok) {
// Allowed in case test doesn't have privs
- } catch (InterruptedException ie) {
+ } catch (InterruptedException fail) {
fail("Unexpected InterruptedException");
}
}
/**
+ * A debugging tool to print all stack traces, as jstack does.
+ */
+ static void printAllStackTraces() {
+ }
+
+ /**
* Checks that thread does not terminate within the default
* millisecond delay of {@code timeoutMillis()}.
*/
@@ -410,7 +435,7 @@
// No need to optimize the failing case via Thread.join.
delay(millis);
assertTrue(thread.isAlive());
- } catch (InterruptedException ie) {
+ } catch (InterruptedException fail) {
fail("Unexpected InterruptedException");
}
}
@@ -432,7 +457,7 @@
delay(millis);
for (Thread thread : threads)
assertTrue(thread.isAlive());
- } catch (InterruptedException ie) {
+ } catch (InterruptedException fail) {
fail("Unexpected InterruptedException");
}
}
@@ -454,8 +479,8 @@
future.get(timeoutMillis, MILLISECONDS);
shouldThrow();
} catch (TimeoutException success) {
- } catch (Exception e) {
- threadUnexpectedException(e);
+ } catch (Exception fail) {
+ threadUnexpectedException(fail);
} finally { future.cancel(true); }
assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
}
@@ -499,24 +524,53 @@
public static final Integer m6 = new Integer(-6);
public static final Integer m10 = new Integer(-10);
-
/**
- * android-changed
- * Android does not use a SecurityManager. This will simply execute
- * the runnable ingoring permisions.
+ * Runs Runnable r with a security policy that permits precisely
+ * the specified permissions. If there is no current security
+ * manager, the runnable is run twice, both with and without a
+ * security manager. We require that any security manager permit
+ * getPolicy/setPolicy.
*/
public void runWithPermissions(Runnable r, Permission... permissions) {
- r.run();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ r.run();
+ }
+ runWithSecurityManagerWithPermissions(r, permissions);
}
/**
- * android-changed
- * Android does not use a SecurityManager. This will simply execute
- * the runnable ingoring permisions.
+ * Runs Runnable r with a security policy that permits precisely
+ * the specified permissions. If there is no current security
+ * manager, a temporary one is set for the duration of the
+ * Runnable. We require that any security manager permit
+ * getPolicy/setPolicy.
*/
public void runWithSecurityManagerWithPermissions(Runnable r,
Permission... permissions) {
- r.run();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ Policy savedPolicy = Policy.getPolicy();
+ try {
+ Policy.setPolicy(permissivePolicy());
+ System.setSecurityManager(new SecurityManager());
+ runWithSecurityManagerWithPermissions(r, permissions);
+ } finally {
+ System.setSecurityManager(null);
+ Policy.setPolicy(savedPolicy);
+ }
+ } else {
+ Policy savedPolicy = Policy.getPolicy();
+ AdjustablePolicy policy = new AdjustablePolicy(permissions);
+ Policy.setPolicy(policy);
+
+ try {
+ r.run();
+ } finally {
+ policy.addPermission(new SecurityPermission("setPolicy"));
+ Policy.setPolicy(savedPolicy);
+ }
+ }
}
/**
@@ -582,10 +636,10 @@
void sleep(long millis) {
try {
delay(millis);
- } catch (InterruptedException ie) {
+ } catch (InterruptedException fail) {
AssertionFailedError afe =
new AssertionFailedError("Unexpected InterruptedException");
- afe.initCause(ie);
+ afe.initCause(fail);
throw afe;
}
}
@@ -623,12 +677,42 @@
/**
* Returns the number of milliseconds since time given by
* startNanoTime, which must have been previously returned from a
- * call to {@link System.nanoTime()}.
+ * call to {@link System#nanoTime()}.
*/
- long millisElapsedSince(long startNanoTime) {
+ static long millisElapsedSince(long startNanoTime) {
return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
}
+// void assertTerminatesPromptly(long timeoutMillis, Runnable r) {
+// long startTime = System.nanoTime();
+// try {
+// r.run();
+// } catch (Throwable fail) { threadUnexpectedException(fail); }
+// if (millisElapsedSince(startTime) > timeoutMillis/2)
+// throw new AssertionFailedError("did not return promptly");
+// }
+
+// void assertTerminatesPromptly(Runnable r) {
+// assertTerminatesPromptly(LONG_DELAY_MS/2, r);
+// }
+
+ /**
+ * Checks that timed f.get() returns the expected value, and does not
+ * wait for the timeout to elapse before returning.
+ */
+ <T> void checkTimedGet(Future<T> f, T expectedValue, long timeoutMillis) {
+ long startTime = System.nanoTime();
+ try {
+ assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ if (millisElapsedSince(startTime) > timeoutMillis/2)
+ throw new AssertionFailedError("timed get did not return promptly");
+ }
+
+ <T> void checkTimedGet(Future<T> f, T expectedValue) {
+ checkTimedGet(f, expectedValue, LONG_DELAY_MS);
+ }
+
/**
* Returns a new started daemon Thread running the given runnable.
*/
@@ -647,8 +731,8 @@
void awaitTermination(Thread t, long timeoutMillis) {
try {
t.join(timeoutMillis);
- } catch (InterruptedException ie) {
- threadUnexpectedException(ie);
+ } catch (InterruptedException fail) {
+ threadUnexpectedException(fail);
} finally {
if (t.getState() != Thread.State.TERMINATED) {
t.interrupt();
@@ -674,8 +758,8 @@
public final void run() {
try {
realRun();
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
}
@@ -729,8 +813,8 @@
threadShouldThrow("InterruptedException");
} catch (InterruptedException success) {
threadAssertFalse(Thread.interrupted());
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
}
@@ -741,8 +825,8 @@
public final T call() {
try {
return realCall();
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
return null;
}
}
@@ -759,8 +843,8 @@
return result;
} catch (InterruptedException success) {
threadAssertFalse(Thread.interrupted());
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
return null;
}
@@ -800,16 +884,16 @@
public void await(CountDownLatch latch) {
try {
assertTrue(latch.await(LONG_DELAY_MS, MILLISECONDS));
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
public void await(Semaphore semaphore) {
try {
assertTrue(semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS));
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
@@ -1003,8 +1087,8 @@
@Override protected final void compute() {
try {
realCompute();
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
}
}
}
@@ -1018,8 +1102,8 @@
@Override protected final T compute() {
try {
return realCompute();
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
return null;
}
}
@@ -1043,12 +1127,12 @@
public int await() {
try {
return super.await(2 * LONG_DELAY_MS, MILLISECONDS);
- } catch (TimeoutException e) {
+ } catch (TimeoutException timedOut) {
throw new AssertionFailedError("timed out");
- } catch (Exception e) {
+ } catch (Exception fail) {
AssertionFailedError afe =
- new AssertionFailedError("Unexpected exception: " + e);
- afe.initCause(e);
+ new AssertionFailedError("Unexpected exception: " + fail);
+ afe.initCause(fail);
throw afe;
}
}
@@ -1076,9 +1160,7 @@
q.remove();
shouldThrow();
} catch (NoSuchElementException success) {}
- } catch (InterruptedException ie) {
- threadUnexpectedException(ie);
- }
+ } catch (InterruptedException fail) { threadUnexpectedException(fail); }
}
void assertSerialEquals(Object x, Object y) {
@@ -1097,8 +1179,8 @@
oos.flush();
oos.close();
return bos.toByteArray();
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
return new byte[0];
}
}
@@ -1111,8 +1193,8 @@
T clone = (T) ois.readObject();
assertSame(o.getClass(), clone.getClass());
return clone;
- } catch (Throwable t) {
- threadUnexpectedException(t);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
return null;
}
}
@@ -1137,4 +1219,12 @@
shouldThrow(expectedExceptionClass.getName());
}
}
+
+ public void assertIteratorExhausted(Iterator<?> it) {
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertFalse(it.hasNext());
+ }
}