18f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle/*
28f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Written by Doug Lea with assistance from members of JCP JSR-166
38f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Expert Group and released to the public domain, as explained at
48f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * http://creativecommons.org/publicdomain/zero/1.0/
58f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Other contributors include Andrew Wright, Jeffrey Hayes,
68f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Pat Fisher, Mike Judd.
78f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */
88f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
9b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepackage jsr166;
118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
128e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport static java.util.concurrent.TimeUnit.MILLISECONDS;
13b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport static java.util.concurrent.TimeUnit.MINUTES;
148e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport static java.util.concurrent.TimeUnit.NANOSECONDS;
158e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.io.ByteArrayInputStream;
178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.io.ByteArrayOutputStream;
188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.io.ObjectInputStream;
198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.io.ObjectOutputStream;
20b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.lang.reflect.Constructor;
218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.lang.reflect.Method;
22b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.lang.reflect.Modifier;
23b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak import java.security.CodeSource;
248e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.Permission;
258e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.PermissionCollection;
268e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.Permissions;
278e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.Policy;
288e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.ProtectionDomain;
298e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.security.SecurityPermission;
308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.ArrayList;
318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.Arrays;
328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.Date;
338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.Enumeration;
348e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.Iterator;
358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.List;
368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.NoSuchElementException;
378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.PropertyPermission;
388e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.BlockingQueue;
398e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.Callable;
408e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.CountDownLatch;
418e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.CyclicBarrier;
42b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.concurrent.ExecutionException;
43b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.concurrent.Executors;
448e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.ExecutorService;
45b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.concurrent.ForkJoinPool;
468e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.Future;
478e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.RecursiveAction;
488e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.RecursiveTask;
498e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.RejectedExecutionHandler;
508e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.Semaphore;
518e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.ThreadFactory;
528e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.ThreadPoolExecutor;
538e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.concurrent.TimeoutException;
54b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.concurrent.atomic.AtomicBoolean;
558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.atomic.AtomicReference;
56b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.regex.Matcher;
578e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport java.util.regex.Pattern;
588e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
598e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.AssertionFailedError;
608e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.Test;
618e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.TestCase;
62b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport junit.framework.TestResult;
638e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.TestSuite;
648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle/**
668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Base class for JSR166 Junit TCK tests.  Defines some constants,
678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * utility methods and classes, as well as a simple framework for
688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * helping to make sure that assertions failing in generated threads
698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * cause the associated test that generated them to itself fail (which
708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * JUnit does not otherwise arrange).  The rules for creating such
718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * tests are:
728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * <ol>
748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
75b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>All assertions in code running in generated threads must use
768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * #threadAssertEquals}, or {@link #threadAssertNull}, (not
788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * particularly recommended) for other code to use these forms too.
808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Only the most typically used JUnit assertion methods are defined
81b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * this way, but enough to live with.
828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
83b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>If you override {@link #setUp} or {@link #tearDown}, make sure
848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * to invoke {@code super.setUp} and {@code super.tearDown} within
858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * them. These methods are used to clear and check for thread
86b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * assertion failures.
878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * <li>All delays and timeouts must use one of the constants {@code
898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS},
908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * {@code LONG_DELAY_MS}. The idea here is that a SHORT is always
918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * discriminable from zero time, and always allows enough time for the
928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * small amounts of computation (creating a thread, calling a few
938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * methods, etc) needed to reach a timeout point. Similarly, a SMALL
948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * is always discriminable as larger than SHORT and smaller than
958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * MEDIUM.  And so on. These constants are set to conservative values,
968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * but even so, if there is ever any doubt, they can all be increased
97b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * in one spot to rerun tests on slower platforms.
988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
99b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>All threads generated must be joined inside each test case
1008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * method (or {@code fail} to do so) before returning from the
1018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * method. The {@code joinPool} method can be used to do this when
102b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * using Executors.
1038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
1048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * </ol>
1058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
1068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * <p><b>Other notes</b>
1078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * <ul>
1088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
109b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>Usually, there is one testcase method per JSR166 method
1108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * covering "normal" operation, and then as many exception-testing
1118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * methods as there are exceptions the method can throw. Sometimes
1128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * there are multiple tests per JSR166 method when the different
1138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * "normal" behaviors differ significantly. And sometimes testcases
114b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * cover multiple methods when they cannot be tested in isolation.
1158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
116b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>The documentation style for testcases is to provide as javadoc
1178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * a simple sentence or two describing the property that the testcase
1188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * method purports to test. The javadocs do not say anything about how
119b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * the property is tested. To find out, read the code.
1208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
121b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>These tests are "conformance tests", and do not attempt to
1228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * test throughput, latency, scalability or other performance factors
1238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * (see the separate "jtreg" tests for a set intended to check these
1248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * for the most central aspects of functionality.) So, most tests use
1258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * the smallest sensible numbers of threads, collection sizes, etc
126b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * needed to check basic conformance.
1278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
1288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * <li>The test classes currently do not declare inclusion in
1298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * any particular package to simplify things for people integrating
130b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * them in TCK test suites.
1318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
132b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <li>As a convenience, the {@code main} of this class (JSR166TestCase)
133b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * runs all JSR166 unit tests.
1348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle *
1358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * </ul>
1368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */
1378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepublic class JSR166TestCase extends TestCase {
138b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final boolean useSecurityManager =
139b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Boolean.getBoolean("jsr166.useSecurityManager");
140b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
141b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    protected static final boolean expensiveTests =
142b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Boolean.getBoolean("jsr166.expensiveTests");
143b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
144b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
145b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * If true, also run tests that are not part of the official tck
146b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * because they test unspecified implementation details.
147b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
148b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    protected static final boolean testImplementationDetails =
149b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Boolean.getBoolean("jsr166.testImplementationDetails");
150b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
151b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
152b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * If true, report on stdout all "slow" tests, that is, ones that
153b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * take more than profileThreshold milliseconds to execute.
154b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
155b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final boolean profileTests =
156b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Boolean.getBoolean("jsr166.profileTests");
157b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
158b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
159b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The number of milliseconds that tests are permitted for
160b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * execution without being reported, when profileTests is set.
161b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
162b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final long profileThreshold =
163b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Long.getLong("jsr166.profileThreshold", 100);
164b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
165b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
166b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The number of repetitions per test (for tickling rare bugs).
167b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
168b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final int runsPerTest =
169b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Integer.getInteger("jsr166.runsPerTest", 1);
170b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
171b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
172b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The number of repetitions of the test suite (for finding leaks?).
173b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
174b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final int suiteRuns =
175b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Integer.getInteger("jsr166.suiteRuns", 1);
176b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
177b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static float systemPropertyValue(String name, float defaultValue) {
178b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        String floatString = System.getProperty(name);
179b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        if (floatString == null)
180b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return defaultValue;
181b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        try {
182b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return Float.parseFloat(floatString);
183b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } catch (NumberFormatException ex) {
184b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            throw new IllegalArgumentException(
185b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                String.format("Bad float value in system property %s=%s",
186b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                              name, floatString));
187b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
188b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
189b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
190b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
191b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The scaling factor to apply to standard delays used in tests.
192b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
193b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final float delayFactor =
194b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        systemPropertyValue("jsr166.delay.factor", 1.0f);
195b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
196b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
197b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The timeout factor as used in the jtreg test harness.
198b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * See: http://openjdk.java.net/jtreg/tag-spec.html
199b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
200b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final float jtregTestTimeoutFactor
201b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        = systemPropertyValue("test.timeout.factor", 1.0f);
202b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
203b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public JSR166TestCase() { super(); }
204b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public JSR166TestCase(String name) { super(name); }
205b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
206b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
207b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * A filter for tests to run, matching strings of the form
208b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * methodName(className), e.g. "testInvokeAll5(ForkJoinPoolTest)"
209b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Usefully combined with jsr166.runsPerTest.
210b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
211b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final Pattern methodFilter = methodFilter();
212b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
213b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static Pattern methodFilter() {
214b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        String regex = System.getProperty("jsr166.methodFilter");
215b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return (regex == null) ? null : Pattern.compile(regex);
216b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
217b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
218b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // Instrumentation to debug very rare, but very annoying hung test runs.
219b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    static volatile TestCase currentTestCase;
220b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // static volatile int currentRun = 0;
221b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    static {
222b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Runnable checkForWedgedTest = new Runnable() { public void run() {
223b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // Avoid spurious reports with enormous runsPerTest.
224b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // A single test case run should never take more than 1 second.
225b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // But let's cap it at the high end too ...
226b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            final int timeoutMinutes =
227b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                Math.min(15, Math.max(runsPerTest / 60, 1));
228b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            for (TestCase lastTestCase = currentTestCase;;) {
229b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                try { MINUTES.sleep(timeoutMinutes); }
230b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                catch (InterruptedException unexpected) { break; }
231b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                if (lastTestCase == currentTestCase) {
232b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    System.err.printf(
233b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                        "Looks like we're stuck running test: %s%n",
234b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                        lastTestCase);
235b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                     System.err.printf(
236b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                         "Looks like we're stuck running test: %s (%d/%d)%n",
237b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                         lastTestCase, currentRun, runsPerTest);
238b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                     System.err.println("availableProcessors=" +
239b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                         Runtime.getRuntime().availableProcessors());
240b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                     System.err.printf("cpu model = %s%n", cpuModel());
241b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    dumpTestThreads();
242b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    // one stack dump is probably enough; more would be spam
243b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    break;
244b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                }
245b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                lastTestCase = currentTestCase;
246b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }}};
247b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest");
248b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        thread.setDaemon(true);
249b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        thread.start();
250b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
251b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
252b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//     public static String cpuModel() {
253b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//         try {
254b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//             Matcher matcher = Pattern.compile("model name\\s*: (.*)")
255b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                 .matcher(new String(
256b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//                      Files.readAllBytes(Paths.get("/proc/cpuinfo")), "UTF-8"));
257b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//             matcher.find();
258b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//             return matcher.group(1);
259b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//         } catch (Exception ex) { return null; }
260b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak//     }
2618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
262b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public void runBare() throws Throwable {
263b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        currentTestCase = this;
264b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        if (methodFilter == null
265b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            || methodFilter.matcher(toString()).find())
266b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            super.runBare();
267b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
268b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
269b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    protected void runTest() throws Throwable {
270b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        for (int i = 0; i < runsPerTest; i++) {
271b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // currentRun = i;
272b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (profileTests)
273b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                runTestProfiled();
274b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            else
275b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                super.runTest();
276b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
277b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
278b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
279b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    protected void runTestProfiled() throws Throwable {
280b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        for (int i = 0; i < 2; i++) {
281b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            long startTime = System.nanoTime();
282b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            super.runTest();
283b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            long elapsedMillis = millisElapsedSince(startTime);
284b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (elapsedMillis < profileThreshold)
285b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                break;
286b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // Never report first run of any test; treat it as a
287b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // warmup run, notably to trigger all needed classloading,
288b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (i > 0)
289b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                System.out.printf("%n%s: %d%n", toString(), elapsedMillis);
290b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
291b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
292b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
293b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
294b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Runs all JSR166 unit tests using junit.textui.TestRunner.
295b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
296b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // android-note: Removed because no junit.textui
297b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // public static void main(String[] args) {
298b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     main(suite(), args);
299b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // }
300b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
301b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // static class PithyResultPrinter extends junit.textui.ResultPrinter {
302b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     PithyResultPrinter(java.io.PrintStream writer) { super(writer); }
303b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     long runTime;
304b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     public void startTest(Test test) {}
305b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     protected void printHeader(long runTime) {
306b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         this.runTime = runTime; // defer printing for later
307b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
308b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     protected void printFooter(TestResult result) {
309b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         if (result.wasSuccessful()) {
310b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             getWriter().println("OK (" + result.runCount() + " tests)"
311b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //                 + "  Time: " + elapsedTimeAsString(runTime));
312b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         } else {
313b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             getWriter().println("Time: " + elapsedTimeAsString(runTime));
314b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             super.printFooter(result);
315b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         }
316b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
317b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // }
318b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
319b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
320b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns a TestRunner that doesn't bother with unnecessary
321b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * fluff, like printing a "." for each test case.
322b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
323b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // static junit.textui.TestRunner newPithyTestRunner() {
324b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     junit.textui.TestRunner runner = new junit.textui.TestRunner();
325b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     runner.setPrinter(new PithyResultPrinter(System.out));
326b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     return runner;
327b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // }
328b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
329b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
330b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Runs all unit tests in the given test suite.
331b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Actual behavior influenced by jsr166.* system properties.
332b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
333b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // static void main(Test suite, String[] args) {
334b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     if (useSecurityManager) {
335b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         System.err.println("Setting a permissive security manager");
336b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         Policy.setPolicy(permissivePolicy());
337b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         System.setSecurityManager(new SecurityManager());
338b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
339b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     for (int i = 0; i < suiteRuns; i++) {
340b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TestResult result = newPithyTestRunner().doRun(suite);
341b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         if (!result.wasSuccessful())
342b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             System.exit(1);
343b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         System.gc();
344b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         System.runFinalization();
345b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
346b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // }
347b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
348b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static TestSuite newTestSuite(Object... suiteOrClasses) {
349b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        TestSuite suite = new TestSuite();
350b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        for (Object suiteOrClass : suiteOrClasses) {
351b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (suiteOrClass instanceof TestSuite)
352b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                suite.addTest((TestSuite) suiteOrClass);
353b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            else if (suiteOrClass instanceof Class)
354b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                suite.addTest(new TestSuite((Class<?>) suiteOrClass));
355b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            else
356b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                throw new ClassCastException("not a test suite or class");
357b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
358b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return suite;
359b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
360b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
361b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static void addNamedTestClasses(TestSuite suite,
362b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                                           String... testClassNames) {
363b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        for (String testClassName : testClassNames) {
364b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            try {
365b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                Class<?> testClass = Class.forName(testClassName);
366b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                Method m = testClass.getDeclaredMethod("suite",
367b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                                                       new Class<?>[0]);
368b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                suite.addTest(newTestSuite((Test)m.invoke(null)));
369b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            } catch (Exception e) {
370b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                throw new Error("Missing test class", e);
371b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
372b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
373b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
374b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
375b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static final double JAVA_CLASS_VERSION;
376b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static final String JAVA_SPECIFICATION_VERSION;
377b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    static {
378b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        try {
379b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged(
380b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                new java.security.PrivilegedAction<Double>() {
381b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                public Double run() {
382b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    return Double.valueOf(System.getProperty("java.class.version"));}});
383b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            JAVA_SPECIFICATION_VERSION = java.security.AccessController.doPrivileged(
384b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                new java.security.PrivilegedAction<String>() {
385b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                public String run() {
386b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    return System.getProperty("java.specification.version");}});
387b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } catch (Throwable t) {
388b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            throw new Error(t);
389b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
390b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
391b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
392b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static boolean atLeastJava6() { return JAVA_CLASS_VERSION >= 50.0; }
393b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static boolean atLeastJava7() { return JAVA_CLASS_VERSION >= 51.0; }
394b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static boolean atLeastJava8() { return JAVA_CLASS_VERSION >= 52.0; }
395b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static boolean atLeastJava9() {
396b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return JAVA_CLASS_VERSION >= 53.0
397b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            // As of 2015-09, java9 still uses 52.0 class file version
398b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?(9|[0-9][0-9])$");
399b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
400b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static boolean atLeastJava10() {
401b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return JAVA_CLASS_VERSION >= 54.0
402b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?[0-9][0-9]$");
403b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
404b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
405b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
406b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Collects all JSR166 unit tests as one suite.
407b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
408b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // android-note: Removed because the CTS runner does a bad job of
409b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // public static Test suite() {
410b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     // Java7+ test classes
411b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     TestSuite suite = newTestSuite(
412b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ForkJoinPoolTest.suite(),
413b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ForkJoinTaskTest.suite(),
414b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         RecursiveActionTest.suite(),
415b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         RecursiveTaskTest.suite(),
416b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         LinkedTransferQueueTest.suite(),
417b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         PhaserTest.suite(),
418b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ThreadLocalRandomTest.suite(),
419b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AbstractExecutorServiceTest.suite(),
420b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AbstractQueueTest.suite(),
421b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AbstractQueuedSynchronizerTest.suite(),
422b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AbstractQueuedLongSynchronizerTest.suite(),
423b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ArrayBlockingQueueTest.suite(),
424b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ArrayDequeTest.suite(),
425b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicBooleanTest.suite(),
426b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicIntegerArrayTest.suite(),
427b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicIntegerFieldUpdaterTest.suite(),
428b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicIntegerTest.suite(),
429b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicLongArrayTest.suite(),
430b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicLongFieldUpdaterTest.suite(),
431b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicLongTest.suite(),
432b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicMarkableReferenceTest.suite(),
433b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicReferenceArrayTest.suite(),
434b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicReferenceFieldUpdaterTest.suite(),
435b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicReferenceTest.suite(),
436b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         AtomicStampedReferenceTest.suite(),
437b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentHashMapTest.suite(),
438b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentLinkedDequeTest.suite(),
439b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentLinkedQueueTest.suite(),
440b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentSkipListMapTest.suite(),
441b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentSkipListSubMapTest.suite(),
442b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentSkipListSetTest.suite(),
443b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ConcurrentSkipListSubSetTest.suite(),
444b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         CopyOnWriteArrayListTest.suite(),
445b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         CopyOnWriteArraySetTest.suite(),
446b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         CountDownLatchTest.suite(),
447b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         CyclicBarrierTest.suite(),
448b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         DelayQueueTest.suite(),
449b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         EntryTest.suite(),
450b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ExchangerTest.suite(),
451b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ExecutorsTest.suite(),
452b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ExecutorCompletionServiceTest.suite(),
453b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         FutureTaskTest.suite(),
454b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         LinkedBlockingDequeTest.suite(),
455b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         LinkedBlockingQueueTest.suite(),
456b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         LinkedListTest.suite(),
457b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         LockSupportTest.suite(),
458b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         PriorityBlockingQueueTest.suite(),
459b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         PriorityQueueTest.suite(),
460b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ReentrantLockTest.suite(),
461b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ReentrantReadWriteLockTest.suite(),
462b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ScheduledExecutorTest.suite(),
463b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ScheduledExecutorSubclassTest.suite(),
464b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         SemaphoreTest.suite(),
465b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         SynchronousQueueTest.suite(),
466b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         SystemTest.suite(),
467b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ThreadLocalTest.suite(),
468b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ThreadPoolExecutorTest.suite(),
469b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ThreadPoolExecutorSubclassTest.suite(),
470b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         ThreadTest.suite(),
471b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TimeUnitTest.suite(),
472b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TreeMapTest.suite(),
473b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TreeSetTest.suite(),
474b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TreeSubMapTest.suite(),
475b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         TreeSubSetTest.suite());
476b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
477b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     // Java8+ test classes
478b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     if (atLeastJava8()) {
479b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         String[] java8TestClassNames = {
480b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "Atomic8Test",
481b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "CompletableFutureTest",
482b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "ConcurrentHashMap8Test",
483b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "CountedCompleterTest",
484b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "DoubleAccumulatorTest",
485b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "DoubleAdderTest",
486b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "ForkJoinPool8Test",
487b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "ForkJoinTask8Test",
488b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "LongAccumulatorTest",
489b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "LongAdderTest",
490b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "SplittableRandomTest",
491b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "StampedLockTest",
492b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "SubmissionPublisherTest",
493b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             "ThreadLocalRandom8Test",
494b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         };
495b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         addNamedTestClasses(suite, java8TestClassNames);
496b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
497b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
498b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     // Java9+ test classes
499b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     if (atLeastJava9()) {
500b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         String[] java9TestClassNames = {
501b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //             // Currently empty, but expecting varhandle tests
502b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         };
503b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //         addNamedTestClasses(suite, java9TestClassNames);
504b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     }
505b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
506b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    //     return suite;
507b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // }
508b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
509b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /** Returns list of junit-style test method names in given class. */
510b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static ArrayList<String> testMethodNames(Class<?> testClass) {
511b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Method[] methods = testClass.getDeclaredMethods();
512b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        ArrayList<String> names = new ArrayList<String>(methods.length);
513b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        for (Method method : methods) {
514b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (method.getName().startsWith("test")
515b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                && Modifier.isPublic(method.getModifiers())
516b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                // method.getParameterCount() requires jdk8+
517b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                && method.getParameterTypes().length == 0) {
518b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                names.add(method.getName());
519b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
520b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
521b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return names;
522b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
523b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
524b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
525b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns junit-style testSuite for the given test class, but
526b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * parameterized by passing extra data to each test.
527b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
528b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static <ExtraData> Test parameterizedTestSuite
529b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        (Class<? extends JSR166TestCase> testClass,
530b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak         Class<ExtraData> dataClass,
531b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak         ExtraData data) {
532b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        try {
533b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            TestSuite suite = new TestSuite();
534b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            Constructor c =
535b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                testClass.getDeclaredConstructor(dataClass, String.class);
536b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            for (String methodName : testMethodNames(testClass))
537b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                suite.addTest((Test) c.newInstance(data, methodName));
538b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return suite;
539b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } catch (Exception e) {
540b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            throw new Error(e);
541b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
542b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
543b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
544b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
545b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns junit-style testSuite for the jdk8 extension of the
546b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * given test class, but parameterized by passing extra data to
547b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * each test.  Uses reflection to allow compilation in jdk7.
548b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
549b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public static <ExtraData> Test jdk8ParameterizedTestSuite
550b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        (Class<? extends JSR166TestCase> testClass,
551b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak         Class<ExtraData> dataClass,
552b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak         ExtraData data) {
553b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        if (atLeastJava8()) {
554b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            String name = testClass.getName();
555b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            String name8 = name.replaceAll("Test$", "8Test");
556b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (name.equals(name8)) throw new Error(name);
557b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            try {
558b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                return (Test)
559b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    Class.forName(name8)
560b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    .getMethod("testSuite", new Class[] { dataClass })
561b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    .invoke(null, data);
562b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            } catch (Exception e) {
563b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                throw new Error(e);
564b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
565b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } else {
566b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return new TestSuite();
567b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
568b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
569b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
570b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // Delays for timing-dependent tests, in milliseconds.
571ed4f365789d43b1961657195df223a19bf4ef20fPrzemyslaw Szczepaniak
5728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static long SHORT_DELAY_MS;
5738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static long SMALL_DELAY_MS;
5748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static long MEDIUM_DELAY_MS;
5758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static long LONG_DELAY_MS;
5768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
5778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
578b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns the shortest timed delay. This can be scaled up for
579b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * slow machines using the jsr166.delay.factor system property,
580b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * or via jtreg's -timeoutFactor: flag.
581b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * http://openjdk.java.net/jtreg/command-help.html
5828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
5838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    protected long getShortDelay() {
584b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return (long) (50 * delayFactor * jtregTestTimeoutFactor);
5858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
5868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
5878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
5888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Sets delays as multiples of SHORT_DELAY.
5898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
5908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    protected void setDelays() {
5918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        SHORT_DELAY_MS = getShortDelay();
5928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        SMALL_DELAY_MS  = SHORT_DELAY_MS * 5;
5938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
5948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        LONG_DELAY_MS   = SHORT_DELAY_MS * 200;
5958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
5968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
5978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
5988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Returns a timeout in milliseconds to be used in tests that
5998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * verify that operations block or time out.
6008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    long timeoutMillis() {
6028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return SHORT_DELAY_MS / 4;
6038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
606b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns a new Date instance representing a time at least
607b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * delayMillis milliseconds in the future.
6088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    Date delayedDate(long delayMillis) {
610b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // Add 1 because currentTimeMillis is known to round into the past.
611b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new Date(System.currentTimeMillis() + delayMillis + 1);
6128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
6158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * The first exception encountered if any threadAssertXXX method fails.
6168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    private final AtomicReference<Throwable> threadFailure
6188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        = new AtomicReference<Throwable>(null);
6198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
6218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Records an exception so that it can be rethrown later in the test
6228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * harness thread, triggering a test case failure.  Only the first
6238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * failure is recorded; subsequent calls to this method from within
6248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the same test have no effect.
6258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadRecordFailure(Throwable t) {
627b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        System.err.println(t);
628b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        dumpTestThreads();
6298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        threadFailure.compareAndSet(null, t);
6308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void setUp() {
6338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        setDelays();
6348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
636b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    void tearDownFail(String format, Object... args) {
637b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        String msg = toString() + ": " + String.format(format, args);
638b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        System.err.println(msg);
639b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        dumpTestThreads();
640b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        throw new AssertionFailedError(msg);
641b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
642b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
6438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
6448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Extra checks that get done for all test cases.
6458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     *
6468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Triggers test case failure if any thread assertions have failed,
6478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * by rethrowing, in the test harness thread, any exception recorded
6488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * earlier by threadRecordFailure.
6498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     *
6508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Triggers test case failure if interrupt status is set in the main thread.
6518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void tearDown() throws Exception {
6538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        Throwable t = threadFailure.getAndSet(null);
6548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        if (t != null) {
6558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (t instanceof Error)
6568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw (Error) t;
6578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else if (t instanceof RuntimeException)
6588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw (RuntimeException) t;
6598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else if (t instanceof Exception)
6608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw (Exception) t;
6618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else {
6628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                AssertionFailedError afe =
6638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    new AssertionFailedError(t.toString());
6648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                afe.initCause(t);
6658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw afe;
6668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
6678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
6688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        if (Thread.interrupted())
670b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            tearDownFail("interrupt status set in main thread");
6718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        checkForkJoinPoolThreadLeaks();
6738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
676b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Finds missing PoolCleaners
6778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
6788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void checkForkJoinPoolThreadLeaks() throws InterruptedException {
679b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Thread[] survivors = new Thread[7];
6808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        int count = Thread.enumerate(survivors);
6818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        for (int i = 0; i < count; i++) {
6828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            Thread thread = survivors[i];
6838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            String name = thread.getName();
6848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (name.startsWith("ForkJoinPool-")) {
6858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                // give thread some time to terminate
6868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                thread.join(LONG_DELAY_MS);
687b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                if (thread.isAlive())
688b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    tearDownFail("Found leaked ForkJoinPool thread thread=%s",
689b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                                 thread);
6908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
6918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
692b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
693b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        if (!ForkJoinPool.commonPool()
694b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            .awaitQuiescence(LONG_DELAY_MS, MILLISECONDS))
695b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            tearDownFail("ForkJoin common pool thread stuck");
6968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
6978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
6988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
6998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like fail(reason), but additionally recording (using
7008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadFail(String reason) {
7048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            fail(reason);
7068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (AssertionFailedError t) {
7078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            threadRecordFailure(t);
708b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            throw t;
7098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertTrue(b), but additionally recording (using
7148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertTrue(boolean b) {
7188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertTrue(b);
7208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (AssertionFailedError t) {
7218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            threadRecordFailure(t);
7228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw t;
7238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertFalse(b), but additionally recording (using
7288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertFalse(boolean b) {
7328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertFalse(b);
7348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (AssertionFailedError t) {
7358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            threadRecordFailure(t);
7368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw t;
7378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertNull(x), but additionally recording (using
7428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertNull(Object x) {
7468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertNull(x);
7488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (AssertionFailedError t) {
7498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            threadRecordFailure(t);
7508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw t;
7518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertEquals(x, y), but additionally recording (using
7568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertEquals(long x, long y) {
7608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertEquals(x, y);
7628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (AssertionFailedError t) {
7638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            threadRecordFailure(t);
7648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw t;
7658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertEquals(x, y), but additionally recording (using
7708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertEquals(Object x, Object y) {
7748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertEquals(x, y);
7768e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (AssertionFailedError fail) {
7778e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadRecordFailure(fail);
7788e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            throw fail;
7798e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) {
7808e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
7818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Just like assertSame(x, y), but additionally recording (using
7868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * threadRecordFailure) any AssertionFailedError thrown, so that
7878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the current testcase will fail.
7888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
7898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadAssertSame(Object x, Object y) {
7908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
7918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertSame(x, y);
7928e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (AssertionFailedError fail) {
7938e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadRecordFailure(fail);
7948e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            throw fail;
7958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
7968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
7978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
7988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
7998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Calls threadFail with message "should throw exception".
8008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
8018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadShouldThrow() {
8028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        threadFail("should throw exception");
8038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
8048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
8058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
8068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Calls threadFail with message "should throw" + exceptionName.
8078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
8088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadShouldThrow(String exceptionName) {
8098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        threadFail("should throw " + exceptionName);
8108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
8118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
8128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
8138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Records the given exception using {@link #threadRecordFailure},
8148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * then rethrows the exception, wrapping it in an
8158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * AssertionFailedError if necessary.
8168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
8178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void threadUnexpectedException(Throwable t) {
8188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        threadRecordFailure(t);
8198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.printStackTrace();
8208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        if (t instanceof RuntimeException)
8218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw (RuntimeException) t;
8228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        else if (t instanceof Error)
8238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw (Error) t;
8248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        else {
8258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            AssertionFailedError afe =
8268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                new AssertionFailedError("unexpected exception: " + t);
8278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            afe.initCause(t);
8288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw afe;
8298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
8308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
8318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
8328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
8338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Delays, via Thread.sleep, for the given millisecond delay, but
8348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * if the sleep is shorter than specified, may re-sleep or yield
835b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * until time elapses.  Ensures that the given time, as measured
836b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * by System.nanoTime(), has elapsed.
8378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
8388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    static void delay(long millis) throws InterruptedException {
839b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        long nanos = millis * (1000 * 1000);
840b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final long wakeupTime = System.nanoTime() + nanos;
841b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        do {
8428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (millis > 0L)
8438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                Thread.sleep(millis);
8448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else // too short to sleep
8458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                Thread.yield();
846b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            nanos = wakeupTime - System.nanoTime();
847b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            millis = nanos / (1000 * 1000);
848b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } while (nanos >= 0L);
849b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
850b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
851b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
852b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Allows use of try-with-resources with per-test thread pools.
853b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
854b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    class PoolCleaner implements AutoCloseable {
855b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        private final ExecutorService pool;
856b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public PoolCleaner(ExecutorService pool) { this.pool = pool; }
857b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public void close() { joinPool(pool); }
858b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
859b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
860b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
861b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * An extension of PoolCleaner that has an action to release the pool.
862b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
863b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    class PoolCleanerWithReleaser extends PoolCleaner {
864b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        private final Runnable releaser;
865b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public PoolCleanerWithReleaser(ExecutorService pool, Runnable releaser) {
866b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            super(pool);
867b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            this.releaser = releaser;
868b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
869b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public void close() {
870b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            try {
871b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                releaser.run();
872b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            } finally {
873b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                super.close();
874b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
8758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
8768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
8778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
878b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    PoolCleaner cleaner(ExecutorService pool) {
879b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new PoolCleaner(pool);
880b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
881b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
882b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    PoolCleaner cleaner(ExecutorService pool, Runnable releaser) {
883b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new PoolCleanerWithReleaser(pool, releaser);
884b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
885b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
886b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    PoolCleaner cleaner(ExecutorService pool, CountDownLatch latch) {
887b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new PoolCleanerWithReleaser(pool, releaser(latch));
888b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
889b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
890b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    Runnable releaser(final CountDownLatch latch) {
891b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new Runnable() { public void run() {
892b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            do { latch.countDown(); }
893b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            while (latch.getCount() > 0);
894b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }};
895b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
896b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
897b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    PoolCleaner cleaner(ExecutorService pool, AtomicBoolean flag) {
898b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new PoolCleanerWithReleaser(pool, releaser(flag));
899b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
900b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
901b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    Runnable releaser(final AtomicBoolean flag) {
902b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new Runnable() { public void run() { flag.set(true); }};
903b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
904b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
9058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
9068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Waits out termination of a thread pool or fails doing so.
9078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
908b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    void joinPool(ExecutorService pool) {
9098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
910b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            pool.shutdown();
911b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) {
912b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                try {
913b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    threadFail("ExecutorService " + pool +
914b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                               " did not terminate in a timely manner");
915b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                } finally {
916b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    // last resort, for the benefit of subsequent tests
917b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    pool.shutdownNow();
918b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    pool.awaitTermination(MEDIUM_DELAY_MS, MILLISECONDS);
919b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                }
920b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
9218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (SecurityException ok) {
9228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            // Allowed in case test doesn't have privs
9238e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) {
924b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            threadFail("Unexpected InterruptedException");
9258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
9268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
9278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
928b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /** Like Runnable, but with the freedom to throw anything */
929b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    interface Action { public void run() throws Throwable; }
930b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
9318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
932b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Runs all the given actions in parallel, failing if any fail.
933b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Useful for running multiple variants of tests that are
934b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * necessarily individually slow because they must block.
9358e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     */
936b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    void testInParallel(Action ... actions) {
937b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        ExecutorService pool = Executors.newCachedThreadPool();
938b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        try (PoolCleaner cleaner = cleaner(pool)) {
939b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            ArrayList<Future<?>> futures = new ArrayList<>(actions.length);
940b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            for (final Action action : actions)
941b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                futures.add(pool.submit(new CheckedRunnable() {
942b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    public void realRun() throws Throwable { action.run();}}));
943b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            for (Future<?> future : futures)
944b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                try {
945b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    assertNull(future.get(LONG_DELAY_MS, MILLISECONDS));
946b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                } catch (ExecutionException ex) {
947b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    threadUnexpectedException(ex.getCause());
948b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                } catch (Exception ex) {
949b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                    threadUnexpectedException(ex);
950b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                }
951b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
952b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
953b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
954b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
955b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * A debugging tool to print stack traces of most threads, as jstack does.
956b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Uninteresting threads are filtered out.
957b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
958b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    static void dumpTestThreads() {
959b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // Android-change no ThreadMXBean
960b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
961b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // System.err.println("------ stacktrace dump start ------");
962b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
963b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     String name = info.getThreadName();
964b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     if ("Signal Dispatcher".equals(name))
965b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         continue;
966b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     if ("Reference Handler".equals(name)
967b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         && info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
968b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         continue;
969b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     if ("Finalizer".equals(name)
970b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
971b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         continue;
972b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     if ("checkForWedgedTest".equals(name))
973b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         continue;
974b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     System.err.print(info);
975b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // }
976b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // System.err.println("------ stacktrace dump end ------");
9778e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    }
9788e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
9798e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    /**
9808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that thread does not terminate within the default
9818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * millisecond delay of {@code timeoutMillis()}.
9828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
9838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertThreadStaysAlive(Thread thread) {
9848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertThreadStaysAlive(thread, timeoutMillis());
9858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
9868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
9878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
9888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that thread does not terminate within the given millisecond delay.
9898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
9908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertThreadStaysAlive(Thread thread, long millis) {
9918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
9928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            // No need to optimize the failing case via Thread.join.
9938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(millis);
9948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertTrue(thread.isAlive());
9958e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) {
996b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            threadFail("Unexpected InterruptedException");
9978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
9988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
9998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that the threads do not terminate within the default
10028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * millisecond delay of {@code timeoutMillis()}.
10038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertThreadsStayAlive(Thread... threads) {
10058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertThreadsStayAlive(timeoutMillis(), threads);
10068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that the threads do not terminate within the given millisecond delay.
10108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertThreadsStayAlive(long millis, Thread... threads) {
10128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
10138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            // No need to optimize the failing case via Thread.join.
10148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(millis);
10158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            for (Thread thread : threads)
10168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                assertTrue(thread.isAlive());
10178e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) {
1018b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            threadFail("Unexpected InterruptedException");
10198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
10208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that future.get times out, with the default timeout of
10248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * {@code timeoutMillis()}.
10258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertFutureTimesOut(Future future) {
10278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertFutureTimesOut(future, timeoutMillis());
10288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Checks that future.get times out, with the given millisecond timeout.
10328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertFutureTimesOut(Future future, long timeoutMillis) {
10348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        long startTime = System.nanoTime();
10358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
10368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            future.get(timeoutMillis, MILLISECONDS);
10378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            shouldThrow();
10388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } catch (TimeoutException success) {
10398e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Exception fail) {
10408e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
10418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } finally { future.cancel(true); }
10428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
10438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Fails with message "should throw exception".
10478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void shouldThrow() {
10498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        fail("Should throw exception");
10508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Fails with message "should throw " + exceptionName.
10548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void shouldThrow(String exceptionName) {
10568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        fail("Should throw " + exceptionName);
10578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
10588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * The number of elements to place in collections, arrays, etc.
10618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final int SIZE = 20;
10638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    // Some convenient Integer constants
10658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer zero  = new Integer(0);
10678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer one   = new Integer(1);
10688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer two   = new Integer(2);
10698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer three = new Integer(3);
10708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer four  = new Integer(4);
10718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer five  = new Integer(5);
10728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer six   = new Integer(6);
10738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer seven = new Integer(7);
10748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer eight = new Integer(8);
10758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer nine  = new Integer(9);
10768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m1  = new Integer(-1);
10778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m2  = new Integer(-2);
10788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m3  = new Integer(-3);
10798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m4  = new Integer(-4);
10808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m5  = new Integer(-5);
10818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m6  = new Integer(-6);
10828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final Integer m10 = new Integer(-10);
10838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
10848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
10858e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * Runs Runnable r with a security policy that permits precisely
10868e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * the specified permissions.  If there is no current security
10878e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * manager, the runnable is run twice, both with and without a
10888e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * security manager.  We require that any security manager permit
10898e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * getPolicy/setPolicy.
10908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
10918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void runWithPermissions(Runnable r, Permission... permissions) {
10925d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer        // Android-changed: no SecurityManager
1093b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // SecurityManager sm = System.getSecurityManager();
1094b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // if (sm == null) {
1095b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     r.run();
1096b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // }
1097b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // runWithSecurityManagerWithPermissions(r, permissions);
109805fd64ae4c92b1787a4cfa632ea1e6b3ceeeff91Narayan Kamath        r.run();
10998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
11008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
11018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
11028e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * Runs Runnable r with a security policy that permits precisely
11038e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * the specified permissions.  If there is no current security
11048e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * manager, a temporary one is set for the duration of the
11058e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * Runnable.  We require that any security manager permit
11068e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * getPolicy/setPolicy.
11078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
11088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void runWithSecurityManagerWithPermissions(Runnable r,
11098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                                                      Permission... permissions) {
11105d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer        // Android-changed: no SecurityManager
1111b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // SecurityManager sm = System.getSecurityManager();
1112b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // if (sm == null) {
1113b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     Policy savedPolicy = Policy.getPolicy();
1114b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     try {
1115b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         Policy.setPolicy(permissivePolicy());
1116b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         System.setSecurityManager(new SecurityManager());
1117b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         runWithSecurityManagerWithPermissions(r, permissions);
1118b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     } finally {
1119b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         System.setSecurityManager(null);
1120b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         Policy.setPolicy(savedPolicy);
1121b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     }
1122b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // } else {
1123b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     Policy savedPolicy = Policy.getPolicy();
1124b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     AdjustablePolicy policy = new AdjustablePolicy(permissions);
1125b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     Policy.setPolicy(policy);
1126b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
1127b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     try {
1128b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         r.run();
1129b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     } finally {
1130b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         policy.addPermission(new SecurityPermission("setPolicy"));
1131b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //         Policy.setPolicy(savedPolicy);
1132b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        //     }
1133b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        // }
113405fd64ae4c92b1787a4cfa632ea1e6b3ceeeff91Narayan Kamath        r.run();
11358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
11368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
11378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
11388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Runs a runnable without any permissions.
11398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
11408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void runWithoutPermissions(Runnable r) {
11418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        runWithPermissions(r);
11428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
11438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
11448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
11458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * A security policy where new permissions can be dynamically added
11468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * or all cleared.
11478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
11488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class AdjustablePolicy extends java.security.Policy {
11498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        Permissions perms = new Permissions();
11508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AdjustablePolicy(Permission... permissions) {
11518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            for (Permission permission : permissions)
11528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                perms.add(permission);
11538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
11548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        void addPermission(Permission perm) { perms.add(perm); }
11558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        void clearPermissions() { perms = new Permissions(); }
11568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public PermissionCollection getPermissions(CodeSource cs) {
11578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return perms;
11588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
11598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public PermissionCollection getPermissions(ProtectionDomain pd) {
11608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return perms;
11618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
11628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public boolean implies(ProtectionDomain pd, Permission p) {
11638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return perms.implies(p);
11648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
11658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void refresh() {}
11668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public String toString() {
11678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            List<Permission> ps = new ArrayList<Permission>();
11688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            for (Enumeration<Permission> e = perms.elements(); e.hasMoreElements();)
11698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                ps.add(e.nextElement());
11708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return "AdjustablePolicy with permissions " + ps;
11718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
11728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
11738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
11748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
11758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Returns a policy containing all the permissions we ever need.
11768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
11778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static Policy permissivePolicy() {
11788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return new AdjustablePolicy
11798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            // Permissions j.u.c. needs directly
11808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            (new RuntimePermission("modifyThread"),
11818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new RuntimePermission("getClassLoader"),
11828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new RuntimePermission("setContextClassLoader"),
11838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             // Permissions needed to change permissions!
11848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new SecurityPermission("getPolicy"),
11858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new SecurityPermission("setPolicy"),
11868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new RuntimePermission("setSecurityManager"),
11878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             // Permissions needed by the junit test harness
11888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new RuntimePermission("accessDeclaredMembers"),
11898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new PropertyPermission("*", "read"),
11908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle             new java.io.FilePermission("<<ALL FILES>>", "read"));
11918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
11928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
11938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
11948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Sleeps until the given time has elapsed.
11958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Throws AssertionFailedError if interrupted.
11968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
11978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void sleep(long millis) {
11988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
11998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(millis);
12008e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) {
12018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            AssertionFailedError afe =
12028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                new AssertionFailedError("Unexpected InterruptedException");
12038e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            afe.initCause(fail);
12048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            throw afe;
12058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
12068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
12078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
12088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
12098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Spin-waits up to the specified number of milliseconds for the given
12108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
12118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
12128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
12138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        long startTime = System.nanoTime();
12148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        for (;;) {
12158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            Thread.State s = thread.getState();
12168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (s == Thread.State.BLOCKED ||
12178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                s == Thread.State.WAITING ||
12188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                s == Thread.State.TIMED_WAITING)
12198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return;
12208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else if (s == Thread.State.TERMINATED)
12218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                fail("Unexpected thread termination");
12228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            else if (millisElapsedSince(startTime) > timeoutMillis) {
12238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadAssertTrue(thread.isAlive());
1224cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                fail("timed out waiting for thread to enter wait state");
12258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
12268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            Thread.yield();
12278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
12288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
12298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
12308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
1231cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * Spin-waits up to the specified number of milliseconds for the given
1232cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
1233cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * and additionally satisfy the given condition.
1234cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     */
1235cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    void waitForThreadToEnterWaitState(
1236cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        Thread thread, long timeoutMillis, Callable<Boolean> waitingForGodot) {
1237cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        long startTime = 0L;
1238cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        for (;;) {
1239cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            Thread.State s = thread.getState();
1240cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            if (s == Thread.State.BLOCKED ||
1241cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                s == Thread.State.WAITING ||
1242cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                s == Thread.State.TIMED_WAITING) {
1243cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                try {
1244cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                    if (waitingForGodot.call())
1245cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                        return;
1246cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                } catch (Throwable fail) { threadUnexpectedException(fail); }
1247cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            }
1248cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            else if (s == Thread.State.TERMINATED)
1249cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                fail("Unexpected thread termination");
1250cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            else if (startTime == 0L)
1251cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                startTime = System.nanoTime();
1252cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            else if (millisElapsedSince(startTime) > timeoutMillis) {
1253cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                threadAssertTrue(thread.isAlive());
1254cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer                fail("timed out waiting for thread to enter wait state");
1255cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            }
1256cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer            Thread.yield();
1257cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        }
1258cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    }
1259cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer
1260cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    /**
1261cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
1262cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
12638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
12648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void waitForThreadToEnterWaitState(Thread thread) {
12658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
12668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
12678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
12688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
1269cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
1270cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
1271cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     * and additionally satisfy the given condition.
1272cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer     */
1273cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    void waitForThreadToEnterWaitState(
1274cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        Thread thread, Callable<Boolean> waitingForGodot) {
1275cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
1276cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    }
1277cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer
1278cff661d65e3e6e2ac731ebbf938251656deb4be4Tobias Thierer    /**
12798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Returns the number of milliseconds since time given by
12808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * startNanoTime, which must have been previously returned from a
12818e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * call to {@link System#nanoTime()}.
12828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
12838e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    static long millisElapsedSince(long startNanoTime) {
12848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
12858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
12868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
12878e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//     void assertTerminatesPromptly(long timeoutMillis, Runnable r) {
12888e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//         long startTime = System.nanoTime();
12898e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//         try {
12908e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//             r.run();
12918e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//         } catch (Throwable fail) { threadUnexpectedException(fail); }
12928e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//         if (millisElapsedSince(startTime) > timeoutMillis/2)
12938e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//             throw new AssertionFailedError("did not return promptly");
12948e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//     }
12958e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
12968e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//     void assertTerminatesPromptly(Runnable r) {
12978e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//         assertTerminatesPromptly(LONG_DELAY_MS/2, r);
12988e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath//     }
12998e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
13008e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    /**
13018e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * Checks that timed f.get() returns the expected value, and does not
13028e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     * wait for the timeout to elapse before returning.
13038e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath     */
13048e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    <T> void checkTimedGet(Future<T> f, T expectedValue, long timeoutMillis) {
13058e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        long startTime = System.nanoTime();
13068e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        try {
13078e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS));
13088e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) { threadUnexpectedException(fail); }
13098e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        if (millisElapsedSince(startTime) > timeoutMillis/2)
13108e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            throw new AssertionFailedError("timed get did not return promptly");
13118e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    }
13128e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
13138e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    <T> void checkTimedGet(Future<T> f, T expectedValue) {
13148e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        checkTimedGet(f, expectedValue, LONG_DELAY_MS);
13158e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    }
13168e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
13178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
13188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Returns a new started daemon Thread running the given runnable.
13198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
13208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    Thread newStartedThread(Runnable runnable) {
13218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        Thread t = new Thread(runnable);
13228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.setDaemon(true);
13238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.start();
13248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return t;
13258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
13268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
13288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Waits for the specified time (in milliseconds) for the thread
13298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * to terminate (using {@link Thread#join(long)}), else interrupts
13308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the thread (in the hope that it may terminate later) and fails.
13318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
13328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void awaitTermination(Thread t, long timeoutMillis) {
13338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
13348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            t.join(timeoutMillis);
13358e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) {
13368e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
13378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        } finally {
13388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (t.getState() != Thread.State.TERMINATED) {
13398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                t.interrupt();
1340b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                threadFail("timed out waiting for thread to terminate");
13418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
13428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
13438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
13448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
13468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Waits for LONG_DELAY_MS milliseconds for the thread to
13478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * terminate (using {@link Thread#join(long)}), else interrupts
13488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * the thread (in the hope that it may terminate later) and fails.
13498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
13508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void awaitTermination(Thread t) {
13518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        awaitTermination(t, LONG_DELAY_MS);
13528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
13538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    // Some convenient Runnable classes
13558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedRunnable implements Runnable {
13578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract void realRun() throws Throwable;
13588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final void run() {
13608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
13618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                realRun();
13628e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
13638e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
13648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
13658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
13668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
13678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class RunnableShouldThrow implements Runnable {
13698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract void realRun() throws Throwable;
13708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        final Class<?> exceptionClass;
13728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) {
13748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            this.exceptionClass = exceptionClass;
13758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
13768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final void run() {
13788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
13798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                realRun();
13808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadShouldThrow(exceptionClass.getSimpleName());
13818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (Throwable t) {
13828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                if (! exceptionClass.isInstance(t))
13838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    threadUnexpectedException(t);
13848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
13858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
13868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
13878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class ThreadShouldThrow extends Thread {
13898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract void realRun() throws Throwable;
13908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        final Class<?> exceptionClass;
13928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) {
13948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            this.exceptionClass = exceptionClass;
13958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
13968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
13978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final void run() {
13988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
13998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                realRun();
14008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadShouldThrow(exceptionClass.getSimpleName());
14018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (Throwable t) {
14028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                if (! exceptionClass.isInstance(t))
14038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    threadUnexpectedException(t);
14048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
14058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
14068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedInterruptedRunnable implements Runnable {
14098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract void realRun() throws Throwable;
14108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final void run() {
14128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
14138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                realRun();
14148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadShouldThrow("InterruptedException");
14158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException success) {
14168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadAssertFalse(Thread.interrupted());
14178e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
14188e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
14198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
14208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
14218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedCallable<T> implements Callable<T> {
14248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract T realCall() throws Throwable;
14258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final T call() {
14278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
14288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return realCall();
14298e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
14308e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
14318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return null;
14328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
14338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
14348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedInterruptedCallable<T>
14378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        implements Callable<T> {
14388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract T realCall() throws Throwable;
14398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public final T call() {
14418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
14428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                T result = realCall();
14438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadShouldThrow("InterruptedException");
14448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return result;
14458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException success) {
14468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threadAssertFalse(Thread.interrupted());
14478e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
14488e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
14498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
14508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return null;
14518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
14528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class NoOpRunnable implements Runnable {
14558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {}
14568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class NoOpCallable implements Callable {
14598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public Object call() { return Boolean.TRUE; }
14608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static final String TEST_STRING = "a test string";
14638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class StringTask implements Callable<String> {
1465b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final String value;
1466b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public StringTask() { this(TEST_STRING); }
1467b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public StringTask(String value) { this.value = value; }
1468b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public String call() { return value; }
14698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
14718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
14728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return new CheckedCallable<String>() {
14738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            protected String realCall() {
14748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                try {
14758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    latch.await();
14768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                } catch (InterruptedException quittingTime) {}
14778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return TEST_STRING;
14788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }};
14798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1481b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public Runnable countDowner(final CountDownLatch latch) {
14828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return new CheckedRunnable() {
14838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            public void realRun() throws InterruptedException {
1484b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                latch.countDown();
14858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }};
14868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
14878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1488b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    class LatchAwaiter extends CheckedRunnable {
1489b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        static final int NEW = 0;
1490b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        static final int RUNNING = 1;
1491b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        static final int DONE = 2;
1492b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final CountDownLatch latch;
1493b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        int state = NEW;
1494b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        LatchAwaiter(CountDownLatch latch) { this.latch = latch; }
1495b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public void realRun() throws InterruptedException {
1496b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            state = 1;
1497b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            await(latch);
1498b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            state = 2;
1499b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
1500b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
1501b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
1502b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public LatchAwaiter awaiter(CountDownLatch latch) {
1503b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new LatchAwaiter(latch);
1504b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
1505b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
1506b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public void await(CountDownLatch latch, long timeoutMillis) {
15078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
1508b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (!latch.await(timeoutMillis, MILLISECONDS))
1509b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                fail("timed out waiting for CountDownLatch for "
1510b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                     + (timeoutMillis/1000) + " sec");
15118e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) {
15128e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
15138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1516b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public void await(CountDownLatch latch) {
1517b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        await(latch, LONG_DELAY_MS);
1518b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
1519b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
15208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void await(Semaphore semaphore) {
15218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
1522b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (!semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS))
1523b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                fail("timed out waiting for Semaphore for "
1524b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                     + (LONG_DELAY_MS/1000) + " sec");
15258e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) {
15268e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
15278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     /**
15318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//      * Spin-waits up to LONG_DELAY_MS until flag becomes true.
15328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//      */
15338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     public void await(AtomicBoolean flag) {
15348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//         await(flag, LONG_DELAY_MS);
15358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     }
15368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     /**
15388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//      * Spin-waits up to the specified timeout until flag becomes true.
15398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//      */
15408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     public void await(AtomicBoolean flag, long timeoutMillis) {
15418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//         long startTime = System.nanoTime();
15428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//         while (!flag.get()) {
15438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//             if (millisElapsedSince(startTime) > timeoutMillis)
15448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//                 throw new AssertionFailedError("timed out");
15458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//             Thread.yield();
15468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//         }
15478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle//     }
15488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class NPETask implements Callable<String> {
15508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public String call() { throw new NullPointerException(); }
15518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class CallableOne implements Callable<Integer> {
15548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public Integer call() { return one; }
15558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class ShortRunnable extends CheckedRunnable {
15588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() throws Throwable {
15598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(SHORT_DELAY_MS);
15608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
15648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() throws InterruptedException {
15658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(SHORT_DELAY_MS);
15668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class SmallRunnable extends CheckedRunnable {
15708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() throws Throwable {
15718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(SMALL_DELAY_MS);
15728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
15768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() {
15778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
15788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(SMALL_DELAY_MS);
15798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
15808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class SmallCallable extends CheckedCallable {
15848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected Object realCall() throws InterruptedException {
15858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(SMALL_DELAY_MS);
15868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return Boolean.TRUE;
15878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class MediumRunnable extends CheckedRunnable {
15918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() throws Throwable {
15928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(MEDIUM_DELAY_MS);
15938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
15948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
15958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
15968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
15978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() throws InterruptedException {
15988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            delay(MEDIUM_DELAY_MS);
15998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
16038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return new CheckedRunnable() {
16048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            protected void realRun() {
16058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                try {
16068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    delay(timeoutMillis);
16078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                } catch (InterruptedException ok) {}
16088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }};
16098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
16128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() {
16138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(MEDIUM_DELAY_MS);
16158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
16208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected void realRun() {
16218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(LONG_DELAY_MS);
16238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
16288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * For use as ThreadFactory in constructors
16298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
16308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class SimpleThreadFactory implements ThreadFactory {
16318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public Thread newThread(Runnable r) {
16328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return new Thread(r);
16338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public interface TrackedRunnable extends Runnable {
16378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        boolean isDone();
16388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static TrackedRunnable trackedRunnable(final long timeoutMillis) {
16418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        return new TrackedRunnable() {
16428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                private volatile boolean done = false;
16438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                public boolean isDone() { return done; }
16448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                public void run() {
16458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    try {
16468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                        delay(timeoutMillis);
16478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                        done = true;
16488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    } catch (InterruptedException ok) {}
16498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                }
16508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            };
16518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedShortRunnable implements Runnable {
16548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
16558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {
16568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(SHORT_DELAY_MS);
16588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                done = true;
16598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedSmallRunnable implements Runnable {
16648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
16658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {
16668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(SMALL_DELAY_MS);
16688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                done = true;
16698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedMediumRunnable implements Runnable {
16748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
16758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {
16768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(MEDIUM_DELAY_MS);
16788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                done = true;
16798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedLongRunnable implements Runnable {
16848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
16858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {
16868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
16878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(LONG_DELAY_MS);
16888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                done = true;
16898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
16908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
16938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedNoOpRunnable implements Runnable {
16948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
16958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void run() {
16968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            done = true;
16978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
16988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
16998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class TrackedCallable implements Callable {
17018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public volatile boolean done = false;
17028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public Object call() {
17038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                delay(SMALL_DELAY_MS);
17058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                done = true;
17068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (InterruptedException ok) {}
17078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return Boolean.TRUE;
17088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
17098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
17128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Analog of CheckedRunnable for RecursiveAction
17138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
17148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedRecursiveAction extends RecursiveAction {
17158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract void realCompute() throws Throwable;
17168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        @Override protected final void compute() {
17188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                realCompute();
17208e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
17218e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
17228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
17238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
17248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
17278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * Analog of CheckedCallable for RecursiveTask
17288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
17298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public abstract class CheckedRecursiveTask<T> extends RecursiveTask<T> {
17308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        protected abstract T realCompute() throws Throwable;
17318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        @Override protected final T compute() {
17338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return realCompute();
17358e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Throwable fail) {
17368e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                threadUnexpectedException(fail);
17378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return null;
17388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
17398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
17408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
17438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * For use as RejectedExecutionHandler in constructors
17448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
17458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public static class NoOpREHandler implements RejectedExecutionHandler {
17468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public void rejectedExecution(Runnable r,
17478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                                      ThreadPoolExecutor executor) {}
17488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
17518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * A CyclicBarrier that uses timed await and fails with
17528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * AssertionFailedErrors instead of throwing checked exceptions.
17538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
17548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public class CheckedBarrier extends CyclicBarrier {
17558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public CheckedBarrier(int parties) { super(parties); }
17568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        public int await() {
17588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                return super.await(2 * LONG_DELAY_MS, MILLISECONDS);
17608e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (TimeoutException timedOut) {
17618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw new AssertionFailedError("timed out");
17628e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            } catch (Exception fail) {
17638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                AssertionFailedError afe =
17648e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                    new AssertionFailedError("Unexpected exception: " + fail);
17658e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath                afe.initCause(fail);
17668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                throw afe;
17678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
17688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
17698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void checkEmpty(BlockingQueue q) {
17728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
17738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertTrue(q.isEmpty());
17748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertEquals(0, q.size());
17758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertNull(q.peek());
17768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertNull(q.poll());
17778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertNull(q.poll(0, MILLISECONDS));
17788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertEquals(q.toString(), "[]");
17798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertTrue(Arrays.equals(q.toArray(), new Object[0]));
17808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertFalse(q.iterator().hasNext());
17818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                q.element();
17838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                shouldThrow();
17848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (NoSuchElementException success) {}
17858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                q.iterator().next();
17878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                shouldThrow();
17888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (NoSuchElementException success) {}
17898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try {
17908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                q.remove();
17918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                shouldThrow();
17928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            } catch (NoSuchElementException success) {}
17938e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
17948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
17968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertSerialEquals(Object x, Object y) {
17978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(Arrays.equals(serialBytes(x), serialBytes(y)));
17988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
17998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
18008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    void assertNotSerialEquals(Object x, Object y) {
18018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertFalse(Arrays.equals(serialBytes(x), serialBytes(y)));
18028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
18038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
18048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    byte[] serialBytes(Object o) {
18058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
18068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            ByteArrayOutputStream bos = new ByteArrayOutputStream();
18078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            ObjectOutputStream oos = new ObjectOutputStream(bos);
18088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            oos.writeObject(o);
18098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            oos.flush();
18108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            oos.close();
18118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return bos.toByteArray();
18128e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) {
18138e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
18148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return new byte[0];
18158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
18168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
18178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
18188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    @SuppressWarnings("unchecked")
18198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    <T> T serialClone(T o) {
18208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        try {
18218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            ObjectInputStream ois = new ObjectInputStream
18228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                (new ByteArrayInputStream(serialBytes(o)));
18238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            T clone = (T) ois.readObject();
18248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            assertSame(o.getClass(), clone.getClass());
18258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return clone;
18268e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (Throwable fail) {
18278e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            threadUnexpectedException(fail);
18288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            return null;
18298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
18308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
18318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
18328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void assertThrows(Class<? extends Throwable> expectedExceptionClass,
18338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                             Runnable... throwingActions) {
18348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        for (Runnable throwingAction : throwingActions) {
18358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            boolean threw = false;
18368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            try { throwingAction.run(); }
18378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            catch (Throwable t) {
18388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                threw = true;
18398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                if (!expectedExceptionClass.isInstance(t)) {
18408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    AssertionFailedError afe =
18418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                        new AssertionFailedError
18428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                        ("Expected " + expectedExceptionClass.getName() +
18438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                         ", got " + t.getClass().getName());
18448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    afe.initCause(t);
18458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    threadUnexpectedException(afe);
18468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                }
18478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }
18488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            if (!threw)
18498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                shouldThrow(expectedExceptionClass.getName());
18508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        }
18518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
18528e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
18538e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    public void assertIteratorExhausted(Iterator<?> it) {
18548e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        try {
18558e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            it.next();
18568e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath            shouldThrow();
18578e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        } catch (NoSuchElementException success) {}
18588e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        assertFalse(it.hasNext());
18598e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    }
18608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle}
1861